목록전체 글 (14)
Sonji-log
1. 이 항목이 왜 중요한가C++에서는 내가 직접 쓰지 않아도 컴파일러가 몇몇 함수를 자동으로 만들어 주는 경우가 있다. 대표적으로 아래 두 가지가 자주 문제를 만든다.복사 생성자(copy constructor)복사 대입 연산자(copy assignment operator)겉으로 보기에는 편리하다. 하지만 어떤 클래스는 "복사되면 안 되는 객체" 인데도, 아무 조치를 하지 않으면 복사가 가능해질 수 있다.예를 들어, 아래와 같은 경우를 생각해 보자.mutex 같은 동기화 객체파일 핸들, 소켓 핸들 같은 시스템 자원"오직 하나만 존재해야 하는" 객체(Singleton Pattern에 해당하는 성격의 객체를 생각하면 쉽다)내부적으로 복사 의미가 애매하거나 위험한 객체이런 객체를 실수로 복사하면 다음과 같은 ..
이 항목의 핵심은 간단하다.클래스의 생성/복사/대입/소멸 동작을 내가 명시하지 않으면 컴파일러가 "합리적이라고 판단한 기본 동작"을 넣어 준다.문제는 이 기본 동작이 "컴파일은 되지만 의도는 틀린 코드"를 만들 수 있다는 점이다. 특히 리소스 소유권(메모리, 파일, 소켓, 뮤텍스)을 다루는 클래스에서 위험하다.1. 컴파일러가 자동으로 만들 수 있는 함수C++ 클래스에서 특별히 선언하지 않으면 컴파일러가 다음 멤버 함수를 자동으로 선언할 수 있다.기본 생성자(default constructor)소멸자(destructor)복사 생성자(copy constructor)복사 대입 연산자(copy assignment operator)C++11 이후에는 이동 의미(move semantics)가 추가되어 아래도 상황에..
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당 남아있는 ..
