목록전체 글 (12)
Sonji-log
1. 왜 초기화가 중요한가초기화되지 않은 객체를 쓰면 버그가 바로 드러날 때도 있고, 꽤 잘 재현되는 것처럼 보일 때도 있다.문제는 그 재현성이 신뢰할 만하지 않다는 점이다. 빌드 옵션이나 코드 배치, 실행 환경이 바뀌면 증상이 달라지거나 갑자기 사라질 수 있다.핵심은 단순하다.초기화되지 않은 값은 믿을 수 없다.컴파일러가 항상 자동으로 올바른 초기화를 해주지 않는다.특히 기본 타입(int, double, 포인터 등)은 상황에 따라 초기화가 되기도 하고 안 되기도 한다.int x; // 초기화되지 않음 (값 미정)double y; // 초기화되지 않음 (값 미정)int* p; // 초기화되지 않음 (쓰레기 주소 가능)이 상태에서 값을 읽으면 동작이 예측 불가능해진..
System Call목차시스템 콜 정의시스템 콜 제공시스템 콜 세부구성시스템 콜 구현시스템 콜 정의시스템 콜(System Call)은 사용자 공간(User Space) 과 커널 공간(Kernel Space) 사이를 이어주는 인터페이스다.시스템 콜이 필요한 이유는 크게 3가지다.하드웨어를 직접 다루지 않아도 되게 해준다.예) 파일 입출력을 할 때, 애플리케이션은 디스크 구조나 파일시스템 내부 구현을 몰라도 된다.보안과 안정성을 지켜준다.예) 커널이 중간에서 권한 검사와 자원 접근 통제를 수행한다.프로세스마다 가상화된 실행 환경을 제공한다.예) 각 프로세스는 자신만의 주소 공간을 가진 것처럼 동작한다.리눅스에서 사용자 공간 프로세스가 커널 기능을 사용하려면, 기본적으로 시스템 콜 경로를 거쳐야 한다.트랩(T..
1. 왜 const를 사용해야 하는가const를 쓰는 이유는 간단하다. "바뀌면 안 되는 값을 못 바꾸게 만들기" 위해서다.의도의 전달const를 붙이면 "이 값은 안 바뀐다"는 약속을 코드에 직접 적는 셈이다. 그래서 나중에 코드를 읽는 사람(미래의 나 포함)도 의도를 바로 이해할 수 있다.컴파일러를 통한 실수 방지const 값은 바꾸려고 하면 컴파일 단계에서 바로 에러가 난다. 프로그램을 실행하기 전에 실수를 잡을 수 있다는 뜻이다.const int maxSize = 100;maxSize = 200; // 컴파일 에러 → 실수를 즉시 발견핵심은 "내가 조심하자"가 아니라 "컴파일러가 막아주게 하자"다. const를 붙일 수 있으면 가능한 붙이는 편이 안전하다.2. const의 적용 범위const는 생..
HackerRank에서 C++문제를 조금 풀었더니 받은 뱃지.아무래도 Medium 레벨 문제부터 들어가서 경험치가 많이 찼던 것 같다.HackerRank 특성상 개수로만 밀어붙여도 꽤 많은 경험치를 얻을 수 있기 때문에 뱃지는 그냥 공부의식 고취를 위해서 주는 타이틀이 아닌가 싶다.물론 그 목적에 완벽히 부합하게 받고 좋아했다.
간단한 알고리즘을 제한시간 내 성공적으로 풀이한 사람에게 주어지는 증명같다.난이도가 어렵지 않다는 점만 기억나고, 실제로 무슨 문제가 나왔는지는 기억이 잘 나지 않는다(작성일 기준 약 3주가량 지났기 때문). 비록 굉장히 고차원적이고 어려운 증명은 아니었지만 무언가를 받았다는 점에 집중하기로 했다.
문제 링크https://school.programmers.co.kr/learn/courses/30/lessons/42627분류Heap, SJF(Shortest Job First), Priority Queue시도한 방법문제는가상의 스케줄러를 만드는 일이다.가정에서는 중간중간에 발생하는 Context Switching에 걸리는 시간이 없다고 명시되어 있으므로, 단순히 작업하는 데 걸리는 시간의 총합을 반환하면 된다. 문제의 핵심은 잔여시간이 긴 작업이 처리되고 있을 경우, 다른 작업들은 계속 기다리기만 해야 한다는 점이다.이 부분은 전체 turn-around time을 크게 저해할 수 있으므로, 모든 작업이 끝났을 때 완료까지 걸리는 시간이 가장 짧은 작업을 우선해서 처리해야 한다고 해석할 수 있다.위 구조..
문제 링크https://school.programmers.co.kr/learn/courses/30/lessons/17684분류구현, 해시, 문자열시도한 방법초기에 모든 알파벳을 인덱스에 순차대로 담아 사전을 초기화한다.이후 버퍼에 대상 문자열의 한 글자씩 담고, 사전에 없을 경우 색인에 추가하며 버퍼를 flush하며 대상 문자열의 인덱스를 한 칸씩 밀어준다.위 과정을 마치고 나면 answer에 방금 검색된 색인을 담아 전달한다. 방향성 자체는 맞았지만, GPT 리팩토링 결과 몇 군데 지적받았다. 색인에 등록할 때는 탐색의 용이함을 확보하기 위해 한 글자씩 등록된 부분에 vector로 색인을 추가했지만, map 컨테이너에 내장된 find 함수를 사용하므로 굳이 리스트로 구현할 필요가 없었다.map> -> ..
문제 링크https://school.programmers.co.kr/learn/courses/30/lessons/12927분류구현, 우선순위, 그리디 알고리즘시도한 방법문제에서 원하는 야근 피로도는 남은 작업양의 제곱합으로 구한다. 제곱은 대상 수가 클수록 더 빠르게 커지므로, 작업 개수 자체가 줄어드는 것 보다 각 작업의 남은 시간을 최대한 균일하고 적게 만드는 편이 제곱합을 줄이는 더 좋은 방법이다. 단순하게 남은 시간만큼 루프를 돌며 가장 큰 값에서 1씩 감산하는 방법을 선택했다.남은 작업량을 대상으로 Priority Queue를 사용하면 항상 가장 많이 남은 작업이 맨 앞으로 오기 때문에, 루프를 돌면서 Priority Queue의 맨 앞 작업이 1씩 감산하게 작성했다. 한 Epoch당 남아있는 ..
정의Key-Value(키-값) 쌍을 저장하고, 빠르게 데이터를 검색, 삽입, 삭제할 수 있게 만든 자료구조.해시 함수를 이용해 데이터를 특정 key에 매핑하여 효율적으로 검색할 수 있도록 설계되었다.e.g., 전화번호부(Key : Value = 이름 : 전화번호) Q1. 왜 빠른가요?A1. 해시 함수를 사용해서 키를 고유 배열 인덱스로 매핑하기 때문. 배열은 인덱스만 알고 있다면 순차적으로 탐색할 필요 없이 원하는 위치에 바로 액세스할 수 있으므로, 검색, 삽입, 삭제에서 모두 시간복잡도가 O(1)로 동작해 빠른 속도를 보임.아래 동작원리의 기본 구조와 동작 과정 참조. 동작 원리기본 구조해시 테이블은 내부적으로 배열을 사용해서 데이터를 저장한다.데이터를 해시 함수를 통해 특정 인덱스로 변환하고, 그 ..
책 내용 정리예를 들어, 아래와 같은 코드를 작성했다고 가정하자.#define ASPECT_RATIO 1.653우리는 당연하게 ASPECT_RATIO 가 symbolic name으로 파악할 수 있지만, 컴파일러 입장에서는 전처리기가 숫자 상수로 바꾸어버리기 때문에 컴파일러의 기호 테이블에 들어가지 않아 디버깅이 다소 난해해질 수 있다.이를 매크로 대신 상수로 작성하고, 비교를 위해 아래처럼 코드를 작성했다고 가정하자.#include using namespace std;#define ASPECT_RATIO 1.653int main(void){ const double aspect_ratio = 1.653; cout 실제로 이 코드에서 cout 전에 breakpoint를 찍고 기호 테이블을 보면 아래 그림처럼..
