1. 아니.... 핸드폰 음악 재생을 액티브2에서 할 수 있을 줄 알았는데 안되더라..?

음악을 들으면서 운동을 하고 싶다?

내 아이콘X는 노래를 듣기 위해 핸드폰에 연결되어 있다. 그리고, 액티브2가 운동을 체크해줄 수 있으니 헬스는 액티브2에서 실행했다.

렛풀다운을 한다고 했을 때 한 회 할 때마다 횟수를 세주는 기능이 있다. 그런데 아이콘X는 핸드폰에 연결이 되어 있으니 운동 횟수를 오디오로 들을 수 있는 기능은 있으나 마나한 기능이다...ㅋ

 

2. 삼성 헬스 "기본 운동" 기능 휴식 시간 설정 여부

내가 못찾은 건지 없는건지 기본 휴식 시간이 1분으로 되어 있는데 이거 조절 어디서 하는지 모르겠다.

그리고 "기본 운동"기능....

일시 정지는 가능한데 내가 얼마나 쉬었는지 알 수가 없다....ㅋㅋ

아니 목표 설정기능으로 3세트 몇회 이런식으로 설정 해놓고 사람이 대신 세고, 다음 다음 버튼 누르면서 휴식시간이랑 운동시간 체크 할 수 있게 하면 되지 그게 뭐 어렵다고 이따구로 만들어놨는지 진심 이해가 안간다.

지원을 안하는 건가.... 할 생각이 없는건가.... 운동 안해본 사람들만 모아놓은 건가...

 

3. 보통 헬스를 하는 사람은 각 사람만의 루틴이 있다. 하지만 삼성 헬스 앱에는 이런 루틴을 설정할 수 있는 곳도 없다...ㅋㅋㅋ 내가 하나씩 일일이 다 눌러줘야대 ㅋㅋㅋㅋㅋㅋ

'끄적끄적' 카테고리의 다른 글

[2019.06.04] 작은 습관  (0) 2019.06.04

어제 sbs 스페셜의 "작은 습관이 인생을 바꾼다"라는 프로그램을 보고 잠을 못잤다. 

머릿 속에 무수히 많은 생각들이 스쳐지나가면서 앞으로 어떤 길을 나아가야할지 결정하지 못했기 때문이다.

 

"그래 일단 작은 것부터 해보자"라는 생각으로 작은 습관 2가지를 결정했다.

 

1. 하루 팔굽혀펴기 10회

 

원래 매일 헬스를 가지만 현재 라섹 수술 회복기간이라 헬스를 쉬고 있다. 그래도 팔굽혀펴기 10회는 괜찮겠지... 라는 마음으로 결정하였다. 혹여 헬스를 가지 못하더라도 팔굽혀펴기는 무슨 일이 있어도 하기로 결정하였다.

(작은 습관이니깐!)

 

2. 하루 책 2장

 

이론상 300페이지의 책이 있으면 하루 2장... 150일이면 한 권을 다 읽을 수 있다. 5개월에 1권이면 많은 건 아니지만... 책 안 읽는 사람도 겁나 많잖아?

시작이 반이라는 소리가 괜히 있는 게 아니라고 생각한다.

그리고 내가 하루에 2장 읽는다고 진짜 2장만 읽고 넘길 것도 아니고..ㅎ 하루에 3장 읽으면 100일(약 3개월)만에 한 권 읽을 수 있다. 

그래서 시작해보려 한다.

 

+ 읽은 책 내용을 1~2줄로 계속 업로드를 해볼 예정이다. 이건 잘 지켜질진 모르겠지만 글을 쓰기 위해 읽으면 더욱 집중이 될 것 같아서 한 번 시작해보려 한다.

 

 

'끄적끄적' 카테고리의 다른 글

[갤럭시 워치 액티브2 사용기] 느낀점  (1) 2019.12.14

[끄적끄적]

6월 2일 방영했던 sbs 스페셜 "작은 습관이 인생을 바꾼다"라는 프로그램을 본 후 가장 처음 세운 작은 습관 2가지.

그 중 첫번째가 팔굽혀펴기 10회. 그리고 두 번째가 하루 책 2장 읽기이다.

(최소 2장이 목표이지 2장 읽고 때려치진 않는다)

 

하루 책 2장 읽기를 실천하기 위해 시작.


2019.06.04

 

수학이라는 용어는 "배움으로써 얻는 지식"이라는 뜻의 고대 그리스어 '마테마'에서 유래했다고 한다. 

즉, 수학은 우리의 삶과 더욱 많이 연관되어 있고, 이 책에서는 어떻게 수학을 이용하여 정보를 처리하고 생활 속에서 매일 사용하는 제품을 개발하는지 살펴본다고 한다.


2019.06.05

 

1장을 읽었다. 1장에서의 키워드는

  • 문자=정보의 매개체
  • 로제타, 코퍼스
  • CheckBit

정도로 볼 수 있겠다.

 

먼저 문자=정보의 매개체라는 말은 당연하면서도 중요한 의미를 가진다. 문자 그 자체로는 "흰 것은 종이요. 검은 것은 글자다"밖에 되지 않는다.

즉, 그 문자의 의미가 우선시되어야 한다는 의미이다. 세익스피어의 글을 보면 문법에 어긋나는 문장들이 다수 있다.

과거 어떤 사람들은 문법에 어긋나는 문장들을 고치기 위해 노력하였는데 이는 밑빠진 독에 물붓는 형국이 되어버렸다.

여기서도 알 수 있다시피 문장에서 중요한 것은 문법이 아니라 문장 안에 있는 정보인 것이다.

우리 집에 AI 스피커 클로바가 있는데 개같이 말해도 찰떡같이 알아듣더라.

 

로제타... 게임 닉네임으로 쓰면 참 괜찮겠다 싶은 단어다.

로제타는 [이집트 상형문자, 이집트 표음문자, 고대 그리스 문자]가 적혀있는 고대 이집트의 역사를 기록한 비석이다.

현재 우리는 이 기록 덕분에 1000년 전 마야 문명보다 5000년 전 이집트 문명의 역살르 더 잘 알고 있다고 한다.

(기록이 이렇게 중요하다)

여기서 유심히 봐야할 것은 바로 하나의 내용을 세 가지 언어로 나눠 썻다는 것이다.

이를 통해

  • "채널 코딩"
    세 가지 언어 중 하나의 내용만 완벽하게 보존된다면 내용의 유실이 발생하지 않는다는 것.
  • "코퍼스(말뭉치)"
    여러 나라 언어를 번역하는데 굉장히 중요한 데이터셋. 기계번역의 기초가 됨.

