TIL0721

황준승·2021년 7월 22일
0
post-thumbnail

😆 캐시란?

우리는 메모리의 처리 속도를 보다 빠르게 처리하기 위한 장치가 바로 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

  • Write Through의 문제점을 보완하는 방법으로 캐시 내의 데이터만 갱신, 메인 메모리는 추후에 업데이트되는 방법이다.

문제점: 회로가 복잡, 디바이스 제어의 경우 캐시의 내용을 디바이스로 전달하지 않는 경우가 간혹 발생한다.

😃 MAP vs Object

javascript map 자료형은 Object와 굉장히 유사합니다. 두 자료형 모두 키를 값으로 설정하고, 해당 값을 검색하고, 키를 삭제하고, 키에 무언가가 저장되어 있는지 여부를 알수 있습니다. 하지만 위 두 자료형에는 다음과 같은 차이가 있습니다.

👍 MAP vs LRU cache

  • 제 생각에는 LRU cache는 데이터의 크기에 대해 시간적, 공간적 제약이 있고 map은 그런 제약이 따로 없다는 것이 차이점이라고 생각합니다.

😷 javascript 콘솔 입출력

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

동기와 비동기 method

동기 방식에서는 백그라운드 작업 완료 여부를 계속 확인하며, 호출한 함수가 바로 return되지 않고 백그라운드 작업이 끝나야 return됩니다.

쉽게 말해, 코드 한 문장 문장이 실행이 완료되어야 다음 코드를 실행할 수 있게되는 방식

비동기 방식에서는 호출한 함수가 바로 return되어 다음 작업으로 넘어가며, 작업 완료 여부는 신경 쓰지 않고 나중에 백그라운드가 알림을 줄때 비로소 처리함수니다.

즉, 메인 스레드?에 코드들을 먼저 다 실행한 후에 백그라운드에 있는 코드들을 실행하는 방식

Promise

자바 스크립트와 노드에서 주로 비동기를 접합니다. 특히 이벤트 리스터를 사용할 때 콜백함수를 자주 사용합니다. 우리는 이 자바스크립트의 콜백함수의 지옥으로부터 탈출하기 위해 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) => {
            
            });
        })
    });
}
  • Promise로 짠 코드
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에 따라 오류를 한번에 처리할 수 있습니다.

async/await

이처럼 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);
  }  
};
profile
다른 사람들이 이해하기 쉽게 기록하고 공유하자!!

0개의 댓글