언어 특성
1. Python과 다른 언어의 차이점에 대해 이야기해 보세요.
언어 특징: 간결하고 우아하며, 중괄호, 세미콜론, 일부 키워드, 타입 선언을 생략합니다.
언어 유형: 인터프리터 언어로, 한 줄씩 해석하고 실행하므로 디버깅이 편리하고 개발 효율성이 높습니다.
서드파티 라이브러리: Python은 오픈 소스이며 자유롭게 발전하도록 설계되었습니다. 웹, 시스템 관리, 자동화 테스트, 웹 크롤링, 데이터 분석, 인공지능 등 다양한 분야에서 활용됩니다. Python은 매우 포괄적인 서드파티 라이브러리를 보유하고 있습니다.
Python과 Java 비교:
Python은 Java보다 간단합니다. Python은 함수가 일급 시민인 반면, Java는 클래스가 일급 시민입니다. Python은 동적 타이핑 언어이고, Java는 정적 타이핑 언어입니다.
Python과 C 비교:
사용성: Python은 라이브러리가 풍부하고 사용이 간결하여 적은 코드로 복잡한 기능을 구현할 수 있는 반면, C로는 더 복잡할 수 있습니다.
속도: Python의 실행 속도는 C에 비해 현저히 느립니다. Python과 CPython 인터프리터는 모두 C 언어로 작성되었습니다.
2. 인터프리터 언어와 컴파일 언어에 대해 간략히 설명해 보세요.
컴파일 언어와 인터프리터 언어:
인터프리터 언어: 실행하면서 코드를 해석합니다.
컴파일 언어: 코드를 먼저 컴파일한 후 실행합니다.
3. Python 인터프리터의 종류와 각각의 특징은 무엇인가요?
CPython:
C 언어로 개발되었으며 가장 널리 사용되는 인터프리터입니다.
IPython:
CPython을 기반으로 하는 대화형 인터프리터로, 상호작용 방식이 향상되었으며 기능은 CPython과 동일합니다.
PyPy:
실행 효율성을 목표로 하며, JIT(Just-In-Time) 기술을 사용하여 Python 코드를 동적으로 컴파일하여 실행 효율성을 높입니다.
Jython:
Java 위에서 실행되는 인터프리터로, Python 코드를 Java 바이트코드로 직접 컴파일하여 실행합니다.
IronPython:
Microsoft .NET 플랫폼 위에서 실행되는 인터프리터로, Python 코드를 .NET 바이트코드로 컴파일합니다.
4. Python 3와 Python 2의 차이점에 대해 아는 대로 설명해 보세요.
Python 2.7과 Python 3.6을 기준으로 Python 3와 Python 2의 주요 차이점과 일반적인 예시를 제시합니다:
1. 문자 인코딩 지원 통합: 기본 인코딩이 UTF-8로 변경되어 유니코드 처리가 용이해졌습니다.
2. 새로운 문법 추가: print, exec 등이 함수로 변경되었고, 문자열 포맷팅, 타입 힌트, nonlocal, yield from, async/await, yield for 키워드 및 __annotations__, __context__, __traceback__, __qualname__ 등의 dunder 메서드가 추가되었습니다.
3. 일부 문법 변경: metaclass, raise, map, filter 및 dict의 items/keys/values 메서드가 리스트 대신 이터레이터를 반환하도록 변경되었으며, 디스크립터 프로토콜, 클래스 속성 정의 순서 유지, 키워드 인자 순서 유지가 가능해졌습니다.
4. 일부 문법 제거: cmp, <> (!=), xrange (range로 통합), 클래식 클래스가 제거되었습니다.
5. 새로운 모듈 추가: concurrent.futures, venv, unittest.mock, asyncio, selectors, typing 등이 추가되었습니다.
6. 일부 모듈 변경: 주로 함수/클래스/메서드(예: functools.lru_cache, threading.Barrier) 또는 인자가 추가되었습니다.
7. 모듈 이름 변경: 관련 모듈들이 하나의 패키지로 통합되었습니다 (예: httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib가 http로 통합, urllib, urllib2, urlparse, robotparse가 urllib로 통합). SocketServer는 socketserver로, Queue는 queue로 변경되었습니다.
8. 일부 모듈 또는 함수 제거: gopherlib, md5, contextlib.nested, inspect.getmoduleinfo 등이 제거되었습니다. 제거 이유는 주로 오래되었거나 대체재가 등장했기 때문입니다.
9. 성능 최적화: dict 구현 개선으로 메모리 사용량이 20-25% 감소했으며, pickle 직렬화/역직렬화 효율이 향상되었습니다. collections.OrderedDict가 C로 구현되었고, os.scandir을 통해 glob 모듈의 glob() 및 iglob()이 3-6배 빨라졌습니다. 이러한 최적화는 개발자가 직접 인지하지 않아도 성능 향상을 가져옵니다.
10. 기타: 빌드 프로세스, C API, 보안 관련 변경 사항 등은 일반적으로 개발자가 직접 신경 쓸 필요가 없습니다.
5. Python 3와 Python 2에서 int와 long의 차이는 무엇인가요?
Python 2에는 long 타입이 존재했습니다.
Python 3에는 long 타입이 없고 int 타입만 존재합니다.
6. xrange와 range의 차이점은 무엇인가요?
xrange는 xrange 객체를 반환하고, range는 리스트를 반환합니다. xrange는 범위의 크기와 상관없이 동일한 메모리를 사용합니다.
참고: Python 3에는 xrange가 없습니다.
Python 3에서의 예시:
>>> range(10)
range(0, 10)
>>> type(range(10))
<class 'range'>
코딩 스타일
7. PEP 8이란 무엇인가요?
1. 변수:
상수: 대문자와 밑줄 (예: USER_CONSTANT).
비공개 변수: 소문자와 선행 밑줄 (예: _private_value). Python에는 엄격한 의미의 비공개 변수는 없지만, 이 규칙은 해당 변수에 외부에서 직접 접근하지 않도록 하는 개발자 간의 약속입니다.
내장 변수: 소문자와 이중 선행/후행 밑줄 (예: __class__). 이는 내장 변수와의 충돌을 피하기 위한 Python의 이름 맹글링(name mangling) 메커니즘입니다. 사용자 정의 변수에서는 이 스타일을 피해야 합니다.
2. 함수 및 메서드:
일반적으로 소문자와 밑줄을 사용합니다. 일부 오래된 라이브러리에서는 카멜 케이스(CamelCase)를 사용하기도 했지만, 현재는 소문자와 밑줄이 표준입니다.
비공개 메서드: 소문자와 선행 밑줄 (private 변수와 마찬가지로 실제 접근 제한은 아닙니다). 이중 선행 밑줄은 Python의 이름 맹글링 때문에 피해야 합니다.
특수 메서드: 소문자와 이중 선행/후행 밑줄 (예: 연산자 오버로딩).
함수 매개변수: 소문자와 밑줄. 기본값 할당 시 등호(=) 양쪽에 공백이 없습니다.
3. 클래스:
클래스는 항상 파스칼 케이스(PascalCase)로 명명합니다 (각 단어의 첫 글자를 대문자로 하고 나머지는 소문자로). 클래스 이름은 간결하고 명확하며 클래스의 역할을 잘 나타내야 합니다.
4. 모듈 및 패키지:
__init__ 모듈을 제외하고, 모듈 이름은 밑줄 없이 소문자를 사용합니다.
5. 매개변수 관련:
5.1 assert를 사용하여 정적 타입 검사를 하지 마세요. assert는 매개변수를 검증하는 데 사용될 수 있지만, 정적 타입 검사만으로는 부족합니다. Python은 동적 타입 언어이므로, 정적 타입 검사는 설계 사상에 위배됩니다. assert는 함수가 불필요하게 호출되는 것을 방지하는 데 사용되어야 합니다.
5.2 *args와 **kwargs의 남용을 피하세요. *args와 **kwargs 매개변수는 함수의 견고성을 해칠 수 있습니다. 시그니처를 모호하게 만들고, 코드에서 작은 파라미터 파서를 구축하게 만드는 경우가 많습니다.
6. 기타:
6.1 불리언(boolean) 변수 이름은 has 또는 is 접두사를 사용하세요 (예: is_connected = True, has_member = False).
6.2 시퀀스(sequence) 변수 이름은 복수형을 사용하세요 (예: members = ['user_1', 'user_2']).
6.3 딕셔너리(dictionary) 변수 이름은 명시적으로 지으세요 (예: person_address = {'user_1':'10 road WD', 'user_2' : '20 street huafu'}).
6.4 일반적인 이름 사용을 피하세요 (예: list, dict, sequence, element).
6.5 기존 이름 사용을 피하세요 (예: os, sys와 같이 시스템에서 이미 사용 중인 이름).
7. 코드 길이:
한 줄 길이: PEP 8은 79자리를 권장합니다. 에디터 화면에 꽉 차지 않을 정도의 길이를 유지하는 것이 좋습니다.
함수 길이: 30줄 미만을 권장합니다. 스크롤 없이 한 화면에 함수 전체를 볼 수 있도록 합니다.
클래스 길이: 200줄 미만, 10개 미만의 메서드를 권장합니다.
모듈 길이: 500줄 미만을 권장합니다.
8. "Python Zen"에 대해 알고 있나요?
import this 명령어를 실행하면 "The Zen of Python, by Tim Peters"의 내용이 출력됩니다:
"Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!"
9. docstring에 대해 알고 있나요?
함수나 메서드 내에 포함된 내장 설명 문자열입니다. 예를 들어, re 모듈을 import한 후 re.__doc__을 출력하면 help(re)와 유사한 문서 내용을 볼 수 있지만, 보통 더 간결합니다.
10. 타입 힌트에 대해 알고 있나요?
Python 인터프리터는 실행 시점에 변수와 매개변수의 타입을 동적으로 결정합니다. 이는 코드 작성 속도를 높이고 유연성을 제공하지만, 코드 유지보수에는 어려움을 초래할 수 있습니다. 시간이 지난 후 코드를 다시 볼 때 변수, 매개변수, 함수의 반환 타입 등을 잊어버리기 쉽기 때문입니다. 또한, 다른 사람의 코드를 읽을 때 변수나 매개변수의 타입을 즉시 파악하기 어려워 학습에 장애가 될 수 있습니다.
Python 3에서는 이러한 문제를 개선하기 위해 타입 힌트(Type Hinting)라는 새로운 기능을 도입했습니다. 이 기능은 매개변수, 함수 반환 값, 변수에 타입을 명시적으로 지정할 수 있게 합니다. 다만, 타입 힌트는 코드의 가독성을 높이기 위한 주석일 뿐이며, 코드 실행 자체에는 영향을 미치지 않습니다. 변수의 실제 타입은 여전히 Python 인터프리터가 결정합니다.