에 대한 개념을 도입할 수 있다.

 

채널 코딩이라는 단어를 처음 들어봐서 찾아보니 통신 쪽에서 데이터를 안정적으로 보내기 위해 처리하는 작업이라고 한다. 논회 시간에 배운 일종의 Hamming Code같은 느낌으로 봐도 될 것 같다.
또 다른 개념으로는 "소스코딩"이라는 것이 있는데 정보 이론 분야에서 자세하게 다룬다고 한다.

 

과거 프린터가 없었을 때 성경 사본을 만들기 위해 CheckBit를 이용했다고 한다.

(God, Lord와 같이 하나님을 쓸 때 몸을 정갈하게 한다는 것은 알고 있었는데 실수를 줄이기 위해 이런 방법까지 썼다니 놀라울 따름이다)


2019.06.06

 

오늘도 어김없이 작은 습관을 위한 책을 한 4장정도 읽었다. 

인공지능의 시작이라고 불리는, 컴퓨터 과학의 아버지 "앨런 튜링"에서 시작하여

당시 컴퓨터 과학 분야에서 아직 해결되지 않은 문제들을 '다트머스 하계 인공지능 세미나'에서 한 번쯤은 들어봤을 법한 옛날 사람(특히, 섀넌)에 대한 역사적 사실을 설명해준다.

 

하지만 이번 지문에서의 가장 키포인트는

"과거 사람들이 자연어 처리를 어떠한 방식으로 해결하려고 했는가"

라고 볼 수 있겠다.

 

결론부터 말하면 과거 사람들은 인간이 언어를 배우는 방법인 '문법적 접근' 방법을 사용하였다.

(반면 현재는 '의미론적 접근'이라고 볼 수 있겠다.)

언어에 녹아있는 다양한 문법적인 규칙들, 품사, 형태론적인 요소들이 컴퓨터 알고리즘으로 쉽게 구현(?)이 되기 때문이다.

이는 1960년대에 촘스키 형식 언어를 토대로 한 컴파일러 기술이 크게 발전하면서 '문법적 접근' 방법에 더 힘이 실리게 됬다고 이야기한다.

고급 언어도 컴파일러라는 놈으로 해석이 가능하니, 우리의 말도 충분히 가능할 것이라는 직관에서 시작이 된 것이다.

 

하지만 어디 고급 언어가 위대한 자연어와 비교할 수 있단 말인가ㅎ

 

문맥 독립 문법(context independent grammar)의 시간 복잡도는 문구길이의 제곱인데 반해

자연어의 시간복잡도는 문구길이의 6제곱이라고 한다.

길이가 똑같이 10인 문구를 분석하려면 1만배만큼의 시간 차이가 발생한단 뜻이다.(와우)


2019.06.07

 

오늘 읽은 부분의 핵심 키워드는 규칙을 바탕으로 한 구문 분석의 한계와 통계를 바탕으로한 구문 분석으로의 변환 과정에 대한 내용이다.

 

규칙 기반 구문 분석의 한계를 가장 명확하게 보여주는 쉬운 문장 하나가 있다.

The pen is in the box.

The box is in the pen.

두 구문 모두 문법적 오류가 없다.

그리고 첫번째 문장의 경우 영어를 조금이라도 배운 사람이라면 누구나 해석할 수 있는 구문이다.

그럼 두번째 문장을 보자.

박스가 펜 안에 들어가 있다?

pen은 펜이라는 뜻 이외에 울타리란 뜻도 존재한다.

즉, 박스가 울타리 안에 있다. 라는 뜻이된다.

 

이러한 단어의 중의적 성질로 인해 문장의 규칙성만으로는 온전한 기계번역이 이루어질 수 없다.

 

해당 문제를 해결하기 위한 역사적 사실로 음성인식률을 70%->90%로 향상시킨 IBM 왓슨연구소의 '프레더릭 젤리넥'이 있다.

당시 연구소는 통계 기반 방식을 활용해 위와 같은 성과를 도출해냈고, 이는 자연어 번역에 큰 반향을 불러일으켰다고 한다.

하지만 모든 연구자들이 통계 기반 방식을 동의한 것은 아니었다. 이러한 논쟁은 약 15년동안 계속되었다. 결과적으론 통계가 승리했지만 말이다.

 

여기서 무서운 점은 규칙 기반 구문 분석 연구자들은.... 15년동안이나 일종의 삽질을 했다고 봐도 무방하다.

어떠한 분야를 연구하기 위해서는 통찰력, 다른 지식의 수용 자세 역시 상당히 중요하다는 사실이 여실히 들어난다.

 

인문학적(?) 이야기는 이정도로 하고, 그 뒤에는 수학을 이용한 언어 규칙 모델을 수학적으로 표현하고 있다.

조건부 확률 기반이긴 한데 통계 공부 안한지가 너무 오래되서(대학교 때 확률 및 통계 좀 들을 걸 그랬다) 1차적으로 정리를 하고 글을 작성해야겠다.

 

'' 카테고리의 다른 글

[책] 포에버 데이원  (0) 2020.09.18

Linkage Editor의 추가적인 기능들

* 서브루틴을 대체하고, 서브루틴을 패키지화 함.

* 일반적인 라이브러리들이 하나의 program 내에서 multiple storage(동일한 기능을 수행하는 명령어들이 메모리에 중복적으로 Load)되는 것을 피하게 해줌

-> 실행 시간에 common library를 결합해주기 위해 linkage Loader라는 애가 필요



Address Binding

* Assembliing Time : 가장 저급함.... 어셈블리 타임에 어드레스가 결정된다??? 비어있는 어드레스들을 사용할 수 없음

* Load Time : 우리가 지금까지 했던 일반적인 Loader

* Run Time : Dynamic Linking Library. 복잡도는 증가하겠지만, 유연성 역시  증가(Complexity, Flexibility)


각 Linker&Loader의 실행 타임

     * Linkage Editor : before load time 

- Linkage Editor의 역할은 Linking은 되어 있으나 실제 Address는 가지고 있지 않은 일종의 Data로 축적해놓은 상태이다. 이 후 Relocating Loader에 의해 Address를 가지게 된다.

* Linking Loader : at load time

- 7장에서 배운 Loader.

- Pass1 과정에서 external symbols들의 주소를 할당하고

- Pass2 과정에서 실제 Loading, relocation, linking을 수행한다.

* Dynamic Linking : after load time

