May 16, 2024 - 읽기 쉬운 코드

읽기 쉬운 코드를 길벗 리뷰어에 당첨되어 읽기 쉬운 코드를 읽어봤습니다.

내용이 재미있어 총 3번 정도 읽었는데, 소설책을 읽는 것처럼 쓱쓱 읽혀졌습니다.

자바 개발자이고, 예제 샘플은 C# 으로 되어있지만, C# 은 자바와 비슷한 문법과 코드 형태를 가지고 있어, 코드 읽는데는 큰 문제는 없었습니다.

『읽기 쉬운 코드』라는 책 제목은 개발자라면 꼭 한번 읽어야할 듯한 제목을 가지고 있습니다. 자기의 코드도 읽기 어려운 사람이 있고,
남의 코드는 절대 못읽는 사람도 개발을 하다보면 경험해봤습니다.

그리고 나의 코드가 과연 다른 사람에게 읽기 쉬울까? 라는 고민은 개발을 좋아하는 코더라면 자주 생각하는 영역일겁니다. (코더라는 말을 비하의 언어로 쓰지 않는다면 말이죠. )

이 책은 코드의 가독성과 유지 보수성을 높이기 위한 다양한 방법을 제시하고 있습니다.
이 책을 통해 저자는 코드의 품질을 높이는 것이 얼마나 중요한지,
그리고 이를 위해 개발자가 어떤 노력을 기울여야 하는지를 명확하게 전달합니다.

책은 소설책을 읽는 듯 본인의 경험담과, 개발자의 실수, 본인이 그래서 어떻게 그걸 해결하기 위해 노력했는지 순으로, 독자에게 친근하게 설명합니다.

코드는 작성하는 것보다 읽는 경우가 더 많다라는 부분에서 사람의 뇌는 컴퓨터가 가진 한계와는 완전히 다른 인지적 한계를 가지고 있다고 설명합니다.

컴퓨터는 RAM 안에 있는 수많은 것들을 추적해나갈 수 있지만, 우리의 뇌는 7개 정도만 추적할 수 있다고 하네요.

컴퓨터는 프로그래머가 참조하도록 만든 정보만 사용해서 결정을 내리지만, 우리의 뇌는 성급하게 결론을 내리는 경향이 있습니다.
눈에 보이는 것이 전부인 사람이, 그런 개발자가 소프트웨어가 원하는 대로 동작하게 만들려면 당연히 코드를 작성해야 합니다. 그러므로 코드는 우리 뇌에 맞게 구조화해야하며, 코드는 반드시 인간 친화적이어야 합니다.

예전에는 메모리를 위해 어떻게 코드를 짧게 작성해야하는지를 고민했다면, 이제는 컴퓨터 성능이 좋아졌으니, 얼만큼 가독성을 높게 작성해야할지를 고민해야할 시대라는 생각이 들었습니다.

이해하기 어려운 코드는 작업 속도를 느리게 만듭니다. 반면 코드를 이해하기 쉽게 만드는 데 투자한 시간은 나중에 10배 이상으로 보상받게 됩니다.

책은 기존 코드베이스에서 지속적 배포를 다시 적용하는 어려움을 강조합니다.
코드는 작지만, 그 안에서 발생할 수 있는 문제들은 무궁무진하고, 보통 사이드 이펙트라고 한 가지 문제를 해결하면 다른 곳의 2개의 문제가 생기거나, 모든 문제가 해결된 것은 아니기 때문에 지속적인 개선과 유지 보수가 필요합니다.

이는 개발 현장에서 발생하는 다양한 문제들을 해결하는 데 있어 지속적인 노력이 필요하다는 점을 상기시켜 줍니다.

『읽기 쉬운 코드』는 읽기 쉽고 유지 보수하기 쉬운 코드를 작성하는 것이 얼마나 중요한지를 강조합니다. 책은 프로그래밍 언어의 기본적인 구조와 속성을 다루며, 객체지향형 프로그래밍 언어의 강점을 최대화하는 방법을 소개합니다. 이 과정에서 개발자 간의 협업이 필수적이며, 컴파일, 테스트, 디버깅, 배포 과정에서 발생하는 여러 가지 오류들을 체크하고 문제를 해결하는 것이 중요하다고 설명합니다.

