우리는 메모리의 처리 속도를 보다 빠르게 처리하기 위한 장치가 바로 Cache(캐시)이다.
캐시에 자주 사용하는 데이터를 담아두고, 해당 데이터가 필요할 때 프로세서가 메인 메모리 대신 캐시에 접근하도록 하여 처리 속도를 높입니다. 이때 캐시의 저장된 데이터가 너무 크게 되면 정보를 찾는 시간이 오래 걸려 캐시의 데이터 크기에 대한 제한이 있어야 하고 또 일정한 시간 내에 업데이트된 캐시의 데이터만 사용해야 캐시를 효과적으로 사용할 수 있다.
앞서 설명한 것처럼 캐시를 크기에 따라, 시간에 따라 저장할 수 있으며 이를 각각 공간 지역성, 시간 지역성이라고 한다.
최근 접근한 데이터에 다시 접근하는 경향을 말합니다. 가령 루프에서 인덱스 역할을 하는 변수 i에는 짧은 시간안에 여러 번 접근이 이루어집니다.
최근 접근한 데이터의 주변 공간에 다시 접근하는 경향을 말한다. 위 루프의 경우 배열 arr의 각요소를 참조하면서 가까운 메모리 공간에 연속적으로 접근하고 있습니다.
1) LRU(Least Recently Used) : 캐시 내에서 가장 오랫동안 참조되지 않은 블록을 교체하는 방식
2) FIFO(First In First Out) : 캐시 내에서 가장 오랫동안 블록을 먼저 교체하는 방식
3) LFU(Least Frequency Used) : 가장 적게 참조되었던 블록을 교체하는 알고리즘
1) Write Through
문제점 : 메인 메모리의 병목현상 발생 가능성
2) Write back
문제점: 회로가 복잡, 디바이스 제어의 경우 캐시의 내용을 디바이스로 전달하지 않는 경우가 간혹 발생한다.
javascript map 자료형은 Object와 굉장히 유사합니다. 두 자료형 모두 키를 값으로 설정하고, 해당 값을 검색하고, 키를 삭제하고, 키에 무언가가 저장되어 있는지 여부를 알수 있습니다. 하지만 위 두 자료형에는 다음과 같은 차이가 있습니다.
1) readline을 통한 입출력
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What do you think of Node.js? ', (answer) => {
// TODO: Log the answer in a database
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();
});
2) prompt을 통한 입출력
result = prompt(title, [default]);
result는 보여지는 부분, default는 초기 입력값
3) confirm
result = confirm(question);
confirm을 통해 question에 대한 입력값을 받습니다. 이때 입력값은 true, false를 눌러 도출할 수 있습니다.
예)
let isBoss = confirm("Are you the boss?");
alert( isBoss ); // true if OK is pressed
동기 방식에서는 백그라운드 작업 완료 여부를 계속 확인하며, 호출한 함수가 바로 return되지 않고 백그라운드 작업이 끝나야 return됩니다.
쉽게 말해, 코드 한 문장 문장이 실행이 완료되어야 다음 코드를 실행할 수 있게되는 방식
비동기 방식에서는 호출한 함수가 바로 return되어 다음 작업으로 넘어가며, 작업 완료 여부는 신경 쓰지 않고 나중에 백그라운드가 알림을 줄때 비로소 처리함수니다.
즉, 메인 스레드?에 코드들을 먼저 다 실행한 후에 백그라운드에 있는 코드들을 실행하는 방식
자바 스크립트와 노드에서 주로 비동기를 접합니다. 특히 이벤트 리스터를 사용할 때 콜백함수를 자주 사용합니다. 우리는 이 자바스크립트의 콜백함수의 지옥으로부터 탈출하기 위해 Promise를 기반으로 재구성할 수 있습니다.
function findAndSaveUser(Users){
Users.findOne({}, (err,user) =>{
if (err){
return console.error(err);
}
user.name = 'zero';
user.save((err) => {
if (err) {
return console.error(err);
}
Users.findOne({gender:'m'},(err,user) => {
});
})
});
}
function findAndSaveUser(Users){
Users.findOne({})
.then((user) => {
user.name = 'zero';
return user.save();
})
.then((user)=>{
return Users.findOne({gender: 'm'});
})
.catch(err => {
console.error(err);
});
이처럼 (user,err)를 받아서 만약 user를 받는다면 .then에 따라 순차적으로 처리하고 err인자를 받는다면 .catch에 따라 오류를 한번에 처리할 수 있습니다.
이처럼 Promise를 통해서 콜백 지옥에 벗어낫다면 async/await를 통해서 긴 .then .catch구문을 짧게 줄일 수 있습니다.
예)
anync function findAndSaveUser(Users){
let user = await Users.findOne{()};
user.name = 'zero';
user = await user.save();
user = await Users.findOne({gender: 'm'});
}
사실 위의 코드는 다만 err에 대한 작업이 없기 때문에 다음과 같이 코드를 짜야됩니다.
anync function findAndSaveUser(Users){
try{
let user = await Users.findOne{()};
user.name = 'zero';
user = await user.save();
user = await Users.findOne({gender: 'm'});
} catch(error){
console.error(error);
}
};