- execution time까지 linking function을 연기한다.

- execution 되었을 때 subroutine의 load와 linking을 수행된다.

- dynamic loading, load on call 이라고도 불린다.


Dynamic Linking으로 수행되는 Application

* Execution Time 과정에서 외부의 함수 또는 공유된 객체의 실행필요할 경우 허용되어 memory에 적재된다.


load and call(=Dynamic Linking) 요청은 OS의 dynamic Loader에 의해 handling된다.

- 예시 : error handling routines




컴파일러 입문


* 컴파일러란 Translation을 어떻게 할지에 대한 Rule을 가르치는 학문이다.

* Assembler와 달리 자유도가 매우 높기 때문에 쉽사리 눈에 보이지 않다.


좋은 프로그래밍 언어의 요건은

* 문법적인 구조(syntax)와 의미(semantics)가 명확해야 하고,

* 프로그래머의 생각을 자연스럽게 표현할 수 있어야 하며(=문법이 너무 복잡할 경우 불가능)

* 호환성(=이식성)

* 신뢰성

* 모듈화

* 효율성(?)

* 언어의 확장성이 우수(버전 관리를 의미하는 건가?)

* 좋은 프로그래밍 환경 - vendors, consortium이 뒷받쳐줘야 한다.(ex. Java의 eclipse)


용어 설명


컴파일러

* 고 수준의 프로그래밍 언어를 특정 컴퓨터에서 실행 가능한 코드로 변경하는 작업

-ex) C  compiler on SPARC

C 프로그램을 입력받아 SPARC에서 동작 가능한 코드로 변경

* Source Program -> Front_End -> IC(=Intermediate Code) -> BackEnd -> Object Code

- Front_End~Back_End : Compiler의 역할

- Front_End는 language Dependent하고 Back_End는 Machine Dependent하다.


Cross Compiler

* machineA에서 돌아가게 만든 Compiler에 코드를  추가하여 machineB에서 돌아가게 만든 컴파일러



BootStrapping

* 컴파일러(or 어셈블러)를 컴파일 하고자하는 프로그래밍 언어로 작성하는 과정. -> 셀프 호스팅 컴파일러로 이어짐.


Interpreter

* 프로그램을 직접적으로 기계가 동작할 수 있는 sequence로 변환하는  것.


* C : batch-processing -  일괄 처리


* Compiler : Operational System

* Interpreter : Developing System. or Educational System.




기타 잡담

* 상대방과 대화를 할 때 무언가 이해가 안되는 부분이 있는 것은 상대방이 나에게 중요한 핵심을 숨기고 있기 때문이다..ㅋㅋ
























Cascading + Harr를 이용한 장애물 인식


환경


Opencv_Python + Cascading Utility


* Cascading Training 관련 Tool 다운로드 사이트

http://amin-ahmadi.com/cascade-trainer-gui/

* Tool 사용법(Youtube)

https://www.youtube.com/watch?v=EkKOmyF7iqA


Cascading Output : cascade.xml


Opencv_Python에서의 사용 방법



추가

* LibSVM을 활용한 학습 방법

http://jangjy.tistory.com/98?category=754472

- 해당 프로그램을 설치할 때 gnuplot 4.x 버전을 설치하여야 제대로 동작함.





이전에 들었던 수업은 하드웨어를 이용한 동기화 시스템에 대해서 이야기 하였다.

test_and_set()과 compare_and_swap()에 관련된 시스템 콜 기반 Critical Section을 활용한 동기화 Solution에 대해서 말이다.


이번에 배운 것은 하드웨어 동기화 Solution이다.


그 첫번째

Mutex Locks(=Mutual Exclusion Lock)


Mutex Lock에는 두 가지 함수가 존재한다.

Lock을 차지하는 acquire()과 Lock을 놓아주는 release()


두 함수가 어떻게 description되어 있는지를 확인하면


   -> description

이렇게 구성이 되어있다.

코드를 보면 구성이 매우 심플하다 ㅎㅎ


물론 위의 코드는 소프트웨어적으로 처리하는 것이 아닌, 하드웨어적으로 처리하게 된다.

(acquire과 release는 무조건 atomic해야 하기 때문이다.)


하지만 위의 함수에서 가장 큰 Issue가 있는데, 바로 busy_waiting이다.

고가의 cpu를 열심히 돌리는데... 결과론적으로, waiting이라니... 이 얼마나 낭비인가.(spinlock이라고도 불린다.)


이러한 문제에 대한 해결책은 다음장에서 배운다고 하니 일단 넘어가자.


다음으로 배운 것은

semaphore이다.


semaphore의 기원을 한 번 알아보자.


semaphore를 인터넷에 검색하니깐 이러한 그림이 나왔다.

이 그림은 무엇일까...?

바로 빨간색 네모 박스를 의미한다.

저 기찻길 신호등과 기찻길 사이의 공간에는 기차와 차 또는 사람이 같이 들어갈 수 없다. semaphore도 어떠한 자원을 여러명이서 차지할 수 없다는 뜻에서 이름을 이렇게 지었나보다.


각설하고 semaphore를 조금 더 자세히 들여다 보면, Lock과 달리 S라는 variable이 존재한다. 이는 가용 자원수로서 해당 자원을 몇 명의 사람이 사용할 수 있는지를 결정한다.


예를 들어 학교에 학생들을 프로세스, 체육 선생을 semaphore라고 하고, 축구공을 공유자원이라고 하자.

체육 선생이 축구공을 4개 가지고 있다면 S = 4가 되는 것이고, 이는 4개의 process가 각각 사용할 수 있는 것이다.


이 S 변수는 학생이 축구공을 소지하면 개수가 감소하고(S--) 다시 돌려주면 개수가 증가한다(S++)

그리고 전자의 과정을 wait(), 후자를 signal()이라고 한다.

Mutex Lock에서 acquire()과 release()와 동일한 기능을 수행한다.

그리고 어떠한 책에서는 P(), V()라고도 표현하는데 다 같은 의미라고 보면 되겠다.


무튼 wait()와 signal() 함수는 아래와 같은 동작을 수행한다.


S가 0이하라면 semaphore의 공유 자원의 개수가 없는 것이므로 대기한다.

그렇지 않다면 S--를 수행해 가용 자원수를 감소시킨다.

signal()은 자원을 돌려놓는 것이므로 가용 자원수를 증가시킨다.


semaphore의 종류는 크게 2가지 입니다.

* Counting semaphore

- S > 1

* Binary Semaphore

- S == 1