책은 코드의 가독성과 유지 보수성을 높이기 위해 다양한 팁과 방법을 제시합니다. 예를 들어, 코드를 작성할 때 좋은 작명 규칙을 따르고, 코드 리뷰를 통해 문제를 조기에 발견하며, 버전 관리 시스템을 효과적으로 사용하는 방법 등에 대해서도 간략하게나마 설명합니다.

저자는 코드가 단순히 실행되는 것을 넘어서, 사람이 쉽게 이해할 수 있도록 작성되어야 한다고 강조합니다. 이는 특히 팀으로 협업할 때 중요한데, 새로운 팀원이 기존의 코드를 빠르게 이해할 수 있어야 새로운 기능을 추가하거나 기존 코드를 수정하는 데 어려움이 없기 때문입니다.

책은 이론적인 설명뿐만 아니라, 실제 예제를 통해 개념을 적용하는 방법을 보여줍니다. 이 과정에서 코드의 가독성을 높이는 다양한 방법을 직접 경험할 수 있을거라 기대하였습니다.

책은 또한 유지 보수와 버그 관리를 어떻게 효과적으로 할 수 있는지에 대해서도 다룹니다. 예를 들어, 버그가 발생했을 때 이를 우선적으로 해결하고, 결함을 쌓아두지 말 것을 권장합니다. 이는 린 소프트웨어 개발의 품질 내재화 원칙과도 일맥상통합니다.

저자는 코드가 제대로 동작하지 않는 이유를 이해하고, 이를 해결하는 과정을 통해 새로운 통찰력을 얻을 수 있다고 설명합니다.

이 책은 프론트, 백엔드 가리지 말고 한번 읽어보면 생각을 많이 하게 되네요. 특히 팀으로 협업하며 개발을 진행하는 실무자들에게 큰 도움이 될 것입니다. 또한 예비 개발자들에게도 읽기 쉬운 코드의 중요성을 깨닫게 하고, 더 나은 개발자가 되는 데 큰 도움이 될 것입니다.

단점이 없다고 생각되진 않습니다. 너무 많은 내용을 담으려다보니, 내용이 요약되거나 함축적으로 처리되는 부분이 많습니다. 예를 들어 저는 린 소프트웨어에 대해서는 잘 모르지만, 린 소프트웨어와 일맥상통한 부분이 있습니다와 같이 비교대상으로 사용되었을 때, 린소프트웨어에 대한 추가공부가 필요했습니다. 그게 나쁘다는 것보다는, 코드리뷰, 깃 사용법 등 하나하나만으로도 책이 나올 이야기를 다 담으려다보니, 경력자에게는 읽기 쉬운 내용이나, 초급자에게는 추후 경력이 쌓이면 다시 한번 읽어보면 다른 느낌이 들 책으로 느껴졌습니다.

또한 콘웨이의 법칙을 엄청 좋아하는 저에게 콘웨이의 법칙을 설명할때, 시스템을 설계하는 조직은 필연적으로 해당 조직의 커뮤니케이션 구조를 복제한 설계 구조를 만들어낼 수 밖에 없다. 라는 번역이 되어있었는데, 조금 난해하게 설명한(번역된) 부분이 있다고 생각합니다. 아마 논문 그대로를 번역하기 위해서라고 생각하겠지만, 시스템을 설계하는 조직은 그 조직의 커뮤니케이션 구조를 반영한 설계를 하게 됩니다로 외우고 있는 저도 몇번을 읽어봐야 뜻이 이해가 되었습니다.

그럼에도 이 책이 좋다고 생각이 든 이유는, 왜 제대로 동작하지 않는지 이해하지 못한다면, 일단 그 이유를 이해하는 데 주력해야 해야하며, ‘우연에 맡기는 프로그래밍’이 진행되는 것을 막자는 저자의 의도가 너무 명확했습니다. 코드가 왜 동작하는지 이해하지 못하거나, 실제로는 제대로 동작하지 않는다는 것을 진짜로 이해하지 못하는 개발자들을 많이 봐와서, 처음부터 코드를 이해한다면 문제를 더욱 쉽게 해결하자는 강한 의지가 느껴졌습니다.

