Q&A

마지막 강의에선, 학생들이 등록한 질문을 답변했습니다:

프로세스, 가상메모리, 인터럽트, 메모리 관리와 같은 운영체제 관련 주제를 배우는 방법을 추천해주실 수 있나요?

가장 먼저, 위와 같은 주제가 매우 밑단(low level)의 내용이기 때문에 친숙해질 필요가 있을지 의문입니다. 커널(Kernel)을 구현하거나 수정하는 것과 같이 더욱 밑단의 코드를 구현할 때 이런 주제들이 필요할 것입니다. 아니라면, 이전 강의에서 다루었던 프로세스나 관련 명령어 외에는 대부분의 운영체제 주제들이 필요로 하지 않을 것입니다.

위 주제를 배우는 데 도움이 되는 자료는 다음과 같습니다:

가장 우선순위에 두어 배워야 하는 툴이 무엇인가요?

몇몇 주제들은 우선순위에 두어야 할 가치가 있습니다:

파이썬, 배시 스크립트(bash script), 그 외 언어들은 각각 언제 사용하는 건가요?

일반적으로, 배시 스크립트는 특정 일련의 커멘드를 실행하여 사용하는 경우 일회성으로 유용하게 사용할 수 있습니다. 배시는 더 큰 프로그램이나 스크립트에서 작업하기 어렵게 만드는 특이한 특징을 가지고 있습니다:

그러므로 더 크고 복잡한 스크립트의 경우 Python과 Ruby와 같은 상위 언어를 사용하는 것을 권장합니다. 위에서 언급한 언어들로 온라인에선 이미 다양한 문제를 해결하는 사람들이 만든 수많은 라이브러리를 찾을 수 있을 겁니다. 만약 여러분이 원하는 특정 기능을 지원하는 라이브러리가 특정 언어를 사용한다면, 가장 좋은 해결 방법은 그 언어를 사용하는 것입니다.

source script.sh./script.sh의 차이점은 무엇인가요?

두 명령어 다 배시 세션(bash session)에서 script.sh를 읽고 실행하지만, 어떤 세션에서 스크립트를 실행하는지에 따라 달라집니다. source의 경우 현재 배시 세션에서 실행되기 때문에, 스크립트를 통해서 실행되는 디렉터리 변경이나 함수 정의와 같은 환경에 대한 모든 변경사항은 유지됩니다. ./script.sh와 같이 스크립트를 홀로 실행한다면, 현재 배시 세션에서 script.sh에 있는 커맨드를 실행하는 새로운 배시 인스턴스를 실행하게 됩니다. 그러므로, script.sh가 디렉터리를 변경한다고 하면 새로운 배시 인스턴스에서는 디렉터리를 변경되지만, 스크립트를 나가고 부모 인스턴스(이전 인스턴스)에 돌아오면 부모 세션에선 디렉터리가 변경되지 않습니다. 마찬가지로 script.sh 터미널에서 사용하고 싶은 함수를 정의했다면, 여러분은 현재 배시 세션에 적용하기 위해 source로 실행해야 합니다. 그렇지 않으면, 현재 쉘 대신 새로 생성된 배시 인스턴스에 함수가 정의될 것입니다.

다양한 패키지와 툴은 어디에 저장되며 참조되는 건가요? /bin 또는 /lib 인가요?

터미널에서 실행하는 프로그램은 모두 PATH 환경변수에 나열된 디렉터리에 있으며, 특정 프로그램을 찾는 위치를 확인하기 위해 which 명령어(또는 type 명령어)를 사용할 수 있습니다. 일반적으로 특정 유형의 파일이 어디에 존재하는지에 대한 몇 가지 규칙이 있습니다. 하단에 우리가 여태까지 이야기했던 경로들이 있습니다. 더욱 포괄적인 목록들은 파일시스템 계층구조 표준에서 확인하세요.

파이썬과 관련된 것들을 apt-get install으로 설치해야 하나요, 아님 pip install로 설치해야 하나요?

이 질문에 대한 명확한 답변은 없습니다. 대신 이는 시스템의 패키지 매니저를 사용해야 하는지 언어별 패키지 매니저를 사용하여 소프트웨어를 설치해야 하는지에 대한 보다 일반적인 질문과 관련이 있습니다. 고려해야 할 몇 가지 사항은 다음과 같습니다:

여러분은 두 방식을 동시에 사용하면 충돌이 일어나고 디버깅하기 어려우므로 두 가지 방식 중 한 가지를 선택해 사용해야 합니다. 저희의 추천사항으로는 가능하면 언어별 패키지 매니저를 사용하고 시스템 전반 환경을 수정하는 걸 막기 위해 (파이썬의 virtualenv와 같은) 가상환경을 사용하는 것입니다.

제 코드의 성능을 향상하기 위해서 사용하는 가장 쉽고 좋은 프로파일링(profiling) 툴들은 무엇인가요?

프로파일링을 목적으로 사용하는 꽤 도움되는 가장 쉬운 툴은 시간을 출력하는 것입니다. 여러분은 그저 여러분의 코드에 각각 다른 부분을 시간으로 재어서 확인하는 것입니다. 이를 반복한다면 여러분은 코드를 이중 탐색(binary search)해 어느 부분이 시간이 오래 걸리는지 찾아낼 수 있습니다.

더욱 발전된 툴로써는 Valgrind의 Callgrind를 사용하면 프로그램을 실행하고 모든 것이 얼마나 걸리는지, 스택 상황은 어떤지, 어떤 함수가 다른 함수를 호출하는지 확인할 수 있습니다. 그리고 Callgrind는 소스코드에 줄별로 얼마나 시간이 걸리는지 주석 처리를 한 새로운 코드를 만들어줍니다. 하지만 Callgrind는 여러분의 프로그램을 더욱 느리게 하고 쓰레드(thread)를 지원하지 않습니다. 다른 경우에는 perf 툴이나 다른 언어에서 지원하는 샘플링 프로파일러 (sampling profiler)를 사용하면 유용한 데이터를 빠르고 예쁘게 내보냅니다. Flamegraphs는 위 툴로 나온 데이터를 출력하기 위한 좋은 시각화 도구입니다. 또한, 작업 중인 프로그래밍 언어 또는 작업에 대한 특정 도구도 존재합니다. 예를 들어 웹 개발의 경우, Chrome과 Firefox에 내장된 개발 도구는 환상적인 프로파일러를 가지고 있습니다.

가끔 여러분의 시스템이 파일을 읽거나 네트워크 패킷을 보내는 등의 이벤트(시스템 호출)를 기다리는 파트가 여러분의 코드 중 가장 느린 곳일 겁니다. 이러면 하드웨어 기능 측면에서 이론적 속도에 대한 내부(back-of-the-envelope) 계산이 실제 판독 값에서 벗어나지 않는지 확인할 필요가 있습니다. 시스템 호출의 대기 시간을 분석할 수 있는 특수 도구도 있습니다. 예를 들어 eBPF와 같은 도구는 사용자 프로그램의 커널 추적을 도와줍니다. 만약 이러한 저수준의 프로파일링을 해야 한다면 bpftrace도 사용하면 좋습니다.

어떤 브라우저 플러그인을 사용하시나요?

사용하는 플러그인들은 주로 보안과 유용성에 초점이 맞춰져 있습니다:

데이터를 다룰 수 있는 다른 유용한 툴은 무엇이 있나요?

우리가 데이터 처리 강의 때 다루지 못했던 다른 툴로는 jqpup가 있는데, 이는 각각 JSON과 HTML에 최적화된 데이터 파서(parser)입니다. Perl 프로그래밍 언어 역시 더욱 고수준의 데이터 처리 파이프라인(pipeline)을 다루는 데 도움이 됩니다. 또 다른 기술은 공백 텍스트를 적절하게 정렬된 텍스트로 변환하는 데 사용할 수 있는 column -t 명령어입니다.

일반적으로 더욱 독특한 데이터 처리 툴은 Vim과 Python입니다. 일부 복잡하고 다중 줄의 변경을 원하는 경우 Vim 매크로는 매우 귀중한 툴이 될 수 있습니다. 일련의 동작을 기록하기만 하면 될 뿐 아니라 원하는 횟수만큼 반복할 수 있는데, 예를 들어 편집기 렉쳐 노트 (그리고 작년 강의 영상)에는 XML-formatted 파일을 Vim 매크로만으로 JSON으로 바꾸는 예시가 있습니다.