- Binary Semaphore는 Mutex Lock과 동일한 역할을 수행한다고 보면 된다.


기본적으로 Semaphore는 다양한 사용법이 있는데 그 중 하나

1. P1의 S1 다음에 P2의 S2를 수행하고 싶은 경우


위의 코드를 한 번 보자.

synch = 0으로 초기화한다고 가정한다.

wait() 함수의 경우 parameter가 0일 경우 대기하게 되고,

signal()함수는 S1작업이 모두 끝나게 되면  호출되어 synch++을 수행하게 될 것이다.

이렇게 하면 자연스럽게 각 Process 간에서의 동작도 수행 순서를 설정할 수 있게 된다.


하지만 이 semaphore도 문제가 있다. 바로 busy_waiting 문제!!!


busy_waiting을 해결하기 위해서는 Process의 Waiting 상태(=Blocked)를 이용하는 것이다.

이와 관련된 list를 하나 생성하고, wait가 필요하다면 list에 push후 block시킨다. - (1)번

그리고 조건을 만족하면 list에서 process를 pop하고 wakeup 시킨다. - (2)번


        










그렇게 변경된 wait()와 signal() 함수.

semaphore라는 구조체가 하나 생성이 되었고, 해당 구조체는 value(=S), list(=wait_list) 두 개의 인자를 가진다.


wait() 함수가 호출되면 이전처럼 busy_waiting 후 가용 자원수를 감소시키는 것이 아닌, 일단 가용 자원수(value)를 감소시킨 후 해당 자원수가 음수일 경우 대기해야 하므로, list에 해당 process를 push한 후 block()시킨다.


signal() 함수의 경우 가용자원수를 다시 늘리는 작업 뿐만 아니라, list에 process가 들어가 있을 경우(S->value <= 0을 만족하는 경우) list에 있는 process를 제거시켜주고, 해당 process(현재 process가 아님)를 깨운다.


Ex)

A라는 process에서 wait()를 호출하고, B라는 process에서 wait()를 호출하였고, semaphore의 value는 1이라고 가정해보자.


A라는 process에서 wait()를 호출하게 되면, semaphore->value는 0이 되고, critical section에 들어가서 필요한 작업을 수행하게 될 것이다. 그 사이에 B Process에서 wait()를 호출하게 되면 B Process는 block 상태에 들어가게 될 것이다.

그 후 A process의 Critical Section에서 모든 작업이 종료되고, signal()을 수행하게 되면 list에 들어있던 B process를 꺼내 wakeup(=unblock)을 수행하게 될 것이다.

그렇게 B process wait()이후부터 동작을 수행하게 될 것이고 critical section 작업을 수행할 것이며 그 당시 semaphore->value는 0을 유지하고 있을 것이다.



자 이제 이렇게 동기화 작업 사이에서 발생할 수 있는 문제점들에 대해서 한 번 이야기를 해보자.


이야기할 문제는 크게 3가지가 있다.

1. Deadlock

* 두 개 이상의 Process가 서로를 기다림으로써 발생하는 문제. Program이 멈춰버리게 된다.

2. Starvation

* Priority 등에 의해서 어느 하나의 process가 동작하지 못하고 굶어 죽는 현상

3. Priority Inversion

* 이 역시 priority에 의해서 더 낮은 process가 더 높은 process보다 먼저 수행되는 현상.

* 이 현상은 priority-inheritance protocol을 이용하여 해결할 수 있다.


위에서 언급한 문제들을 일반화시켜 설명해보려 한다.


1. Bounded-Buffer Problem


Bounded-Buffer Problem은 Producer-Consumer 사이에서 발생할 수 있는 문제이고, semaphore를 이용하여 해결할 수 있다.

Producer

 Consumer

 

 


여기서는 value가 3종류가 사용되었다.

semaphore empty

semaphore full

semaphore mutex

n개의 buffer가 있다고 가정하였을 때

mutex = 1, full = 0, empty = n으로 초기화를 수행한다.



Producer는 Buffer에 데이터가 꽉 차 있을 경우에는 기다려야 한다.

코드를 보면 가장 먼저 wait(empty)를 수행하게 되는데, wait() 함수는 parameter 값을 일단 감소시키고, 감소된 결과 값이 0 미만일 경우 대기하게 된다. 따라서 empty < 0일 경우는(=Buffer에 빈자리가 없을 경우 = Buffer가 꽉찬 경우) wait를 수행하고, 그렇지 않을 경우는 wait(mutex)를 지나 buffer에 값을 쓰기 시작한다.(=buffer에 값을 넣거나 빼는 행위는 atomic하게 수행되어야 한다.)

writing 과정이 모두 끝나면, signal()을 이용하여 mutex에 대한 lock을 해제해주고, full에 대한 lock 역시 해제한다.

signal() 함수는 가용 자원수를 증가시키는 역할을 수행한다. 즉, full이 0이라는 의미는 현재 Buffer에 사용가능한 데이터가 없다는 의미=사용할 수 있는 데이터가 없다는 것이다.


이러한 맥락에서 Consumer도 쉽게 해석이 되리라 생각된다.



2. Reader- Writers Problem


이번에는 읽는 사람과 쓰는 사람간의 문제이다.

읽는 사람은 누가와서 읽어도 상관없지만, 쓰는 사람은 그 순간에는 최대 1명이 되어야 한다.


이러한 동작을 위해서 3개의 변수가 사용된다.

semaphore rw_mutex = 1

semaphore mutex = 1

int read_count = 0


그리고 Reader-Writers Problem에서는 문제를 해결하기 전에 다양한 가정을 산정지을 수 있다.

(1) writer가 공유 자원에 대한 권한을 가지고 있지 않다면, reader는 waiting할 필요가 없다.


(2) writer가 준비가 되면 바로 writing을 수행해야 한다.


이 두 가지 경우 모두 starvation이 발생할 수 있다.

이번 수업에서는 (1)의 경우에 대해서만 코드를 확인해 보았다.


writer 

 reader

 

 


writer는 간단하다. 읽고 쓰는 사람이 없으면 들어가서 쓰면 된다.

reader의 경우는 살짝 복잡하다.

read_count라는 변수를 증가시키기 위해 mutex semaphore를 이용하여, 다른 process가 실행되지 못하게 하고, count를 증가시킨다. 만약, read count == 1이라면 가장 먼저 공유 자원을 읽으려는 process이므로, 혹여 writer가 있나 없나를 체크 하고 없다면 signal()을 이용해 read_count에 대한 critical section을 종료한다.

