프로그래밍 언어론 3강 연습문제

[프로그래밍 언어론]/언어론 연습문제

2019. 11. 1. 13:09

 

문제에 대한 풀이는 공부하는 과정에 푼 과정이므로, 실제 답안과 다를수도 있습니다.

[2강 연습문제]

Q1.

binding time이란 무엇인가?

A1.

name과 object(name-to-object 기준)간 연결되는 시점을 의미

 

Q2.

정적 바인딩과 동적바인딩의 차이적을 설명해라.

A2.

정적 바인딩은 실행 시점 이전(컴파일 시점)에서 이뤄지는 바인딩을 의미

동적 바인딩은 실행 시전에서 이뤄지는 바인딩을 의미한다.

+) Early binding과 Late binding r다른거임

 

Q3.

바인딩을 빨리할수록(Early binding) 좋은점과 늦게 할수록(Late binding) 좋은점이 무엇인가?

A3.

Early binding : 효율성(실행이전에 위치값 지정되어있어 실행시점에 그냥 지정위치값으로 가면된다)

Late binding : 유연함, 다형성

 

Q4.

name-to-ojbect의 수명(lifetime)과 가시성(visibility)의 차이점을 서술하라.

A4.

바인딩의 수명은 바인딩의 생성부터 제거를 의미하고,

가시성은 내부 subroutine에서 같은 name으로 선언되는 경우에, 밖에있던 바인딩을 비활성화해서 안보이게 하는 것을 의미한다.(scope)

 

Q5.

객체가 정적, 스택, 힙에 할당되는 기준이 뭔지 설명해라.

A5.

정적할당되는 객체 : 전역변수, static으로 선언된 변수, const 상수

스택에 할당되는 객체 : 지역변수, 재귀함수(LIFO)

힙에 할당되는 객체 : 문자열, 리스트, set과 같은 상태에 따라 크기 달라지는 객체(임의로 할당및 해제가 가능)

 

Q6.

스택 frame에서 찾을수 있는 정보와 객체들을 나열해라.

A6.

- Arguments to called routines : 호출된 subroutine에 들어온 인자값​들

- Temporaries : 복잡한 계산중 나오는 임시 값들

- Local variables : 지역변수

- Miscellaneous bookkeeping : 서브 루틴의 반송 주소, 이 subroutine을 요청자의 스택 프레임에 대한 참조값들

- return address

 

Q7.

frame pointer란 무엇이고, 어디에 사용되는가?

A7.

프레임 포인터는 함수가 리턴했을 때 복귀할 스택메모리의 주소를 가지고 있다.

 

Q8.

호출 시퀀스란 무엇인가?

A8.

호출 시퀀스는 caller에 의해 실행되는 호출 바로 직전(프롤로그)과 호출 이후(에필로그)에 실행되는 코드이다.

 

Q9.

내부단편화와 외부단편화란 무엇인가?

A9.

내부단편화 : 메모리가 일정크기로 할당되어있을때, 메모리가 할당되고 남은 공간이 너무작아 사용이 불가능한 현상

외부단편화 : 메모리가 들어온 순서대로 동적 할당뒤 일부 할당 객체 반환된후 남은 공간이 너무작아 새로운 객체가 들어오지 못하는 현상

 

Q10.

garbage collection이란 무엇인가?

A10.

힙 할당후 일부 반환된 공간(바인딩 해제)을 외부단편화 방지하기 위해 한곳으로 모아 결합해 큰 빈공간으로 만드는 것.

 

Q11.

dangling reference란 무엇인가?

A11.

허상 포인터. 두 요소간 바인딩보다 객체가 먼저 제거되서, 바인딩이 가르키는 위치에 아무 객체도 없는 현상.

 


Q12.

name-to-object 바인딩의 scope가 의미하는 것은?

A12.

해당 name이 선언된 순간부터 해당 scope 종료까지. 이때 scope에 내부 subroutine 존재하고 그 내부에서 중복 name으로 선언시, 해당 subroutine에서 hole 발생한다.

 

Q13.

정적 스코프와 동적 스코프의 차이점을 서술해라.

A13.

정적 스코프는 컴파일 시점에 스코프가 확정되므로, 소스코드만으로 스코프 파악할 수 있다.

동적 스코프는 실행 시점에 스코프가 확정되므로, 실행 흐름 따라가봐야 스코프 파악할 수 있다.

 

Q14.

elaboration이란 무엇인가?

A14.

