문제에 대한 풀이는 공부하는 과정에 푼 과정이므로, 실제 답안과 다를수도 있습니다. |
Q1.
control-flow 매커니즘의 8가지 주요 카테고리를 말해라.
1. 시퀀싱(sequencing) 2. Selection(선택) 3. Iteration(반복) 4. Procedural abstraction(절차적 추상화) 5. Recursion(재귀) 6. Concurrency(동시) 7. Exception handling and speculation(예외처리와 견해) 8. Nondeterminacy(불확정성) |
Q2.
operator(연산자)와 일반적인 함수집합들을 구분하는 기준이 무엇인가?
대부분의 명령형 언어에서, 일반적인 함수는 Constructor이다. 괄호와 콤마로 구성된 인자들 목록으로 구성된 함수명의 형태로 구성되어 있다.
그리고 연산자는 연산을 하기위한 수단으로 보다 간단한 형태로 구현된다. (+, -, += 등) 일반적으로 한개 or 두개의 인수만을 취해 괄호와 콤마로 이들을 관리한다. |
Q3.
prefix(전위), infix(중위) 그리고, postfix(후위) 표기법의 차이점에 대해 설명해라. 그리고 Cambridge Polish란 무엇인가? 그리고 후위 표기법을 사용하는 프로그래밍 언어 두개를 말해라.
- prefix : 피연산자 앞에 연산자 위치 ( + 2 3 ) ( ++i ) - infix : 피연산자들 사이에 연산자 위치 ( 2 + 3 ) - postfix : 피연산자 뒤에 연산자 위치 ( 2 3 +) ( i++ )
- Cambridge Polish : 전위 표기법의 일종이며, 함수의 이름을 괄호 안에 넣는 개념이다. ex) ( * ( + 1 3 ) 2 ) / (append a b c my_list)
- 후위 표기법을 사용하는 프로그래밍 언어 : Postscript, Forth |
Q4.
왜 Postscript나 Forth에선 결합이나 절차에 대한 문제들이 발생하지 않는가?
언급된 두 언어는 후위 표기법을 사용 하는 언어이므로, 결합이나 절차적 문제가 발생하지 않는다. 중위 표기법일때나 주로 발생하는 문제들이기 때문에 ex) 1 + 2 + 3 어느 순서대로 계산? + + 1 2 3 과 같은건 순서 문제x
|
Q5.
표현식이 referentialy transparent(참조 투명성) 된다는게 무슨 뜻인가?
표현식이 프로그램의 동작을 변경하지 않고, 해당 표현식과 일치하는 값으로 대체할수 있는 경우를 의미한다. (순수한 함수형 언어에서 표현식은 참조 투영성이라 불리운다) (표현식이 특정 시점에 명확한 값으로 지정되면, 해당 시점부터 동일한 값을 가지고 있다 보장된다) |
Q6.
value model의 변수와 reference model의 변수의 차이점은 무엇이고, 이 차이점이 중요한 이유는 무엇인가?
두 모델은 변수가 값을 지정하는 방식이 다르다. 우선 value model의 변수는 변수마다 공간이 있어 해당 공간에 값을 저장하는 방식이다. 반대로 reference model의 변수는 말그대로 기존의 값이 있는 위치를 참조(가리키는, 포인팅) 방식이다. 그리고 이러한 차이는 프로그램이 실행되며 명확히 갈리게 된다. (예를 들어 변수 a, b = 2, 2일때, value model은 각각의 공간에 2라는 숫자를 저장해 놓는 방식이지만, reference model은 2라는 숫자가 저장된 공간에 각 변수가 화살표를 보내놓은(중복) 방식이다. ) |
Q7.
l-value와 r-value란 무엇인가?
1) l-value : 할당의 왼쪽에 위치해 있으며, 바뀐 위치를 가르킨다. 주로 변수의 일부분. 2) r-value : 할당의 오른쪽에 위치해 있으며, 새로운 값을 공급해준다. 주로 값이나 표현식. |
Q8.
변수에 대해 reference model을 사용하는 언어의 실행에 있어 mutable 변수와 immutable 변수를 구별하는것이 왜 중요한가?
mutable 변수들은 변경될수 있는 값을 여러 변수가 참조할 수 있고, 이 것은 문제를 일으킬수 있기 때문이다. ex) a = e, b = e, e += 1 과 같은 문제 발생 가능 |
Q9.
프로그래밍 언어 디자인에서 문맥의 orthogonality를 정의해라.
orthogonality는 한국어로 직교성이라는 뜻으로, 해당 문맥이 어떻게 조합이 되어도 사용될 수 있으며, 이런 모든 조합들은 말이 되고, 해당 문맥에 주어진 뜻이 다른 것들과 상관 없이 지속성을 가지는 것을 의미한다. |
Q10.
statement와 expression의 차이점은 무엇인가? 그리고 언어가 expression-oriented라는 것이 무슨 의미인가?
statement은 보통 연산식을 의미한다. (오로지 side effect를 위해 실행된다) ex) a = b + 2; expression은 표현식이고 보통 계산을 의미한다. (값을 제공하는 역할) ex) b + 2; 그리고 일반적으로 expression의 개념은 statement에 포함된다.
expression-oriented되는 언어는 statement에 대한 개념이 없는 언어들이다. 즉, 변수에 값을 저장해 다른데서 사용하는 방식이 아닌 언어들. |
Q11.
assignment operator를 사용해 변수를 update하는 것이, 양쪽(왼쪽, 오른쪽)에 변수나 나타나는 일반적인 assigment보다 좋은지 설명해라.
assignment operator가 한번에(at once)에 주소 계산을 하는것을 보장해주기 때문에 깔끔하다.
A[i] = A[i] + 1 와 같은 기존 방식에서 왼쪽의 i 와 오른쪽의 i는 각각의 처리 시점에서 읽기때문에, 두 i가 동일하다는 것을 보장하지 않는다. 하지만 A[i]+=1 와 같이 assignment operator를 사용해 작성하면, 연산에 사용되는 i를 한번만 읽어 처리하기 때문에 i값이 보장된다. |
Q12.
값을 변수에 할당할 수 있을때, 초기값을 명시하는 것이 유용한 이유는 무엇인가?
정적(static) 변수들은 선언시점에 초기화 해주면, 실행시점에 할당되어 실행시간이 오래 걸리는 것을 피해 컴파일 시점에 메모리에 선할당(preallocate)될 수 있다. 또한 초기화되지 않은 변수들로 인한 오류 발생 회피. |
Q13.
aggregates(집약)란 무엇이고, 이것이 유용한 이유는 무엇인가?
'struct'와 같은 '사용자가 정의한 합성 타입'에 대한 컴파일 시점 초기화를 의미한다. 동시에 해당 객체의 모든 부분을 초기화 할 수 있다. ex) struct {int x, y, z;} => nums = { 1, 2, 3 } |
Q14.
JAVA와 C#에서의 definite assignment의 개념에 대해 설명해라.
확실한 초기값 할당. 프로그램의 모든 가능한 flow(흐름)에 대해 변수가 초기화 되어 있지 않으면, 해당 변수를 사용할 수 없는 개념이다. 6.1.3(3) |
Q15.
왜 실행시점에 모든 초기화 되지 않은 변수를 잡아내는 것이 비싼가?
변수의 초기화 여부에 대한 flag를 저장해둘 추가적인 공간이 할당되어야 하고, 이런 flag들은 변수들이 사용될때마다 확인되어야 해서 시간적 비용이 매우 비싸기 때문이다. |
Q16.
왜 컴파일 시점에 모든 초기화 되지 않은 변수를 잡아내는 것이 불가능한가?
정적 할당되지 않고, 스택이나 힙에 저장되는 변수들은 실행시점에 초기화(메모리에 저장)된다. 6.1.3(2) |
Q17.
왜 대부분의 언어에서 연산자 또는 함수의 인자값들이 평가되는 순서를 지정하지 않은 채로 두었는가?
대표적으로 두가지 이유 때문이고, 이는 side effect와 code improvement 이다. 간단하게 이야기 하면 연산자내 인자값들이 side effect 가지고 있을때, 이 인자들의 계산 순서에 따라 결과값이 달라질수 있고, code imporvment측면에선, 계산하는데 빠르게 계산할수 있는 것부터 계산하는등의 이유이다. 6.1.4 |
Q18.
short-circuit Boolean evaluation이란 무엇이고, 왜 유용한가?
단락 논리 평가. 논리 연산자 (ex. A && B ..) 에서 앞 연산자의 결과에 따라 뒤 연산자 계산 여부 결정 방식이다. 만약 앞의 결과로 인해 뒤의 결과를 계산하지 않아도 결과를 알수 있는 경우엔, 해당 전체 논리 연산자 계산 속도를 향상할 수 있다. |
Q19.
goto의 주요 용도와 각 용도들에 대한 구조화된 대안들을 나열해라.
goto문은 조건문과 무조건적인 jump를 이용해 분기문의 역할을 수행하는데 사용되었다. - Return 문 : 기존 현 subroutine의 끝으로 가기위한 jump하기위해 goto 사용의 대안 - Break/exit 문, Continue문 : 반복문 수행중 중간에서 탈출하기 위해 goto문 사용의 대안 - Exception Handling (예외처리) : 예외 발생시 예외문이 있는 곳으로 jump하기위해 goto문 사용의 대안
|
Q20.
예외(Exception)와 다층 리턴(Multilevel Return)의 차이점을 설명해라.
우선 둘다 문맥의 내부에서 외부 문맥으로 이동하는 조작이다. 하지만 우선, 다중 리턴에서는 내부의 문맥의 수행이 완료된 후에, 이후의 과정이 필요없을때 외부문맥으로 이동한다. 반면에, 예외는 내부의 문맥이 다 수행되지 못하고, 외부 문맥이 반드시 수행되야 할때 주로 사용된다. |
Q21.
continuations란 무엇인가? 그들이 사용하는 다른 언어 특징들은 무엇인가?
goto문중 현 context에 해당되는 stack을 해제하는 nonlocal goto의 일반화된 형태를 말한다. (생략) |
Q22.
Lisp에서 시퀀싱이 조작흐름을 형성하는데 상대적으로 중요하지 않은 이유가 무엇인가?
시퀀싱은 각 다른 statement들을 모아 일련의 하나의 덩어리로 만드는 것을 의미한다. 또한 이런 시퀀싱은 side effect들의 발생 순서를 통제하는 등의 주요 역할들을 하는데, Lisp는 함수형 언어이고, 함수형 언어들에선 보통 함수가 side effect를 가지지 못한다. 그래서 시퀀싱의 중요도가 떨어진다. |
Q23.
함수가 side effect를 가질수 있게하는것이 유용한 이유를 말해라.
일반적으로 함수는 다른 값을 return 한다. 그런데 만약 side-effect가 없다면 때에 따라 다른 값을 return 해야하는데 이것이 거의 불가능하다. |
Q24.
단락 부울 평가(Short-circuit boolean evaluation)의 점프 코드 구현에 대해 설명 해라.
선택문에서 단락 평가 방식을 아래와 같이 적용한다. 레지스터에서 선택 표현식인 beq나 bne를 평가하고 저장할 값을 계산하지 않고, 다양한 위치로 분기되도록 한다. |
Q25.
왜 명령형 언어에서 if..then...else문에다 추가록 case or switch문을 제공하는가?
효율적인 코드 작성을 위해서. 예를들어 분기 가능성이 100개가 있으면 if문 만으로 이것을 작성하려면 100개의 if문을 작성해야하는데 case와 switch문을 사용하면 보다 간편한 방식으로 이를 구현할 수 있다. |
Q26.
case statement 구현에 사용될 수 있는 세 가지 서로 다른 검색 전략과 각각이 이상적인 상황에 대해 설명해라.
1) 순차적(Sequential) : 각 case를 순서대로 테스트하는 방법. O(n), 낮은 label 카운트에 적합 2) 해싱(Hashing) : 각 label의 해시 함수를 이용해 해싱하는 방법. O(1), 많은 공간 필요해 큰 범위는 곤란 3) 이진 검색(Binary Search) : 이진 검색 방법으로 case 검색. O(logn). 큰 범위 처리에 적합 |
Q27.
C에서의 switch statement를 종료하기 위한 break문 사용과 break문을 실수로 생략했을때 발생하는 문제에 대해 설명해라.
우선 각 switch case문을 실행한후 break문을 개별적으로 작성해줘야, 해당되는 case문의 코드들만 실행하고 빠져 나갈 것이다. 하지만 이러한 break문을 생략하게 된다면, 계속해서 해당되는 case문을 찾게될것이고, 이는 break문을 찾을때까지 지속된다. |
: Q28~34 부분 재 확인
Q28.**
Enumeration-controlled Loops의 실행의 3가지 세부요소들(subtleties)에 대해 설명해라
1. 순차 테스트(sequential testing), 2. 해싱(hashing), 3. 이진 트리(binary search) if..then..else문으로써의 순차 테스트는 case 상태 label들이 적을때 사용할수 있는 방법이다. 해시 테이블은 label 값이 매우 크지만, 사용하지 않는 공간이 많을때 사용하는 방법이다. 이진 트리는 범위를 쉽게 수용할 수 있고, 평균적으로 O(logn) 시간에 수행된다. |
Q29.
왜 대부분의 언어가 Enumeration-controlled Loops의 한계 또는 소수점 숫자로 증가함을 허용하지 않는가?
소수점 값을 증가값으로 사용하면, 반복되는데 사용되는 변수의 정확한 값에 부정확성이 있을 수 있다. |
Q30.
왜 대부분의 언어에서 Enumeration-controlled Loops가 컴파일 시점에 상수(constant)가 되기위해 step size가 필요한가?
그래야 컴파일 시점에 반복을 수행할 케이스를 생성할 수 있다. (Enumeration-controlled Loops의 특징) |
Q31.**
"반복 횟수" 루프 실행에 대해 설명해라. 이는 어떤 문제점을 해결하는가?
루프 전에 반복 횟수를 센다. 그리고 이는 루프에서 step의 흔적을 테스트할 필요가 없다. |
Q32.
루프에서 사용되는 index 값을 해당 루프문 내에 지역으로 선언하면 어떤 장점이 있는가?
루프의 case에 대한 index 값이 외부로 보여지지 않게되어, 따로 관리해주지 않아도 된다. |
Q33.
C언어는 Enumeration-controlled 방식의 loop를 가지고 있는가?
없다. C에서의 for loop은 명시적인 실행. |
Q34.
collection(a container instance) 이란 무엇인가?
well-defined set. 객체 지향적 프로그래밍 기준으로 배열이나 그와 유사한 자료구조의 내부요소를 순회하는 객체를 의미한다. |
Q35.
진정한 반복자(true iterator)와 반복자 객체(iterator objects)의 차이점에 대해 설명해라.
진정한 반복자는 호출되면, 해당 반복문의 yield statement(실행해야하는 case들)를 실행해 loop의 첫번째 index 값을 계산한다. 이후, yield에 더이상 요소 없드면 반복자는 루프문 종료. = index 값들에 대한 yield들에 대한 반복 방법(ex. for i in range(a,b,c))
그리고, 반복자 객체는 진정한 반복자를 흉내내는 방법이다. 하지만 yield statement없이, 호출되었을때 반복자의 상태가 객체의 데이터 멤버들 안에 유지되어야한다. = 반복을 할수있는 방법을 가지고 있는 클래스들 (ex. for(Interger i : myTree)) |
Q36.
C와 같은 언어에서 반복자 객체를 사용해서 얻을 수 있는 두가지 장점을 말해라.
1. 가독성이 좋다. 2. 타입과 함수를 묶어서 관리 할수있다. |
Q37.
first-class function의 언어에서 일반적으로 사용되는 반복에 대한 접근 방식에 대해 설명해라.
재귀 기반으로 index를 인자로 가지고 있는 함수를 루프문의 내부내용을 작성한다. |
Q38.
pretest-loop나 post-test loop보다 mid-test loop의 결과가 더 우아한 예시를 들어라.
while (True){ line = read_line(stdin); if (all_blanks(line)) break; // 출력전에 mid-test consume_line(line); } |
Q39.
꼬리 재귀(tail-recursive)란 무엇인가? 그리고 이것이 중요한 이유는 무엇인가?
꼬리 재귀는 일반적인 재귀 방식에선 함수가 호출된 위치를 기억하고 스택에 저장해야되 비효율적인 반면 추가 연산이 재귀적 호출을 따라가지 않는 재귀방식을 의미한다. |
Q40.
applicative-order 와 normal-order 표현식 평가방법의 차이점을 설명해라. 각자 어떤 순환방식을 지향하는가?
Q41.
lazy evaluation이란 무엇인가? promises란 무엇인가? memoization이란 무엇인가?
Q42.
lazy evaluation가 지향되는 두가지 이유를 설명해라.
Q43.
파라미터가 항상 lazily 하게 평가되는 언어를 말해라.
Q44.
조작흐름이 불확정성을 종종 가져야 하는 두가지 이유를 들어라.
'[프로그래밍 언어론] > 언어론 연습문제' 카테고리의 다른 글
프로그래밍 언어론 7강 연습문제 (0) | 2019.12.15 |
---|---|
프로그래밍 언어론 3강 연습문제 (0) | 2019.11.01 |
프로그래밍 언어론 1강 정리 및 연습문제 (2) | 2019.10.14 |