또한 고무 오리 이야기도 좋았습니다. 문제를 설명하는 것만으로도 새로운 통찰력을 얻을 수 있습니다. 동료가 없다면 고무 오리에게 문제를 설명해보는 것도 좋다는 글도 재미있게 읽었습니다. 한 프로그래머가 고무 오리를 사용했기 때문에 이 기법은 고무 오리 디버깅이란 이름으로 알려져 있습니다. 저는 고무 오리 대신 스택 오버플로 Q&A 사이트에 질문을 작성해보곤 합니다. 질문을 다 작성하기도 전에 문제가 무엇인지 깨닫는 경우가 많습니다. 요즘은 챗GPT에게 물어보게 되지만요.

결함의 수를 줄일 수는 있지만, 결함을 없앨 수는 없습니다. 자신에게 도움이 되는 방향으로 작업을 해야 합니다. 즉, 결함이 쌓이게 둬서는 안 됩니다. 가장 이상적인 결함의 수는 0개입니다. 버그가 없다는 건 생각만큼 비현실적이지 않습니다. 린 소프트웨어 개발에서는 품질의 내재화라고 합니다. 결점을 ‘나중에 처리’하겠다며 미뤄두지 마십시오. 소프트웨어 개발에서 ‘나중’은 ‘절대 안 한다’와 같습니다. 버그가 나타나면, 이 버그를 해결하는 것을 우선순위로 삼아야 합니다.

그래서 이 책이 좋다고 느껴졌습니다. 이 책을 통해 코드를 작성하는 데 있어서의 철학과 접근 방식을 다시 한번 생각해보게 되었습니다. 앞으로도 이 책의 가르침을 마음에 새기며 더 나은 코드를 작성하기 위해 노력할 것입니다.

Mar 2, 2024 - 제로부터 시작하는 러스트 백엔드 프로그래밍 1

러스트를 알게 된 시점은 StackOverflow(stackoverflow.com)에서 설문조사 중
현재 사용하는 언어 중, 내년에도 사용하고 싶은언어는? 이라고 질문을,
스택오버플로우 가입자 중 65,000명 에게 물어봤을 때 86.1 퍼센트를 차지한 언어가 Rust 였기 때문입니다.

러스트는 안전하고, 빠르고, 병렬성에 초점을 둔 시스템 프로그래밍 언어이다.

  • Rust 공식문서

러스트는 다른 언어에 존재하는 고충을 해결하면서 더욱 적은 단점으로 확실하게 러스트가 다른언어보다 한 발 앞서해 해준다.

  • 스택오버플로우 Rust Top 컨트리뷰터 Jake Goulding

라는 유명한 이야기가 있을 정도로 Rust 는 매우 핫한 언어입니다. ‘제로부터 시작하는 러스트 백엔드 프로그래밍’ 라는 책의 옮긴이 김모세님도, 머리말에서 ‘안전하고’, ‘병렬적이며’,’실용적인’ 언어로 설계되었다고 적혀있다.

이 책에서는 러스트가 API 개발을 위한 생상적인 언어가 될 수 있는지에 대한 의문을, 할 수 있다는 설명을 하면서 어떤 생산적인 라이브러리를 사용하면되는지 알려줍니다.

이 책은 툴링부터 시작하여, 도커를 거쳐 테스트 방법까지 고민하는 책입니다. 기초 문법을 배울려면 Rust in action 을 보는 게 조금 더 좋을 거 같고, (러스트 프로그래밍 공식 가이드는 아직 못봤기 때문에 본 책을 추천합니다.) 어느정도 배운 러스트를 실무에 사용하거나 실용적인 부분에 대해 학습할때 매우 좋은 책이라고 생각합니다.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

자세한 설명법이나 doc 에 대해서는 첨부를 통해 사이트를 알려줘, 사이트의 가이드를 통해 설치를 진행했습니다.