CSV로 제공되는 표로 나타낸 데이터들은 Python 라이브러리인 pandas라는 좋은 툴이 있습니다. 그룹별로, 조인(join) 또는 필터와 같은 복잡한 작업을 쉽게 정의할 뿐만 아니라 데이터의 서로 다른 속성을 쉽게 표시할 수 있기 때문입니다. 또한 pandas에선 XLS, HTML, LaTex와 같이 표로 나타낸 다양한 파일 형식으로 변환하는 것을 도와줍니다. 대안으로는 R 프로그래밍 언어 (논의할 필요 없이 나쁜 프로그래밍 언어)에서는 데이터를 통한 통계 계산에 많은 기능이 있으며 파이프라인의 마지막 단계로 상당히 유용할 수 있습니다. ggplot2는 R의 훌륭한 플롯 라이브러리입니다.

도커(Docker)와 가상 머신(Virtual Machine)의 차이점은 무엇인가요?

도커는 컨테이너(container)라고 불리는 좀 더 일반적인 개념에 기반을 두고 있습니다. 컨테이너와 가상 머신의 주요 차이점은 가상 머신은 커널(kernel)이 호스트 시스템과 같더라도 커널을 포함한 전체 OS 스택을 실행한다는 것입니다. VM(가상 머신)과 달리 컨테이너는 다른 커널 인스턴스를 실행하지 않고 커널을 호스트와 공유합니다. Linux에서 이것은 LXC라는 메커니즘을 통해 달성되며, 일련의 격리 메커니즘을 사용하여 자체 하드웨어에서 실행된다고 생각되는 프로그램을 실행하지만 실제로는 호스트와 하드웨어와 커널을 공유합니다. 따라서 컨테이너는 전체 VM보다 오버헤드(overhead)가 낮습니다. 반대로 컨테이너는 가상 머신보다 더 약한 격리를 가지며 호스트가 컨테이너와 같은 커널을 실행하는 경우에만 작동합니다. 예를 들어, MacOS에서 도커를 실행하는 경우 도커는 초기 Linux 커널을 얻기 위해 Linux 가상 시스템을 실행해야 하므로 오버헤드는 여전히 상당합니다. 마지막으로, 도커는 컨테이너의 구체적인 구현이며 소프트웨어 배포에 적합합니다. 이 때문에 일부 이상한 점이 있는데, 예를 들어 도커 컨테이너는 기본적으로 재부팅을 하면 모든 저장 정보가 초기화됩니다.

운영 체제 간 장단점이 각각 어떻게 되고 그 중 어떤 걸 골라야 하나요? (예를 들어 우리의 목적에 맞는 Linux 배포판을 고르는 등)

Linux 배포판(distro)이 많아도, 각각은 대부분의 사용 사례에서 상당히 같게 작동될 것입니다. 대부분의 Linux 및 UNIX 기능들은 대부분의 배포판에서 배울 수 있습니다. 배포판들의 주요 차이점은 패키지 업데이트를 다루는 방법입니다. Arch Linux와 같은 배포판은 문제점이 많은 양날의 검인 롤링 업데이트 정책을 사용한다. 반대로 Debian, CentOS, Ubuntu LTS와 같은 배포판은 리포지토리(repository)에 업데이트를 릴리스할 때 훨씬 엄격하므로, 새로운 기능을 희생시켜 더 안정적이다. 데스크톱과 서버에 쉽고 안정적인 경험을 하고 싶다면 Debian이나 Ubuntu를 추천한다.

macOS는 인터페이스를 잘 다듬은 Windows와 Linux 사이의 좋은 타협점입니다. 다만 macOS는 Linux보단 BSD에 기반을 두기 때문에, 시스템과 명령어가 약간 다릅니다. 한번 다룰만한 대안은 FreeBSD입니다. 비록 일부 프로그램이 FreeBSD에서 돌아가지 않겠지만, BSD 환경은 Linux보다 훨씬 덜 단편화되어있고 더 잘 문서화되어 있습니다. Windows 애플리케이션을 만들거나 게임을 위한 훌륭한 드라이버 지원과 같은 Windows만의 인정할만한 기능들을 사용해야 할 때 외에는 Windows는 추천하지 않습니다.