이렇게 되면 현재 rw_mutex = 0인 상태이기 때문에 writer는 접근을 할 수 없다. 하지만 다른 reader들은 얼마든지 접근이 가능하다.

read가 다 끝났으면 다시 read_count를 감소시켜주기 위해 wait(mutex)를 실행하고, read count--를 수행한다.

만약 read count가 0이라면, 읽는 사람이 없다는 뜻이므로, rw_mutex를 증가시킨다.


이렇게 하면 reader writer problem의 (1)번 경우가 해결된다.



3. Dining Philosophers Problem


해당 그림에서 5명의 사람(Process)가 있고, 5개의 젓가락(Shared resource)가 있다. 그리고 하나의 프로세스는 자신의 양 옆에 있는 두 개의 젓가락을 사용할 수 있다.


여기서 발생할 수 있는 문제는 바로 DeadLock이다.


이러한 코드가 있다고 가정해보자.

각각 따로 실행이 잘 된다면 문제가 없을 것이다. 하지만 5개의 process가 동시에 젓가락을 탐한다고 해보자.
만약 모두가 왼쪽 젓가락을 원했다. 그래서 왼쪽 젓가락을 사용할 수 있는 것을 확인하고, 오른쪽 젓가락을 확인해보니 모든 젓가락이 사용중인 것이다. 이렇게 되면 각 Process가 서로서로를 기다리게 되고, 결과적으로 시스템이 멈춰버리는 DeadLock 문제가 발생하게 된다.

오늘 배운 것은 바로 여기까지~






















이번 수업에서는 Machine-Independent Loader Features. 즉, 기계에 독립적인 Loader의 특징에 대해서 공부해보려 한다.


Automatic library search

자동적으로 외부의 reference를 관리하는 방식.

이러한 linking과 loading의 옵션

: 대체할 소스를 입력시킬 수 있다 - INCLUDE

: 외부 참조를 변경하거나, 제거할 수 있다 - DELETE, CHANGE

: 외부 참조의 자동 처리를 조절할 수 있다...?


목표

loaded된 프로그램에 subprogram의 routines들을 자동적으로 통합시키는 것


<실행 순서>

Linkage Loader

* 참조되었지만 정의되지 않은 외부 심볼들을 계속적으로 추적해야 한다. [ESTAB(=External Symbol TABle)을 이용하여]

* Pass 1 마지막에 undefined된 심볼이 존재한다면 "unresolved"라고 명명한다.

* Loader는 unresolved된 심볼에 대해서 library들을 검사한다.

  -> 기존에는 단순히 에러를 리턴하였다.

* 모든 unresolved 심볼의 정의를 찾을 때까지 라이브러리를 계속 search한다.


Automatic Library Search에 대한 추가적인 discussion

* linking loader는 override가 가능하다.

* linking loader가 모든 object program의 Define record를 탐색하는 과정에서 Directory(=계층적으로 자료를 저장) 하면 더욱 효율적으로 탐색을 수행할 수 있다. -> data


Loder Option

* User가 직접 지시하여 기존의 processing을 수정할 수 있는 것.

INCLUDE : 라이브러리를 포함시키는 것

DELETE : 심볼을 삭제시키는 것

CHANGE : 심볼을 바꾸는 것

LIBRARY MYLIB : 사용자가 만든 라이브러리를 먼저 탐색하는 것(General함)

NOCALL : 심볼을 unresolved 상태로 남겨놓는 것



Loader Design Option


Linking Loader와 Linkage Editor

Linking Loader

 Linkage editor

* 모든 linking과 relocation을 수행한다.

* automatic library search를 포함하고,

프로그램의 실행을 위해 메모리에 link된 프로그램을 load한다.


* 거의 모든 Program 과정에서 reassembled되는 것

= 계속 바뀌는 것. (인풋 아웃풋을 이야기하는 것이 아님)

ex) 프로그램 개발 과정, 테스트 환경 같은 것들은 개발을 수행하면서 프로그램의 알고리즘이 계속 바뀌게 되므로 계속 reassemble을 수행해줘야 함.

 * 나중에 실행하기 위해 프로그램의 link된 버전을 생산한다.


* reassemble할 필요 없이 많이 실행 되는 것.

 = standard library. 이는 우리가 계속 바꾸지 않음.

  


Linkage Editor는 Dynamic Linking을 수행하기 위해서 사용됨.


Dynamic Linking이란?

* Runtime 과정에서 Dynamic Loader에 의해 필요한 부분이 Memory에 적재되는 것.

ex) Exception Handler




잡담


탐색기의 불편한 점... 다운로드의 불편한 점... XML... URI.... Rule Engine....


윈도우의 탐색기는 과거나 지금이나 변한 것이 하나도 없다.

현재 윈도우의 탐색기는 탐색을 전적으로 User가 책임져야 한다.

탐색기는 단순히 탐색을 수행할 수 있게 도와주는 것이 아니라 각 파일 간의 relation을 형성하여, 하나의 파일을 실행시켰을 때 해당 파일과 연관된 다양한 파일 또는 URL들을 띄워줌으로써 과거에 수행했던 작업을 계속적으로 수행할 수 있게 도와주면 정말 좋을듯 하다. -> 특허 등록 상태 ㅎㅎ


다운로드는 어디서 다운로드를 받았는지 URL을 tag 형태로 저장해놓으면 정말 좋을 거 같은데 그러한 기능이 없음.


AI는 relation을 만드는 학문. 이러한 relation은 Rule engine을 이용하여 만들 수 있음. 아주 강력한 도구.

Rule-engine은 사람이 concurrent하게 일할 수 있게 해줌.





컴퓨터 관련 분야에서 가장 중요한 것은 영어다.


격언 : 컴퓨터를 잘하는 사람에게 영어를 가르치는 것보다 영어를 잘하는 사람한테 컴퓨터를 가르치는 것이 더 낫다.

자신의 의견을 어필하기 위한 수단이 영어다.


영어 공부 열씨미 하즈아아


각설하고, Synchronization에 대해서 오늘은 공부하였다.


동기화 문제가 발생하는 이유는 바로 일관성(consistency)가 깨지기 때문이다. 만약 하나의 코어에서 하나의 process만 동작한다면 동기화가 필요 없겠지만, 다양한 process가 다양한 코어에서 사용되다 보니 일관성이 깨져 동기화 문제가 발생하게 되는 것...


이러한 문제를 해결하기 위한 방법으로 소프트웨어적인 방법과 하드웨어적인 방법 크게 두 가지가 존재한다.





