전체 글(29)
-
async void는 되도록이면 사용하지 말자.
Task를 이용해 비동기 코드를 작성할 때, async void는 되도록이면 사용하지 않는 것이 좋다. async void가 가진 문제점들은 다음과 같다. 1. Task를 반환하지 않으므로 호출자에서 await을 통해 완료 되었는지 알 수 없다. 누군가가 아래와 같이 스트림에 바이트 배열을 기록하는 클래스를 만들었다고 해보자. public class DataWriter { public async void WriteDataAsync(byte[] data); public int Length { get; private set; } } 만약 WriteDataAsync 비동기 함수의 작업이 언제 끝나는지 알고싶다면 어떻게 해야할까? 방법이 없다. Polling을 통해 데이터가 모두 기록되었는지 확인하는 등 비효율..
2024.03.30 -
[책 리뷰] Unit Testing: Principles, Practices, and Patterns
이 책은 제목대로 유닛 테스트의 원리, 실전, 패턴에 대하여 다루는 책이다. 이 책을 읽게된 계기는 TDD(*Test-Driven Development, 테스트 주도 개발*)에 대해 공부하다가 ’테스트’ 라는 개념에 대해 더 자세히 공부하고 싶었고, 테스트 비기너가 시작하기에 너무 짧지도 않고 너무 길지도 않은 책을 찾다가 이 책을 선택하게 되었다. (너무 짧으면 내용이 부실할까 걱정되었고, 너무 길면 읽다가 지칠까봐..) 책 초반에는 유닛 테스트의 목표와 개념에 대해 설명하며, 중반에는 잘 짜여진 유닛 테스트의 특성과 좋은 유닛 테스트를 작성 하는 방법, 후반에는 인티그레이션 테스트와 유닛 테스트 안티 패턴에 대해 설명하고 있다. 당연할지도 모르겠지만 프로그래밍을 막 시작하는 사람이 읽기에 좋은 책은 ..
2024.03.27 -
std::chrono - 1. Duration
이전 글에서 time_t 타입의 문제는 단위가 달라지면 값이 가지는 의미가 달라지는데도 정상적으로 컴파일이 된다는 것 이었다. 그럼 단위가 다르면 컴파일 에러를 띄우는 방법이 있을까? 바로, 각 단위에 대한 타입을 만들어주는 것이다. class seconds { ... } class minutes { ... } void f(seconds sec); int main() { minutes mins{10}; f(mins); // Compile Error!! f(10); // Compile Error!! } 위 예제를 보면 초(seconds)와 분(minutes)을 나타내는 각각의 클래스를 만들어주었다. 이제 main 함수를 보면 두 번의 f 함수의 호출은 실패하는데, 첫 번째는 매개변수와 인자의 타입이 다르기..
2022.09.22 -
std::chrono - 0. chrono가 왜 필요한가?
C++11 이전에 시간/날짜를 측정하기 위해서는 외부 라이브러리를 사용하거나 표준 라이브러리를 사용해야 했다. 하지만 라이브러리의 사용은 프로젝트에서 시간의 단위 변환이 많아질수록 사용이 까다롭고 버그가 발생할 확률이 높아졌는데, 그 이유는 다음과 같다. 단위 변환을 위해서 직접 특정 값을 곱하거나 나누어줘야 했으므로 프로젝트 내 특정 단위를 사용하다가 다른 단위를 사용하기로 설계를 수정한다면 모든 코드를 변경해야 한다. #include #include void g(time_t milliseconds) { std::cout
2022.09.21 -
폰 노이만, 하버드, 수정된 하버드 아키텍처
Von Neumann Architecture 폰 노이만 구조는 폰 노이만에 의해 고안된 디지털 컴퓨터의 설계 구조로, 명령어(instruction)들과 데이터(data)들이 같은 메모리에 저장되며, 명령어와 데이터의 메모리 주소가 하나의 주소 공간(address space)을 공유한다. 폰 노이만 구조는 명령어와 데이터를 동시에 가져올 수 없는데, 같은 메모리 버스(memory bus)를 공유하기 때문이다. 메모리 버스를 공유하면 한 번에 하나의 명령어 또는 데이터 메모리 주소에 접근이 가능하기 때문에 처리에 필요한 데이터가 많아지면 병목 현상이 발생하게 되는데, 이 병목 현상을 폰 노이만 병목(Von Neumann bottleneck)이라 한다. Harvard Architecture 사진을 보면 폰 노..
2022.09.18 -
std::intializer_list는 어떻게 생성 및 파괴될까?
std::initializer_list는 단순히 특정 타입 오브젝트의 배열이 아니다. 정확히 말하면 initializer_list는 컴파일러가 생성한 임시 배열(temporary array)의 포인터와 크기를 들고있는 오브젝트이다. 다음 코드를 보자. 6번 라인을 보면 0~9까지 총 10개의 원소로 initializer_list를 초기화했다. 그냥 척 보기에는 list 변수가 10개의 int를 들고있는 배열로 보이는데, 6번 라인의 어셈블리를 확인해보자. 먼저 read-only 메모리에 우리가 입력한 0~9까지의 숫자들이 .Lconstinit 레이블로 저장된 것을 볼 수 있는데, 어셈블리 5~8번 라인을 보면 .Lconstinit 레이블에 있는 0~9까지의 40byte를 스택 메모리 [rbp - 56]에..
2022.09.16