Jonathan E. Steinhart 의 <한 권으로 읽는 컴퓨터 구조와 프로그래밍>을 읽고 정리하는 온라인 책터디.
매주 2 챕터씩 진행합니다.
요약된 내용은 모두
Jonathan E. Steinhart. (2021). 한 권으로 읽는 컴퓨터 구조와 프로그래밍(오현석, 역). 경기: 책만. (원서 2019년 발행)
>>> 책터디 _8주차
이미 해결된 문제를 자신이 좋아하는 방식으로 다실 풀 경우 가치가 늘어는 것이 아니다.
가능하다면 기존 도구를 개선해야 한다. 이로 인해 더 많은 사람이 혜택을 얻을 수 있다.
새 도구를 만들기보다는, 사용 중인 도구를 이해했는지 확인할 것.
생태계에 순응하고, 대항하지 마라.
소프트웨어 개발의 발전
멀틱스(Multics) 운영체제
: 큰 GE645 메인프레임 컴퓨터에서 실행
1960년대에 벨 전화 연구소와 제너럴 일렉트릭, MIT 가 협력하여 개발
유닉스(UNIX)
: 벨은 멀틱스
프로젝트 참여자 일부(켄 톰슨, 데니스 리치)와 디지털 이큅먼트사(DEC)의 더 작은 컴퓨터에서 실험
-> 최소주의와 모듈화 철학의 새 운영체제인 UNIX 개발. 첫번째 이식가능한(portable) 운영체제.
마이크로소프트 위도우가 유일하게 유닉스 계열이 아니면서, 널리 쓰이는 운영체제이나,
이 조차도 네트워킹에 사용하는 소켓 모델에 더 많은 유닉스 특징 채용
이 책에서는, 유닉스 - 리눅스, 프리BSD(freeBSD), 넷BSD(NetBSD), 오픈BSD(OpenBSD),
최근의 맥OS(macOS) 등의 유닉스 계열 시스템을 모두 포함하는 용어로 사용됐다.
BSD(Berkeley Softweare Distribution)
: 버클리 소프트웨어 배포판
켄 톰슨이 유닉스 복사본 가져와, 학생들이 사용하면서 버클리 자체의 유닉스 버전 만듬.
썬 마이크로시스템즈(Sun Microsystems)회사 창업, 유닉스 기반의 상업적 시스템 판매
-PC : 1980년대 중반 유명해짐.
PC가 저렴해서 대학 교육에 활용하기 시작하면서, PC로 교육받은 사람들은 시스템의 소스 코드 볼 수 없어졌다.
- FOSS(free and open source software) : 자유로운 오픈소스 소프트웨어.
자유롭게 사용 가능하고 법적으로 방해받을 걱정이 없는 소프트웨어
- 오픈소스 : 소스 코드가 열려있어서 누구나 볼 수 있고, 더 중요한 것으로 변경하거나 향상 할 수 있다.
- 카피레프트(copyleft) : 카피라이트(copyright)의 변종. 리처드 스톨먼(Richard Stallman).
다른 사람이 소프트웨어를 자유로, 무료로 사용 변경을 허용하는것.
카피레프트로 소프트웨어 변경한 사람은 다른사람에게 마찬가지로 카피레프트, 변경을 허용해야한다.
*리눅스(Linux) : 리누스 토발즈(Linus Tovalds) 개발. 순식간에 유명해짐. 데이터 센터(클라우드), 안드로이드, 가전제품 등에 많이 쓰인다.
"어떤 프로젝트가 오픈소스라고 해서 그 프로젝트가 잘 만들어진 소프트웨어의 훌륭한 예라는 뜻은 아니다.
하지만 다른 사람의 코드를 살펴보면, 무엇을 해야 할지를 배우는 것만큼이나 무엇을 하지 말아야 할지도 배울 수 있다."
예술작업의 중요성을 깨닫고 크리에이티브 커먼즈(Creative Commons)라는 라이선스를 만듬. 미국 변호사, 학자 로렌스 레식(Lawrence Lessig).
소프트웨어에서 특별한 의미. 소프트웨어 환경 뿐만 아니라 하으뒈어 등 여러 다양한 환경에서 실행될 수 있음.
"현대 시스템은 상당수가 유닉스 기반이기 때문에 과거에 비해 훨씬 서로 비슷하다.
시스템 사이에 매끄럽지 못한 부분은 대부분 GNU 빌드 도구가 제대로 처리해준다."
* GNU : Gnu is Not Unix. 1983년 리처드 스톨먼(Richard Stallman)이 시작. 법적 방해 걱정 없는 자유로운 유닉스 버전 개발이 목표.
* GNU 빌드 도구 : GNU 프로젝트가 automake, autoconf, libtool 등이 들어잇는 빌드 도구(build tool)집합 개발.
"미리 컴파일된 프로그램은 시스템 안에 자신이 의존하는 올바른 버전의 라이브러리가 없으면 제대로 작동하지 않는다."
리눅스에서도 패키지 관리(package management) 활성화.
그러나 패키지 관리프로그램은 서로 호환되지 않으므로, 각기 다른 시스템에서 설치 준비하려면 작업량이 늘어난다.
패키지 관리 문제를 해결하기 위해 최근에 등장한 접근 방법.
애플리케이션과 모든 의존관계를 컨테이너에 한번에 담는 것. 소프트웨어 디플로이(deploy)를 단순화.
단점 : 컨테이너가 공유 라이브러리 사용을 없애고 메모리 활용도 감소. 애플리케이션 자체보다 컨테이너가 크다.
- 스냅(snap) : 컨테이너화된 애플리케이션.
Ex) 컨테이너 리눅스(Container Linux). 리눅스를 컨테이너에서 가볍게 실행.
우분투(Ubuntu)를 만든 캐노니컬(Canonical)에서 만든 애플리케이션용 컨테이너 환경.
- 배포(distribute)는 소프트웨어를 사용자 등에게 전달하는 것.
- 디플로이,전개(deploy)는 소프트웨어 설치, 실행 상태로 만드는 것.
자바는 썬 마이크로시스템즈에서 제임스 고슬링(James Gosling)이 이끄는 팀에 의해 1991년부터 만들어졌다.
자바 언어는 C, C++와 닮았다.
자바 가상 머신이라 불리는 바이트코드(Bytecode)라는 기계어를 실행하는, 자바 인터프리터만 재컴파일해두면
코드를 한 번만 작성하고나면 어디서나 이 코드를 실행할 수 있도록 하는 아이디어 가짐.
자바는 자바언어를 감싸는 여러 소프트웨어로 이뤄진 전체 생태계를 의미한다.
자바가 쓰인 이유
-가비지 컬렉션을 통해 메모리 관리 -> 초보자에게 복잡한 메모리 관리 가르치지 않아도 된다.
단점
-자바 생태계에 여러 전용 도구와 파일 형식이 프로그래머를 힘들게 함
- " 자바 프로그래머는 한 줄로 충분한 코드에 몇백 줄의 코드를 작성하는 경향이 있다. ... 아름다운 클래스 계층을 유지하는 것에 대한 환상적인 강박관념이 있어서 때로는 어떤 목표를 달성하는 것보다 클래스 계층 유지에 더 우선순위를 두곤 한다. "
자바스크립트(브라우저에서 사용하는 스크립팅 언어로 시작)가 브라우저 밖에서 실행되게 해주는 최근에 나온 환경.
클라이언트와 서버 쪽 애플리케이션을 하나의 프로그래밍 언어로 작성할 수 있다는 점.
생각이 멋지기는 하나 결과는 때마다 다르다.
노드는 호환되지 않는 방법으로 자신만의 패키지 관리자를 만들어서, 시스템 유지보수를 어렵게 한다.
의존성이 꼬인 노드 패키지가 상당히 많고 심각한 작업데 적당하지 않다.
네크워크를 통해 다른 누군가의 컴퓨터를 쓴다는 뜻.
네트워크가 전세계로 퍼졌고, 저렴해진 하드웨어 가격덕에 흥미로워짐.
그러나 단지 소프트웨어와 하드웨어의 조합일 뿐. 컴퓨터 자원을 빌려주는 새로운 비즈니스 모델.
엄청난 수의 기계를 한 공간에 밀어 넣으려면 전원과 냉각에 엄청나게 신경 써야 한다.
* 시분할 : ?
하드웨어 환경과 운영체제가 실행되기 위한 명령어 집합을 제공하고, 운영체제가 예상하는 하드웨어 환경을 따로 제공해주기 위한 시스템.
장점 : 특정 운영체제에 종속되는 것을 방지. 운영체제 개발시 도움.
클라우드 컴퓨팅의 주류. 클라우드 상에서 공간을 빌리고, 원하는 운영체제를 조합해 실행할 수 있다.
하이퍼바이저(hypervisor)라고 부르기도 한다.
큰 컴퓨팅 파워와 기능을 제공하는 이동식(portable) 장치 개발.
Ex) 휴대전화. 몇십 년 전 전세계 컴퓨터 능력을 합한 것보다 더 큰 컴퓨팅 파워를 제공한다.
프로그래밍에서 만족스러운 점 중 하나는 예전에 해본 적 없는 일도 할 수 있다는 점이다.
어떻게 하면 해보기도 전에 필요한 기술을 갖출 수 있을까? 어떻게 해야 '경험'을 잘 정의할 수 있을까?
무엇보다 기본이 탄탄해야 한다. ...
경험이란 무엇을 할 수 있고 무엇을 할 수 없는지를 아는 것이라는 점이다. ...
추정은 경험을 바탕으로 하는 직관적인 어림짐작이다.
" 프로젝트 팀원으로 할 수 있는 가장 파괴적인 행위는 아무 경고도 없이 결과물을 제때 전달하지 않는 것이다. .. 갑자기 팀원들에게 기한을 맞추지 못하겠노라고 뒤늦게 알린다면 그에 바로 대응해 작업할 수 있는 사람은 거의 없다. "
- 연습을 통해서 숙제, 작업 시작 전에 얼마나 걸릴지 추정 값을 적어두자.
- 그 후 실제 작업이 얼마나 걸렸는지 추적하자.
- '상황 일지' 작성하자. - 달성한 내용, 생겨난 문제, 다음 보고까지 어떤 일 할지
계획을 달성하지 못했는데 새로운 문제도 없다면 이는 문제.
프로젝트의 모든 요소를 목록화.
각각을 1시간, 1일, 1주일 등의 단위로 세분화.
'상황 일지'가 핵심.
그는 누군가가 자신의 선호를 정당화하고 싶은데 선호한다는 이야기는 하기 싫어서 진행되는 보갑한 의사기술적인 논쟁을 듣고 싶지 않다고 하면서, 이런 식으로 자기 생각을 정당화하는 사람은 원하는 것을 어지 못할 뿐만 아니라 잘못하면 직장을 잃을 수도 있다고 경고했다.
개인적인 선호와 기술적인 필요성을 서로 분리해야 한다.
나는 '코딩은 재미있지 않으며, 기술적으로나 윤리적으로 복잡한 작업이다'라는 이탈리아 연구자인 월터 바니니(Walter Vannini)의 글에 동의한다.
어떤 이데올로기(방법론)든 너무 심각하게 발아들이지 마라. 그 어떤 이데올로기도 순수한 형태로 동작하는 경우는 없다. 필요한 아이디어를 골라잡아서 프로젝트에 맞춰 사용하면 된다.
아이디어를 글로 써보자. 문서를 올바른 수준까지 작성.
부분적으로 작동하는 프로젝트 결과물을 사람들에게 내보이는 것.
-프로토타입은 던져버리고, 프로토타입에서 배운 내용을 기초로 새로운 코드를 작성할 것.
-외부에 배포할 수 있는 제품으로 착각하지 말것.
-유스케이스(use case)문서화
*유스케이스 : 어떤 작업을 완수하기 위해 API를 사용하는 상황을 뜻함
-사용자 요구를 추상화 -> 해법 만들기
*추상화(abstraction) : 다양한 유형의 대상 Ex) 개, 고양이, 말은 -> '동물' 로 추상화
APT(applicaton program interface) :
애플리케이션 프로그램 인터페이스.
소프트웨어 스택에서, 한 스택과 다른 스택 사이의 선.
* 훌륭한 인터페이스
- 내부 구현 노출 X
- 높은 응집도. 좋은 추상화 제공
- 확장 가능성(extensible, 새로운 필요에 맞춰 변화 가능). 잘 된 추상화가 도움.
- 최소화
- 모듈화. 기능들이 서로 독립적.
- 기능의 합성 기능(composable). 여러 기능의 조합 가능성.
-프로그래밍 환경으로 리눅스, 유닉스 파생 환경 선택
맥 - 맥OS는 유닉스 기반으로 준비 끝.
PC - 리눅스 설치. 가상 머신에 리눅스 설치. 버추얼박스(VirtualBox) 윈도우에 설치 뒤, 리눅스를 그 위해서 실행
"셸이 제공하는 기능 중에는 명령을 파일에 넣어서 실행 될 수 있는 프로그램을 만드는 강력한 기능이 있다.
여러분이 어떤 일을 수행하기 위해 같은 명령들을 계속 반복해서 사용한다면,
이 일을 하는 명령을 파일에 넣어서 새로운 명령을 직접 만들 수 있다.
이런 식으로 명령을 만들어 활용하면 보기 좋은 그래픽 화면에서 버튼을 클릭하고 결과를 기다리는 것보다
훨씬 더 생산적으로 일할 수 있다."
의존관계를 가능하면 한 곳에 모아두라.
새로운 버전의 버그를 추가한 경우 어떤 부분이 변경됐는지 확인해야 하기 때문에, 소스 코드를 과거로 돌릴 수 있어야 한다.
여러 사람이 분선되어 진행하는 프로젝트의 경우 Git깃이 유명하다. 깃을 배워라.
테스트를 하지 않으면 프로그램이 잘 작동하는지 실제로 알 수가 없다.
코드의 인터페이스나 동작은 바꾸지 않고 코드 내불르 재작성해 개선하는 과정
왜 ?
코드가 완성되면 코드가 지저분해지거나 나은 방법을 알게 되는 경우때문에. 리팩토링으로 유지 보수 비용 줄일 수 있다.
현실에서는 누구든지 코드의 어떤 부분이든 빠르게 살펴보고 무슨 일을 하는지 이해할 수 있는 것이 더 중요하다. 유지보수할 수 없는, 그저 아름다운 코드를 작성하면 실패하기 쉽다.
오픈소스 소프트웨어의 멋진점. 여러분이 기여할 수 있다는 점. 이들 중 많은 프로젝트는 문서화 등에 도움이 필요하다.
소프트웨어도, 문서도 깔끔하게 잘 작성.
프로젝트를 끝내기 위해 노력하라.