ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 항해 99 5기 TIL_36
    항해 99 2022. 2. 15. 03:37

    ▶ Today I Learned

     

    <CS>

     

    [토큰 저장 방식]

     

    로그인을 위해 JWT 방식을 사용하기로 했고 서버에서  로그인이 인증되면 토큰을 생성하여 클라이언트로 보내주게 된다.

    이때 클라이언트에서는 토큰을 받아 저장해야하는데, 그 저장 방식을 고민하게 되었다.

    방법은 아래와 같다.

     

    로컬 스토리지: 브라우저에 해당 데이터 저장, 세션 스토리지와는 다르게 사용자가 지울 때 까지 브라우저에 남아있게 됨,

    자동 로그인에 적절,

     

    세션 스토리지: 브라우저에 해당 데이터 저장, 로컬 스토리지와는 다르게 브라우저 탭을 닫는 순간 지워지게 됨,

    일회성 로그인에 적절

     

    두 스토리지는 window에 위치함,

    프로토콜, 호스트, 포트가 같으면 같은 스토리지를 공유,

    브라우저별로, 기기별로 다르긴 하지만 보통 모바일은 2.5mb, 데스크탑은 5mb~10mb임

     보통 키-밸류 로 이루어진 데이터를 저장하며 어떤 형태의 데이터도 저장 가능하지만 저장 시 문자열로 저장됨

    객체를 통째로 저장하려면 setItem() 시에는 JSON.stringify, getItem()할 시에는 JSON.parse로 찾음

     

    아래와 같은 형태로 찾을 수 있음

    / keyName 이라는 이름의 key 에 objectData 이름의 객체 데이터를 세션에 저장
    sessionStorage.setItem(keyName, JSON.stringify(objectData));
    
    // keyName 이름의 String 을 가져와 JSON 형태로 다시 Parse 진행
    JSON.parse(sessionStorage.getItem(keyName));

     

     

    쿠키: 쿠키에 해당 정보를 담아 브라우저에 저장, 최대 용량은 4KB이며 만료 기한을 정할 수 있음,

    단, 요청을 할 때 마다 쿠키를 매번 보내게 됨(로컬과 세션 스토리지는 서버로 데이터가 자동 전송되지 않음),

    HTTP의 특성 상 매번 페이지가 로딩되거나 전환될 때 마다 요청을 보내게되고 그러면 쿠키에 담긴 용량이 매번 쓰이게 된다는 단점이 있음

     

    아래 링크에서 좀 더 자세한 설명 참조 가능

     

    출처:

    https://www.zerocho.com/category/HTML&DOM/post/5918515b1ed39f00182d3048

    https://sanghye.tistory.com/14

     

    [CPU]

     

    Central Processing Unit (중앙 처리 장치)

    → 프로그램을 실행하기 위해 메인 메모리에서 명령어를 인출하여 해독하고 실행한다.

    각각의 단계를 Fetch phase, Decode phase, execute phase라고 함

    1. 연산
      • 덧셈, 뺄셈, 곱셈 등의 산술 연산과 논리곱, 논리합, 부정 등의 논리 연산을 수행
    2. 제어
      • 명령어를 순서대로 실행할 수 있도록 제어
    3. 저장
      • 연산에 필요한 데이터, 연산 결과, 명령어 주소 등을 임시로 저장

    CPU의 구조

    1. 레지스터(Register)
      • CPU 내부에 있는 메모리
      • 명령어 주소, 코드, 연산에 필요한 데이터, 연산 결과 등을 임시로 저장
      • 고속 기억장치
      • 다양한 종류가 있음(PC, IR, MBR 등)
    2. 제어 장치(Control Unit)
      • 각 장치들의 동작을 결정하는 신호를 보낸다.
      • 주기적장치에서 프로그램 명령어를 꺼내 해독하고, 그 결과에 따라 명령어 실행에 필요한 제어 신호를 기억장치, 연산장치, 입출력 장치로 보냄
    3. 연산장치(ALU, Arithmetic Logic Unit)
      • 산술 및 논리 연산 수행

    핵심 특수 목적 레지스터

    • 메모리 주소 레지스터(MAR) : 읽기와 쓰기 연산을 수행할 주기억장치의 주소를 저장
    • 프로그램 카운터(PC) : 다음에 수행할 명령어의 주소를 저장
    • 명령어 레지스터(IR) : 현재 실행 중인 명령어를 저장
    • 메모리 버퍼 레지스터(MBR) : 주기억장치에서 읽어온 데이터나 주기억장치에 저장할 데이터를 임시로 저장
    • 누산기(AC) : 연산 결과를 임시로 저장

    CPU 동작과정

    1. 주기억장치는 입력장치에서 입력 받은 데이터 또는 보조기억장치에 저장된 프로그램 읽어옴
    2. CPU는 프로그램을 실행하기 위해 주기억장치에 저장된 프로그램 명령어와 데이터를 읽어와 처리하고 결과를 다시 주기억장치에 저장한다.
    3. 주기억장치는 처리 결과를 보조기억장치에 저장하거나 출력장치로 보낸다.
    4. 제어장치는 명령어가 순서대로 실행되도록 각 장치를 제어한다.

    CPU 클럭 주파수 (Clock Frequency)

    CPU clock frequency 는 CPU 동작 속도를 의미하고, '초당 사이클'을 의미한다.  (단위는 Hz)

    (사이클은 명령어가 요구하는 동작 들을 수행하는 단위)

    동적 주파수 스케일링 (dynamic frquency scaling))을 가지고 있어 speed 조절 가능

     

    Overclocking -> 프로세스 처리 속도를 올릴 수 있지만 신호가 안정되는 속도보다 clock 속도가 빨라질 수도 있으며 CPU가 과열될 수 있음

    Underclocking -> 컴퓨터를 사용하지 않을 때 전력 소모를 줄이는 효과가 있음 (노트북이나 휴대폰처럼 배터리 사용하는 것에 유용함)

     

    출처:

    https://hidelookit.tistory.com/154

    https://technote.kr/309

     

     

    <알고리즘>

     

    조이스틱

    소요 시간: 1시간 25분 + 2시간 + 50분

    해결 여부 : 미해결

     

    https://programmers.co.kr/learn/courses/30/lessons/42860

     

    열심히 아래와 같이 짜보았다.

    let name = "AAAAEEAAAA"
    let leftRight = 0
    //AJEARAO 이거에서 거꾸로 시작하는 건 마치
    // AOARAEJ와 같다
    // 그렇다면
    // 문자열 첫번째 문자를 제외하고 잘라낸 다음 그것을 배열로 쪼개 역순으로 뒤집고 이를 다시 합쳐주어 원래 문자에 더하자.
    let reversedName = name.substring(0,1) + name.substring(1).split('').reverse().join('')
    
    
    
    console.log(reversedName)
    
    //문자열 내 A가 포함되어 있는가? 그리고 문자중 하나라도 A가 아닌게 있는가?
    
    console.log(name.includes('A'));
    
    if(name.includes('A')) {
    // 좌우 경우의 수 따지기
    
    console.log(name.split('')) // "JERAOEN" 인 경우를 고려해보면 A가 중간에 있을 때 나눈 배열의 길이는 같지만 실제로 첫번째에서 마지막문자로 갈때의 횟수 1이 더해지므로 둘중 어떤 선택지가 나을지 비교할 때 [첫번째 배열 길이]와 [두번째 배열 길이 +1]을 비교해주어 더 큰쪽이 있다면 그쪽을 택해야 함
    console.log(reversedName.split(''))
    
    console.log(name.split('').lastIndexOf('A'))
    console.log(reversedName.split('').lastIndexOf('A'))// 인덱스가 더 큰쪽이 적게 감 -> 더 마지막 부분에 A가 있기 때문?
    // 하지만 "EEEAEAR"로 하게 되면 인덱스가 각각 5,4 이지만 횟수는 똑같아 fail
    // name이나 reversedName의 마지막 글자중 하나라도 A인 경우에는 위의 식이 성립, 아니라면 인덱스 번호가 어떻든 간에 결과는 같음
    
    if(name[name.length-1] === 'A' || reversedName[reversedName.length-1] === 'A') {
      if(name.split('').lastIndexOf('A') > reversedName.split('').lastIndexOf('A')) {
        
        // EERAEAA처럼 마지막에 A가 몰려있는 경우?는 어떻게 값을 반환하지?
        // 뒤집으면 AAEAREE E의 인덱스는 2
        // console.log(name.split('').reverse().reduce((a, b, curIndex) => {if(a === 'A' && b === a) {} else {return curIndex}})) // reduce 구문이 안 멈춘다..
    let i = 0
      while (i < name.length) {
        if(name.split('').reverse()[i] === 'A' && name.split('').reverse()[i] ===  name.split('').reverse()[i+1]) {
    
        } else {
    
          // 끝에서 A가 이어지다가 다른 문자가 나오는 인덱스를 찾아 반환
          console.log('정답', i+1)
          console.log(reversedName.length - 1 - (i + 1))
            // 네임 원래 순서대로, 즉, 오른쪽으로 가는 것
            leftRight = reversedName.length - 1 - (i + 1)
    
            break
          }
          i++
      };
    
        // EERAEAA에서 E의 인덱스는 4
    
      } else {
    
    // name.split('').lastIndexOf('A') <= reversedName.split('').lastIndexOf('A')
    let i = 0
      while (i < reversedName.length) {
        if(reversedName.split('')[i] === 'A' && reversedName.split('')[i] === reversedName.split('')[i+1]) {
    
        } else {
    
          // 끝에서 A가 이어지다가 다른 문자가 나오는 인덱스를 찾아 반환
          console.log('정답', i+1)
          console.log(reversedName.length - (i + 1))
            // 네임 원래 순서대로, 즉, 오른쪽으로 가는 것
            leftRight = reversedName.length -1 - (i + 1)
            
            break
            
          }
          i++
        }
      }
    
    } else {
      // 둘다 A가 들어가있긴 하지만 그게 마지막 인덱스가 아니기 때문에
      // 어차피 마지막 까지 이동하여 글자를 바꾸어야 함 -> 어느 쪽으로 가도 좌우 이동 횟수는 같음
      leftRight = name.length - 1
    }
    
    } else {
      // 문자열 내 A가 없단 소리이므로 좌우 어디로 가도 좌우 이동 횟수는 똑같음, 따질 필요 없음
      leftRight = name.length - 1
    };
    
    console.log('최종 좌우 결과', leftRight)

     

    하지만 간과한 사실이 있었다.

    바로, 정방향이든 역방향이든 어느 한쪽으로만 쭉 가야하는 건 아니라는 것이다..!

    아래와 같은 예시가 있었다.

    //JBCAAAAABD" 라는 name이 주어졌을 때, JBC를 만들고 다시 뒤로이동(◀)해서 BD를 완성하면 최소로 이동하는 횟수가 될 것이다
    // 이 경우를 고려하지 못했다,,! 난 그저 중간에 A가 있는 경우는 좌우 어디로 가도 어차피 똑같으니까 신경안써야지 했는데...
    // 이렇게 중간에 A가 많이 있는 경우는 진짜 상상도 못했다... 스스로 테스트 케이스를 나눠보지 못한 나, 생각이 짧았다..

     

    내일 해당 풀이를 좀 더 살펴보아야 겠다.

     

     

    ▶ 느낀 점

     

    오늘도 나름 열심히 공부했다 ;) 비록 알고리즘에서도, CS에서도 배울 것이 한참 남아있지만 그래도 이렇게 하루를 보내며

    내 지식을 하나씩 차곡차곡 채워나간다.

    끝났을 때 뿌듯할 내 모습을 상상하며 히히

     

     

    ▶ 공부 시 참고 링크들

     

     

    https://tobegood.tistory.com/entry/programmersJoystickJavaScript

     

    [프로그래머스/JavaScript/js] 조이스틱

    문제 설명 조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 조이스틱을 각 방향으로 움직이면 아래와 같습니

    tobegood.tistory.com

     

    https://ghost4551.tistory.com/113?category=982768 

     

    [프로그래머스 JavaScript] 조이스틱

    🚩 프로그래머스 Level2 조이스틱 -> 탐욕법(Greedy) 📖 문제 설명 두번째 그림과 같이 오락실 게임에서 이름 등록 과정을 생각하면 이해하기 좋습니다. 위아래 방향키는 알파벳 순서를 의미하고,

    ghost4551.tistory.com

     

     

    '항해 99' 카테고리의 다른 글

    항해 99 5기 TIL_38  (0) 2022.02.17
    항해 99 5기 TIL_37  (0) 2022.02.16
    항해 99 5기 WIL_5  (0) 2022.02.13
    항해 99 5기 TIL_35  (0) 2022.02.13
    항해 99 5기 TIL_34  (0) 2022.02.13
Designed by Tistory.