아, 문제 해결 방법을 정리하기 전에 동기화 문제에 대해서 예시를 한 번 들어보자.


자, 예전에 공부했던 Producer-Consumer Problem에서 우리는 circular queue를 구현하여, 버퍼를 만들어 사용하였다. 이 때 empty와 full을 구분하기 위해 귀중한 buffer 하나를 사용하지 않으면서 말이다.


그런데 한가지 궁금증이 생긴다. 그냥 counter라는 공유 변수를 놓고 버퍼가 차면 하나 증가시키고, 버퍼가 빠지면 하나 감소시키면서 관리하면 되지 않는가?


여기서, 동기화 문제가 발생한다. HLL(=High Level Language)에서 한 줄은 실제 여러줄로 동작될 수 있다.


예를 들어, counter++ 이라는 명령어를 실제로 instruction set 단계로 내려가면

register1 = counter (LOAD)

register1 = register1 + 1 (ALU)

counter = register1 (STORE)

3가지 단계를 거치게 된다.


그런데 이 때 Race Condition이라는 문제가 발생하게 된다.


Race Condition이란?

한국 말로 "경쟁 상태"로서 둘 이상의 입력 또는 조작의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태를 말한다.

- 위키

즉, 실행 순서에 따라서 결과가 다르게 나올 수 있다는 것이다. 말이 되는가? counter++을 했는데 결과가 2개 이상이 나올 수 있는 경우가 있다는 것이?????!!!!!!


결론은 가능하다!


자 예를 한 번 들어보자.


2개의 Process가 존재하고, 각 Process에서 counter++, counter--를 수행해보자.

각 명령은 3개의 instruction set으로 존재하고, 하나의 instruction이 atomic한 경우를 만족한다고 가정하면, context-switching은 instruction과 instruction 사이에서 발생할 수 있을 것이다.


만약 counter++, counter--를 수행하게 되면 초기값이 5였을 때 최종 결과는 항상 5가 되어야 하는데...

register1 = counter

register1 = register+1

------------------------------> context-switching 발생

register2 = counter

register2 = register -1

------------------------------> context-switching 발생

counter = register1

------------------------------> context-switching 발생

counter = register2

위의 과정을 거치면 counter 값은 4가 된다.

위와 같은 경우로 인해 우리는 circular queue에 두 개의 variable을 두고 Producer와 Consumer가 건드릴 수 있는 variable을 각각 설정한 것이다.(이는 공유 자원이 아니다!)



어떠한 이유로 동기화 문제가 발생하는 것을 알았으니, 어떻게 하면 이러한 문제가 발생하지 않을까?


"하나의 Process가 공유 자원을 사용하면 다른 Process는 공유 자원에 접근할 수 없다"

로 해결할 수 있을 것 같다.



좀 더 자세하게 들어가보자.


운영체제에서는 Cirtical Section Problem이라는 것이 있다.


Critical Section(<->remainder section)이란 상호 베타적인 접근을 보장해주는 영역으로서 각 Process마다 Critical Section을 가지고 있고, 어떠한 Process가 Critical Section에서 작업하고 있다면 다른 Process는 Critical Section에서 작업을 할 수 없는 것이다.

Problem은 어떻게 상호 베타적인 접근을 보장해주냐는 것을 의미하고 말이다.


이러한 Critical Section에 들어가기 위한 entry Section 나가기 위한 exit Section이 추가적으로 있고, 이를 그림으로


critical section에 대한 이미지 검색결과


이와 같이 볼 수 있다.


자 이제 해결해야 할 문제는 어떻게 critical Section의 상호베타적 접근을 보장해주기 위한 해결책을 해.............보기 전에

Critical Section Problem에 대한 기준 3가지를 한 번 언급해보려 한다.


1. Mutual Exclusion

-> "상호 배제". 즉, 베타적인 접근을 보장해야 한다는 기준이다. critical section을 사용하는 가장 근본적인 이유라고 하겠다.

2. Progress

->"진행". Critical Section이 무기한 연기될 수 없다. 하나의 Critical Section이 다른 Critical Section에 의해 무기한 연기될 수 없다는 기준이다.

3. Bounded Waiting

-> "한계가 있는 기다림". 어떻게 보면 2와 동일한 말이다. 무기한 연기될 수 없으니깐 기다림에 있어서 제한을 둬야 한다는 기준이다.



이 3가지 기준을 모두 만족해야만 Critical Section Problem을 해결했다고 볼 수 있는 것이다.




그렇다면 구체적으로 들어가서 보자!

먼저 SW Solution을 분석해보자.


Peterson's Solution

위의 솔루션은 제한 조건이 있다.

1. 두 개의 Process에 대한 Solution

2. load, store instruction이 atomic하다. -> 요즘 시스템에는 맞지 않는 말이다.


그리고 2개의 variable을 사용한다.

1. int turn -> Critical Seciton에 누가 들어갈 것인지를 알려주는 변수

2. Boolean flag[2] -> Critical Section에 들어갈 것이라는 의사표시를 하는 변수


프로세스가 2개(Pi, Pj / i = 0, j = 1)가 있다고 했을 때 Peterson's Solution의 알고리즘은 아래와 같다.

entry_section에서 본인의 flag를 true로 바꾸고 turn값을 다른 process로 명명한다.

그리고 while문을 돌며 다른 process의 flag가 true이고, turn == 1일 경우 자신은 대기한다.


여기서 특이한 점은 P0에서 turn = 1을 수행하는 것인데.... 이는 turn에 대한 Consistency가 깨져도 Race Condition이 발생하지 않게 하기 위함이다.


해당 알고리즘은 두 개의 Process가 Critical Section에 접근하지 않으면 되는 것이다.

그렇다면 어떠한 경우에 while문을 빠져 나올 수 있는지를 확인해보자.


P0의 경우

flag[1]==false or turn == 0인 경우이고,

P1의 경우

flag[0] == faluse or turn == 1인 경우이다.


다른 process가 Critical Section에 들어갈 필요가 없다면(flag == FALSE), 내 process는 critical section에 들어가서 작업을 하면 되는 것이고,
flag가 모두 TRUE라면, turn에 의해서 가장 최근에 실행된 process와는 다른 thread가 critical section을 수행하게 된다.


다음으로는 HW Solution을 한 번 확인해보자.


HW Solution의 핵심은 검사와 값 변환을 한 번에 수행하는 것이다. sw라면 수행할 수 없지만 hw이기 때문에 두 개의 행동이 동시에 실행이 가능한 것.


