목록분류 전체보기 (247)
방프리
읽기 시작한건 21년도였지만 잦은 야근과 쉬겠다는 핑계로 미룬지 3년만에 다 읽었다.하지만 다 읽은 후에도 담당 프로젝트 오픈과 라이브 대응으로 미루고 까먹고 또 다시 미루다 생각나서 작성하는 리뷰다.처음에는 하나하나 기억하려고 챕터 별로 정리하려고 했지만 그러기엔 이 도서를 끝까지 다 읽을 지도 미지수였고이것 말고도 해야할 게 너무 많아 그러고 싶지 않았다.이 책을 읽으면서 해당 도서에 대한 평가를 보니 부정적인 평가도 꽤나 접할 수 있었다.그렇다고도 생각되는게 도서 제목이 많은 사람들을 광신도로 이끌기에 최적화된 제목이 아닐까 싶다."클린코드", 제목만 봐서는 책을 읽기만 하면 아주 가이드처럼 완벽한 코드를 만들 수 있지 않을까?이것만 따라하면 돼!! 라는 생각을 심어주기엔 딱이기 때문이다.처음엔 꽤..
1. 포인터에 대한 const 전파const 정확성에서 가장 실수가 많은 것은 const로 초기화된 객체가 멤버 포인터가 가리키는 값을 변경하는 것namespace exp = std::experimetal;class Foo{public: auto set_ptr(int* p) const { ptr_ = p; // not compiled } auto set_val(int v) const { val_ = v; // not compiled } auto set_ptr_val(int v) const { *ptr_ = v; // not compiled } private: exp::propagate_const ptr_ = ..
1. C 함수 포인터를 람다에 할당람단는 일반 함수 포인터로 변환이 가능, 해당 기능 때문에 람다는 캡쳐를 전혀 가질 수 없음 // old C library codeexternal void download_webpage( const char* url, void (*callback)(int, const char*)); auto func() { auto lambda = +[](int result, const char* str) {}; download_webpage("http://www.packet.com", lambda); } 2. 람다와 std::function모든 람다 함수는 자신만의 타입을 가지고 있으며, 동일한 두 개의 람다가 동일한 서명을 가지고 있어도 마찬가지다.std..
1. 변수에서의 auto 사용auto는 지역 변수에 대해 좌에서 우로 초기화하는 방식으로 사용하는 것을 선호 ex) auto i = 0;이동 불가능한 유형이나 복사 불가능한 유형에도 적용 가능2. const 참조const auto&와 같이 나타나는 const 참조는 어느 것과도 바인드가 가능const 참조는 수정을 원하지 않는 변수에 대한 기본적인 선택이어야 함auto func() { auto foo = Foo {}; auto& cref = foo.cref(); // cref는 const 참조 auto& mref = foo.mref(); // mref는 변경 가능한 참조}3. 가변 참조const 참조와 반대로 임시 객체와 바인드가 되지 않음auto&는 가변 참조를 표시하여 사용4. 전달 ..
1. 공유 리소스 초기화공유하는 리소스를 생성할 때가 아닌 처음 사용 시 초기화를 할 때 Lazy형식을 사용한다.게으른 초기화라고도 하는데 팩토리 대리자와 함께 인스턴스를 생성한다.static int _simpleValue;static readonly Lazy MySharedInteger = new Lazy(() => _simpleValue++);void UseSharedInteger(){ int sharedValue = MySharedInteger.Value;}// 비동기 작업 시static int _simpleValue;static readonly Lazy> MySharedAsyncInteger = new Lazy>(() => Task.Run(async () => { a..
1. 스레드 풀에 작업 스케줄링Task.Run을 사용하여 작업을 실행시킨다. 여러 기능이 있으나 Task.Run을 사용하는 것이 유지보수나 변경에 쉽다.Task task = Task.Run(async () =>{ await Task.Delay(TimeSpan.FromSeconds(2)); return 13;}); 2. 작업 스케줄러를 사용해서 코드 실행TaskScheduler 중 TaskScheduler.Default는 작업을 스레드 풀의 큐에 넣는다. Task.Run, 병렬 처리, 데이터 흐름 코드는 모두 TaskScheduler.Default를 사용한다. TaskScheduler.FromCurrentSynchronizationContext를 사용해서 컨텍스트를 저장해놓고 나중에 다시 이 컨..
1. 블로킹 잠금닷넷에서는 여러 기능을 통해 잠금 기법을 제공한다. 다만 대부분의 상황에서의 잠금은 lock으로 처리가 가능하다.단 lock을 사용함에 있어서 네 가지 지침을 확인할 필요가 있다.잠금의 가시성을 제한해야 한다.잠금으로 보호하는 대상을 문서화한다.잠그는 코드를 최소화한다.잠금을 유지하는 동안 절대로 임의의 코드를 실행하지 말아야 한다.class MyClass{ private readonly object _mutex = new object(); private int _value; public void Increment() { lock(_mutex) { _value = _value + 1; } }} 2...
1. 비동기 인터페이스와 상속async 키워드는 구현을 지니는 메서드에서만 적용할 수 있다. 즉, 기본 구현이 없는 추상 메서드나 인터페이스 메서드에는 적용할 수 없다. 하지만 async 키워드가 없어도 async 메서드와 시그니처가 똑같은 메서드를 정의할 순 있지만 대기하는 대상은 메서드가 아닌 형식을 대기하는 것이다.interface IMyAsyncInterface{ Task CountBytesAsync(HttpClient client, string url);}class MyAsyncClass : IMyAsyncInterface{ public async Task CountBytesAsync(HttpClient client, string url) { var bytes = a..