실행 시점의 세부분류. 변수가 공간 할당되는 순간(변수 초기화, 바인딩 생성)

 

Q15.

referencing environment란 무엇인가?

A15.

프로그램 실행 특정 포인트(동적/정적 스코프에따라 다름)에서 활성화 되어있는 바인딩들의 집합.

 

Q16.

closest nested scope rule에 대해 설명해라.

A16.

특정 scope에서 사용된 name(object)가 해당 scope에서 선언되지 않았을때, 해당 scope(subroutine)의 frame에 저장되어있는 가장 가까운 scope(동적/정적 다름)를 따라 이동하며 찾아보는 규칙(전역변수까지 검색)

 

Q17.

scope resolution operator의 목적은 무엇인가?

A17.

내부 subroutine에서 특정 name 중첩 선언되서 외부 name에 대한 binding이 hidden되었을때, 해당 외부 name에 대한 binding에 접근하기 위해 사용

 

Q18.

static chain이란 무엇이고, 어디에 사용되는가?

A18.

스택상에서 해당 subroutine 호출한 frame(이전 subroutine) 참조하기위해 체인 생성.

 

Q19.

forward references란 무엇이고, 이것이 수많은 언어에서 금지되고 제한되는가?

A19.

name이 선언되기 이전에 사용하려 하는것.

정적 시맨틱 오류 발생 가능

 

Q20.

선언과 정의의 차이에 대해 설명하고, 이 둘의 구분이 중요한지 서술해라.

A20.

선언(declaration) : name을 소개하고 해당 scope에 표시, 자세하고 확실한 실행부분은 생략

정의(definition) : name에 충분한 세부사항을 묘사

대부분이 한 선언에 한 정의 가지고 있다.

프로젝트 규모 커지면 모듈화 필요하고, 선언부분따로, 정의부분따로해서 메모리 낭비 감소

 


Q21.

Information hiding이란?

A21.

보통 캡슐화, 추상화를 통해 이뤄지며 외부에 보여주기 싫은 내부정보를 은닉하는것.

 

Q22.

opaque export란?

A22.

이 유형의 변수 타입은 선언될수 있고, 모듈의 subroutine에 인자값으로 전달될수 있고, 다른 것과 비교 및 할당 할수 있지만 다른 어떤 방법으로 조작되지는 못한다.

 

Q23.

왜 모듈의 header와 body를 구분하는게 좋은가?

A23.

모듈의 header와 body는 서로 다른 파일로 나눌수 있고, 이는 개별적인 컴파일에 도움이 된다.

 

Q24.

닫힌 scope의 의미는 무엇인가?

A24.

모듈에서 import할 name들이 반드시 명시되어야하는 언어의 유형의 유형이다.

ex. import 변수명E, 타입명B 

    exprt ..., ...

 

Q25.

'관리자로서의 모듈'과 '타입으로서의 모듈'을 구별해라.

A25.

- 관리자로서의 모듈

: 여러 스택 허용, 대신 모듈 한개를 이 스택들 관리하기위해서 사용한다.

이 스택 인스턴스들을 생성/초기화/파괴위해 추가 서브루틴 요청되고, 모든 서브루틴(push,pop,create)이 특정 스택 지정위해 추가 매개변수 허용 필요하다. 

: 쉽게 말해 추상화 클래스 느낌

- 타입으로서의 모듈

: 모듈이 타입을 가지면, 프로그래머가 임의의 수의 유사한 객체 선언가능 ( 객체지향도 모듈 타입의 확장된 모습)

+) A.push(x) 가 타입으로서의 모듈 방식 / 관리자 모듈에 push(A,x) 전달 이 관리자 방식이다.

 

 

 

Q26.

클래스와 모듈의 차이점은?

A26.

클래스는 모듈과 달리 상속(정의의 확장)과 다형성(클래스 오버라이드)을 지원한다.

 

Q27.

한 같은 프로그래밍 언어에서 모듈과 클래스 둘다 가지면 유용한점은?

A27.

클래스의 문제점은 일단 export되는 방식이다보니, import되면 숨기고 싶은 클래스라도 외부에서 사용된다.

모듈을 이용하면 export 클래스(패키지)명 식으로 지정해줘야 외부에 공유여부가 결정된다.

 

 

 

Q28.

동적 스코프가 run-time 타입 체크가 필요한이유는?

A28.