lock이 False였다면? Lock을 가지고 있는 Process가 없다는 의미니깐, 내가 쓸게 하고 lock을 true로 변경해주고, 이전 값을 반환하게 되면, critical section으로 들어가 동작을 수행한다.

lock이 true면 누군가가 사용하고 있다는 의미니깐 계속 while문을 돌며 대기한다.


compare_and swap도 동일한 기능을 수행한다. 단지 compare과정(lock의 값이 내가 예상하는 값이 맞는지 확인)이 추가된 것일 뿐...


하지만 위의 방식처럼만 사용하게 되먼 Bounded Waiting이 보장되지 않는다.


그래서 아래와 같이 사용한다.



waiting[] 배열은 나 critical Section에 들어가고 싶어! 라고 하는 process들이 표시를 해놓는 공간이다.


Entry_Section

즉, a라는 process가 나 critical section 수행할거야! 라고 하면 waiting[a]를 true로 만들어주고, key값도 true로 만들어주고 기다린다.

key가 true이므로 while은 무조건 한 번 이상은 수행이 될 것이고,

test_and_set()에서 lock이 true라면(lock을 사용하고 있는 process가 있다면) key값은 계속 true를 유지할 것이고,

test_and_set()에서 lock이 false가 된다면 key 값은 false가 되어 critical section을 수행할 것이다.


End_Section

waiting배열을 circular하게 돌아가게 설정을 해놓는다. 즉, j는 i의 바로 옆 배열이라는 소리.

이 때 옆 배열이 나 자신이 아니고, waiting[j] = FALSE일 때는 j를 하나 더 증가시켜준다.(=다음 process는 critical section에 들어가지 않을거야 라는 의미)


그렇게 비교를 하다가 critical section에 들어갈 거야하는 process가 나올 경우 lock은 true를 유지한 채 waiting값만 false로 만들어 critical section으로 들어가게 한다.


만약 한바퀴를 돌아도 waiting이 true인 곳이 없다면 lock을 해제한다.


이게 어떻게 bounded waiting을 만족시키느냐??

index를 변경해가면서 waiting을 검사하므로 priority가 상대적으로 동작하게 된다. 따라서 bounded waiting을 자동적으로 만족하는 것!


















수능도 끝난 지금. 학생부 전형, 논술 전형 등등 다양한 수시 시즌을 보내고 있는 고3을 맞이하여 아주대학교에서도 면접을 보았다고 합니다.


고등학교 생활 3년 동안 C언어는 1도 몰랐었었는데 요즘 친구들은 C, C++, Python까지도 한 번 써보고, 아두이노 kit를 이용하여 간단하나마 뭐라도 만들어 보고 이를 면접에 활용한다는 소리를  듣고 와... 대단하다라는 생각을 하던 찰나 피보나치 정렬을 사용해보고, 피보나치 정렬이 버블 정렬보다 더 좋다는 대답에  교수님이 하신 질문...

"더 좋다의 기준은 무엇인가요???"

이 질문에 어떤 학생은... 빅오 표기법에 대해서 이야기를 했다는 것... ㅋ


진짜 빅오 표기법은 내가 자료구조 및 알고리즘 수업, 그것도 3학년에 되서야 처음 들어본 프로그램의 성능을 나타내는 지표 중 하나인 것을 알았는데 빅오 표기법을 면접 내용으로 꺼낼 수 있는 것 자체만으로도 정말 요즘 고3은 내가 보냈던 고3 생활보다 더 열심히 살아가고 있는구나라는 생각이 들었다.


교수님이 하시는 말씀을 들어보니 "모른다"라는 대답에 대해서는 점수를 깎지 않고, 거짓으로 대답하는 질문에 대해서만 점수를 깎았다고 하시는 것... 이러한 면접의 특성은 내가 회사에 들어갈 때도 동일하게 작용하지 않을까 하는 생각이 든다.



여담은 이쯤 하고

오늘 이렇게 수업 필기를 하는 이유는


교수님의 박사 생활 때 있었던 IBM에서의 인턴 생활을 하기까지, 졸업이 늦춰짐에도 불구하고 데이터 마이닝이라는 분야를 결정하여, 그렇게 돌진하신 일화가 너무 인상깊었기 때문이다.


데이터 마이닝이란?

대규모로 저장된 데이터 안에서 체계적이고 자동적으로 통계적 규칙이나 패턴을 찾아 내는 것이다. 다른 말로는 KDD(데이터베이스 속의 지식 발견, knowledge-discovery in databases)

이라고 위키 피디아에는 정의되어 있다.


유의미한 정보의 발견. 그리고 그 정보의 지식화.


예를 하나 들어보자.

어떠한 통계를 보니 월마트에서 금요일 퇴근 시간에 맥주와 기저귀와의 판매량이 다른 시간대보다 월등히 높다는 결과가 나왔다.

맥주와 기저귀... 이 둘은 전혀 상관관계가 없어 보이는 상품 묶음인데 왜 이러한 결과가 나왔는지 해당 제품들을  구매하는 사람들에게 물어본 결과

"금요일 저녁에 축구 리그전이 있는데 기저귀같이 부피가 큰 제품은 미리 사가지 않으면 축구 경기를 보다가 사가야 하는 경우가 생깁니다. 이를 미연에 방지하기 위해 맥주와 기저귀를 같이 사가는 것이죠"

이를 깨달은 마케팅 부서는 맥주 코너 옆에 기저귀 코너를 놓고 맥주 상품에는 기저귀 할인 쿠폰을, 기저귀에는 맥주 할인 쿠폰을 부착하였더니 매출이 더욱 올랐다는 일화가 있다.


데이터 마이닝은 맥주와 기저귀의 상관관계를 판매량이라는 데이터를 이용하여 정보화 하는 것이라고 보면 되는 것이다.


이러한 데이터 마이닝은 사용 가능한 분야가 정말 무궁무진하다.

알파고와 이세돌의 격전을 예로 한 번 들어보자.

알파고는 학습을 통해 바둑이라는 경기에 대한 패턴을 익힌다.

그리고 대국 진행 과정에서 이전에 놓인 대국의 패턴을 분석하여 미래를 예측하는(predictioin) AI인 것이다.

15수를 앞서 볼 수 있는 것(15개의 패턴이 연결되어 있는 것)과 20수를 앞서 볼 수 있는 것 중 20수를 앞서 볼 수 있는 머신이 더욱 좋은 성능을 가지게 될 것이다.


이를 통해 알 수 있는 것.