bymin@homeui-MacBookPro rust % curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
info: downloading installer

Welcome to Rust!

This will download and install the official compiler for the Rust
programming language, and its package manager, Cargo.

Rustup metadata and toolchains will be installed into the Rustup
home directory, located at:

/Users/bymin/.rustup

This can be modified with the RUSTUP_HOME environment variable.

The Cargo home directory is located at:

/Users/bymin/.cargo

This can be modified with the CARGO_HOME environment variable.

The cargo, rustc, rustup and other commands will be added to
Cargo's bin directory, located at:

/Users/bymin/.cargo/bin

This path will then be added to your PATH environment variable by
modifying the profile files located at:

/Users/bymin/.profile
/Users/bymin/.zshenv

You can uninstall at any time with rustup self uninstall and
these changes will be reverted.

Current installation options:


default host triple: x86_64-apple-darwin
default toolchain: stable (default)
profile: default
modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
> 3

로 설치 후 ,

bymin@homeui-MacBookPro ~ % rustc --version
rustc 1.76.0 (07dca489a 2024-02-04)

2월 4일 버전으로 설치가 되는 것을 확인할 수 있었습니다.

IntelliJ rust 책에서 알려준 가이드로 접속하면 RustLover 라는 사이트로 이동이 됩니다. 젯브레인을 자주 사용하므로, RustLover(RR) 을 설치합니다.

이 책에서는 웹 프레임워크를 actix-web 을 사용하고, 주석을 통해서 모든 소스를 받을 수 있습니다.
https://github.com/LukeMathWalker/zero-to-production 로 pork 받아, 소스를 보면서 진행을 따라가는 것도 좋을 듯했습니다.

https://actix.rs 에 가서 기본 샘플을 그대로 따라하고, doc 을 한번 읽는 것이 좋을듯합니다.

use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, HttpRequest};

#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().body("Hello world!")
}

#[post("/echo")]
async fn echo(req_body: String) -> impl Responder {
HttpResponse::Ok().body(req_body)
}

async fn manual_hello() -> impl Responder {
HttpResponse::Ok().body("Hey there!")
}

async fn greet(req: HttpRequest) -> impl Responder {
let name = req.match_info().get("name").unwrap_or("World");
format!("hello {}!", &name)
}

#[tokio::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().route("/", web::get().to(greet))
.route("/{name}", web::get().to(greet))
})
.bind("127.0.0.1:8000")?
.run().await
}

위의 소스는 예제 소스와, 책의 소스를 혼합하여 서버를 구동하였습니다.

문서 상 Cargo.toml 의 상세내용을 추가해야합니다.

[package]
name = "zero2prod"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web = "4"
tokio = { version = "1.36.0", features = ["rt", "rt-multi-thread", "macros"] }

책 내용과는 조금 다르게 변경되었지만, 정상적으로 동작됩니다.

Jan 8, 2024 - Gradle 6.x to 8.x 업그레이드 가이드

Gradle 6.x에서 8.x로의 업그레이드 시, 여러 변경 사항이 있습니다.

아래는 주요 변경 내용입니다:

1. 의존성 관리 변경

1.1 compileimplementation

Gradle 8.x에서는 compileimplementation으로 변경되었습니다.

이전:

compile 'group:artifact:version'

변경 후:

implementation 'group:artifact:version'

1.2 api → implementation (옵션)

Gradle 5.x 이상에서 도입된 api는 그룹 간 의존성을 전파시키는 역할을 했습니다. 8.x에서는 이를 implementation으로 대체하였습니다.

이전:

compile 'group:artifact:version'

변경 후:

implementation 'group:artifact:version'

2. 테스트 의존성 변경

2.1 testCompile → testImplementation

테스트 의존성을 선언할 때 testCompile은 testImplementation으로 변경되었습니다.

이전:

testCompile 'group:artifact:version'

변경 후:

testImplementation 'group:artifact:version'

3. 기타

3.1 compileOnly는 그대로 유지

Gradle 8.x에서도 compileOnly는 변경되지 않았습니다.