동적 스코프는 실행도중 가장 최근에 만나고 아직 return에 의해 없어지지 않은 현재 바인딩을 스코프 기준으로 하기 때문에, 실행 시점까지 referencing Enviroment 오류 발견이 어렵다.

 

Q29.

컴파일러의 symbol table의 목적은?

A29.

정적 스코프에서 name과 이에 대한 binding 추적하기위해 사용된다.

 

Q30.

aliases란?

A30.

두개 이상의 name이 같은 시점에서 한 object 공간을 가르키는 상황

 

Q32.

오버로딩이란? 그리고 coercion과 다형성과의 차이는?

A32.

오버로딩 : 프로그래머가 동일한 name에 여러 object 받을수 있게한다. 그리고 이를 인자값으로 구별한다.

coercion : 자동 형변환

다형성 : 한 함수명으로 여러 타입 원자값 받을수 있게 같은 함수명으로 여러개 구현(해당 타입, 개수 지원시에만 사용 가능)

 

Q34.

referencing Enviroment의 deep binding과 shallow binding의 차이를 서술해라.

A34.

shallow binding은 동적 스코프에서 사용하는 방식으로, 함수가 호출(call)되는 시점의 referencing Enviroment를 사용.

deep binding은 정적 스코프에서 사용하는 방식으로, 함수가 참조(reference)되는 시점의 referencing Enviroment를 사용.

 

Q35.

동적 스코프 방식의 언어에서 바인딩 규칙이 특히 중요한 이유는?

A35.

실행시점에 바인딩되기때문에..? 킹론상. 컴파일 시점에 스코프 오류 발견하면 금방금방 고치는데 이건 실행해봐야 오류있는지 알수잇어서?

 

Q36.

first-class subroutine이란? 그리고 어떤 언어가 이를 지원하는가?

A36.

first-class subroutine 은 해당 subroutine이 

1. parameter 형태로 subroutine 전달 가능

2. subroutine return 가능

3. 변수에 subroutine 할당 가능

할때 이라고 할수 있다.

이는 함수형언어와 대부분의 스크립팅 언어에서 지원하고, 일부 제한(함수대신 함수의 포인터)을 건 명령형 언어들이 지원한다.

 

Q37.

Subroutine closure란 무엇이고, 어디에 사용되는가?

A37.

subroutine closure는 context 형태로 전달 가능한 함수(first-class)를 의미한다.

클래스를 필드로 취급하고 subroutine의 referencing Enviroment에 대한 정보 유지에 사용한다.

 

Q38.

Object closure란 무엇인가?

A38.

object는 여러개의 bound된 subroutine들에 대한 data 가지고 있다.

여러 subroutine 가지고 있는 클래스(생성자)를 전달해 사용하게끔 (new 클래스명();)

 

Q39.

C#의 delegate가 어떻게 사용되는지 보여라

A39.

예시)

void func(int y) {

  return delegate(int i) {return i+y;}

}

int h = func(2);

int res = h(3);

 

Q40.

지역 scope에 있는 객체가 limited extent, unlimited extent일때에 대해 서술해라.

A40.

limited extent는 해당 지역 scope를 벗어나면 제거된다. - 스택에 저장

unlimited extent는 해당 지역 scope 벗어나도 무한히(가비지 수집 이전) 그 바인딩 유지한다. - 힙에 저장

 


 

Q41.

 

lambda expression이란 무엇인가? 함수형 언어에선 C#이나 Ruby와 비교해서 어떻게 lambda expression을 지원하는가?

람다 표현식이란 이름없는 함수를 의미하고, 함수를 값처럼 사용할 수 있게 해준다.

- C#에서의 람다 표현식 예시 : (int i, int j) => i > j ? i : j

- Ruby에서의 람다 표현식 예시 : -> (i, j){ i > j ? i : j}

 

Q42. (자작)

매크로 확장이란 무엇인가? 그리고 매크로 확장이 오늘날의 언어에서 보이지 않는 대표적인 이유와 그 예시를 보여라.

매크로 확장은 어셈블리 언어에서 반복되는 코드를 위해서 제공되기 시작한 기능이다.

초기 C언에서 또한 #define DIVIDE(a, b)(!(a)%(b))와 같은 매크로 전처리를 제공했지만,

매크로 확장의 대표적인 문제점인 계산순서 문제 외의 여러가지 문제가 있어 오늘날의 대부분의 언어에서는 매크로 확장을 사용하는것을 금지하고 있다.

DIVIDE(y+z, x) -> (!(x % y + z))   //계산순서 문제 예시