데이터 마이닝, 머신 러닝은 결과적으로 데이터의 패턴을 파악하는 것. 해당 패턴의 depth가 낮으면 가까운 미래만 예측 할 수 있을 것이고, 패턴의 depth가 깊으면 더욱 먼 미래까지 예측할 수 있을 것이다.


월마트의 예시도 일정 깊의 패턴을 해석하여 맥주와 기저귀와의 관계를 유의미하게 만든 것 중 하나라고 볼 수 있다.


이러한 prediction은  의료 분야에서도 사용될 수 있다.

"Body Parts on a chip"

우리의 몸은 다양한 기관이 유기적으로 연결되어 있다. 우리의 몸은 외부의 다양한 자극에 좌우되지 않기 위해 호르몬 등을 이용한 항상성 유지에 많은 에너지를 사용한다. 이러한 항상성 유지 메커니즘에 문제가 발생하면 우리의 몸 여기 저기에 문제가 발생하게 된다.

그러나 만약 신체 기관들 사이의 관계를 모두 파악하게 된다면, 우리 신체의 ph가 조금 낮아지게 되면 우리의 몸이 어떠한 변화를 야기하는지 모든 결과를 알 수 있다면? 병을 진단하는데 있어서 확실한 지표가 될 수 있을 것이다.

더 나아가서, 의사가 필요없을지도 모르겠다.

이러한 데이터들의 관계 역시 데이터 마이닝이라는 기법을 통해서 얻을 수 있는 information 중 하나인 것이다.

관계의 깊이가 더욱 깊어질 수록 accuracy가 더 올라가는..ㅎ


데이터 마이닝의 의미는 이쯤하고....

data와 information 그리고, knowledge에 대해서 한 번 이야기를 해보자.


data는 무엇일까? 데이터를 한국 말로 하면 "자료"라고 볼 수 있다. 자료는 있는 그대로 사용할 수 없다. 일련의 "해석" 과정을 거쳐 가치가 있는 것으로 변화시켜야 우리에게 쓸모가 있는 것이다.

음식으로 보면 재료라고 보면 되겠다.


이러한 데이터들을 유의미한 결과로 바꾼 결과가 바로 information(정보)이다. 맛있게 완성된 요리라고 할 수 있겠다.

그리고 이러한 정보를 쌓게 되면 바로 knowledge(지식)이 되는 것이다. 바로 언제든지 사용할 수 있는 레시피가 되는 것이다.


자 아래의 그림을 한 번 보자


데이터가 지식이 되는 과정은 정말 고되다. 변환된 데이터를 패턴화 시켜주는 데이터 마이닝 과정을 거치기 이전에만 3단계를 더 거쳐야 한다.


해당 과정은 아직까지는 노가다 말고는 해결 방법이 없다. 이 방법, 저 방법 다 써봄으로써 불필요한 데이터를 제거하고, 남아있는 데이터를 패턴화 시키기 위해 끊임없는 시행착오를 거쳐야 한다.

어떻게 보면 데이터 마이닝의 어두운 면이랄까....ㅋ



데이터 마이닝에 관해 들은 것은 많지만 직접 해보지는 않았다. 지금은 이전과 다르게 다양한 알고리즘들이 나와 있을 것이고, 하나하나 공부해 가면 정말 무궁무진한 학문임은 틀림없다.


빅데이터, IoT, 4차 산업 혁명. 이러한 산업의 변화가 어떠한 결과를 야기시킬지 정말 궁금하고 기대된다.











무언가를 결정하는 5분, 결정을 수행하는 1시간.


나는 5분을 고통스러워 할 것인가 1시간이 지난 후를 고통스러워할 것인가?


인간은 그 5분을 "인지적 구두쇠"의 원리에 따라 무의식적으로 결정하려는 경향이 있다. 그리고 이러한 원리에 따라 결정한 일은 아주 운이 좋다면 최선의 선택이 될 수도 있지만 대부분의 경우 되돌아 봤을 때 그렇지 못한 경우가 많다.


따라서 중요한 것은 1~2시간을 몰입하기 전에 어떠한 일을 할 것인가 결정하는 것.


하지만 무언가를 결정하는 5분을 캐치해내는 것은 쉬운 일이 아니다.


따라서 우리는 한가지 약속을 한다.

"누군가가 내게 말을 걸어오거나, 전화가 왔을 경우에 의식적으로 결정을 내리자"

- "결정의 순간"은 생산적이지 못하다는 느낌을 받는다. = 우리가 시간을 더욱 민감하게 받아들이고 있다.


->모든 결정의 순간을 음미하고, 결정의 순간을 미리 계획하며, 다음 task를 의식적으로 결정하기 전까지 새로운 일을 하지 말아라.

* 모든 결정의 순간은 소중하고, 그러한 결정의 순간을 붙잡았다면, 오늘 하루 중요한 일이 무엇인지 생각하라.

* 어떤 상황을 시각화하여 생각하는 것은, 신체적으로 직접 그 행동을 수행하는 것과 동일한 효과를 지닌다.

* 한 가지 과업을 완료하면, "자 이제 결정의 순간이야" 라고 외친다.



집행 기능 : "뇌가 다양한 과업을 통제하고 조정하는 능력"

 - 자기 제어, 자기 통제.


이러한 기능들은 유한한 자원이다. 어떤 일을 결정하는데 있어서 그 일이 사소하던 중요하던 우리는 집행 기능을 수행할 수 있는 에너지를 소모하게 된다.


또한 "감정" 역시 집행 기능에 영향을 미친다.


가수 비욘세 : "나는 무대에 설 때마다 '미리' 긴장해요. 긴장이 되지 '않으면' 겁이 나죠"

전타임에서 실수한 쿼터백 : 불안, 초조의 감정을 분노의 감정으로 바꿈 -> 집중력 향상


정신적 피로를 최대한 줄이기 위해 정신 자원을 실질적으로 소모하는 Task가 무엇인지 확인하고, 가장 중요한 업무를 수행하기 전에는 그 Task를 수행하지 말아라.


최상의 능력을 발위할 순간을 선택하고, 그 외의 다른 것들은 과감히 포기하라.(전략적 무능)

Skct에서 요구했던 짧은 시간 내에 전부 풀 수 없는 문제를 제공하고, 문제를 해결하라는 것. 수많은 업무 중에 중요한 것들을 선택하고, 해결하는 것을 보기 위한 것이 아닐까...


정신적 피로를 빠르게 해결할 수 있는 3가지

1. 심호흡

2. 웃음

3. 짧은(10분 내외) 수면


pg 98



+ Recent posts