듀얼 부팅으로 시스템을 설계할 때엔 macOS의 bootcamp가 가장 좋은 조합이라고 생각합니다. 다른 조합은 디스크 암호화와 같은 다른 기능들을 적용하여 사용할 때 장기적으로 문제가 될 수 있습니다.

Vim vs Emacs?

3명의 강의자는 다 주력 에디터로 Vim을 사용하지만, Emacs 역시 좋은 대안품이니 둘 다 사용해보고 어느 것이 여러분에게 맞는지 찾아보세요. Emacs는 Vim의 모달(modal) 편집을 지원하지 않지만, Evil이나 Doom Emacs를 사용해 이를 지원하게 할 수 있습니다. Emacs를 사용하는 장점은 Vim의 기본 스크립팅 언어인 Vimscript보다 더 나은 스크립팅 언어인 Lisp에서 확장 프로그램을 구현할 수 있다는 것입니다.

머신 러닝을 위한 팁이나 기술들이 있나요?

이 수업의 강의나 기술들을 가지고 바로 ML(Machine Learning - 머신러닝)에 적용할 수 있습니다. 많은 과학 분야는 그렇듯이, ML에서는 종종 일련의 실험을 수행하며 어떤 것이 효과가 있고 어떤 것이 효과가 없었는지 확인하고 싶어합니다. 쉘(shell) 툴를 사용하여 이러한 실험을 쉽고 빠르게 검색하고 결과를 합리적인 방법으로 집계할 수 있습니다. 예를 들어 특정 기간 모든 실험을 하위 선택하거나 특정 데이터 집합을 사용할 수 있다는 것입니다. 간단한 JSON 파일을 사용하여 실험의 모든 관련 정보들을 정리하는 작업을 이 강의에서 다룬 도구를 사용하면 믿을 수 없을 정도로 간단히 할 수 있습니다. 마지막으로 GPU로 사용하는 클러스터(cluster)로 작업하지 않는 경우, 이 프로세스는 상당한 시간이 걸려 멘탈이 흔들릴 수 있으므로 자동화하는 방법을 살펴봐야 합니다.

다른 Vim 팁이 있나요?

몇가지 더 있습니다:

2FA란 무엇이고 왜 사용해야 하나요?

투팩터 인증(2FA - Two Factor Authentication)는 여러분 계정의 보안을 비밀번호 말고도 하나의 추가적인 보안 단계를 추가하는 것을 말합니다. 2FA를 사용한 계정에 로그인하려면, 비밀번호를 알아야 하는 것은 물론이고 계정주 본인의 하드웨어에 접근할 수 있는지 “증명”해야 합니다. 가장 쉬운 예시로는 핸드폰의 문자를 받아 인증을 받는 SMS 2FA가 있습니다. 다만 이는 알려진 문제점이 있어, 더 나은 대책으로는 YubiKey와 같은 U2F 솔루션을 사용하는 것이 좋다.

웹 브라우저의 차이점에 대한 의견이 있나요?

현재 2020년 기준 대부분 브라우저는 같은 엔진(블링크 - Blink)을 사용하기 때문에 Chrome과 비슷합니다. 블링크를 기반으로 하는 마이크로소프트 엣지와 블링크와 비슷한 엔진인 웹킷(WebKit)을 기반으로 하는 사파리는 크롬의 하위호환일 뿐입니다. 크롬은 성능과 사용성 측면에서 모두 상당히 좋은 브라우저입니다. 만약 대안을 원한다면, Firefox를 추천합니다. Firefox는 거의 모든 면에서 Chrome과 견줄 만하고 프라이버시 때문에 뛰어납니다. 또 다른 브라우저인 Flow는 아직 사용자가 사용할 수 있을 만큼 발전되지 않았지만, 현재보다 빠른 속도를 약속하는 새로운 렌더링 엔진을 구현하고 있습니다.


이 페이지를 수정.

CC BY-NC-SA에 따라 라이센스를 부여합니다.