본문 바로가기
728x90
반응형

주니어~중니어 레벨에서 여러 언어들을 공부하고 다뤄보다 보니깐

프로그래밍 언어는 개발을 하기 위한 기초/방법이면서, 그 언어의 컨셉에 알맞게 사용해야 하는게 올바른 사용방법이라고 생각한다

보통 이런 것들을 Best Practice / Do Not Apply Anti Pattern 이라고 부르며, 잘 이해하고 쓰기 위한 지침서라고 생각하면 된다

개발을 할때 항상 위에 키워드들을 검색해보는 습관을 기르자

 

잡설하고 여러 프로그래밍 언어들의 특징들에 대해서 알아보자

 

컴퓨터<->사용자 관점 - 수준(Level)

  1. Low Level Language(저수준 언어)
    • 컴퓨터가 직접 이해하고 실행할 수 있는 언어
    • 0과 1로 이루어진 2진 코드(binary code)로 표현되며, 하드웨어 직접 제어가 가능
    • 사람이 이해하고 사용하기 매우 어렵기 때문에 일반적으로 프로그래밍에 직접 사용되지 않음
      • Machine Language(기계어)
  2. Middel Level Language(중급 언어)
    • 기계어보다는 사람이 알아보기 쉬운 니모닉 기호(mnemonic symbol)를 정해 사람이 좀 더 쉽게 컴퓨터의 행동을 제어
    • 어셈블리 언어는 기계어에 직접 대응하는 명령어를 사용하지만, 명령어들이 기호적인 이름(예: ADD, SUB 등)을 가지고 있어서 프로그래밍이 다소 용이
    • 어셈블리 언어는 특정 CPU 아키텍처에 종속적이며, 어셈블러라는 특별한 프로그램을 사용하여 기계어로 변환되어 실행됨
    • 현대에서는 고급 어셈블러가 존재해 높은 추상화를 제공
      • Assembly Language(어셈블리 언어)- x86어셈블리, ARM어셈블리, MIPS 어셈블리, MASM, TASM, FASM, NASM, YASM
  3. High Level Language(고급 언어)
    • 고급 언어는 인간의 언어와 더 유사하며, 프로그래머가 컴퓨터 하드웨어를 직접 다루는 복잡성으로부터 추상화된 언어
    • 하드웨어의 세부 사항으로부터 추상화를 제공하므로, 다양한 하드웨어 플랫폼에서 작동할 수 있게 해주는 컴파일러나 인터프리터가 필요
    • 메모리 주소 지정, 레지스터 사용과 같은 기본 하드웨어 구성 요소보다는 프로그래밍 논리에 더 중점을 둠 
      • C, C++, C#, Java, Pascal, Python, Visual Basic

 

실행 방식 관점 - Compile/Interpret/Hybrid

  1. Interpreted Language(인터프리트 언어)
    • 컴파일 과정을 거치지 않고, 실행 즉시 인터프리터를 거쳐서 실행되는 프로그래밍 언어
    • 실행 시마다 소스코드를 한 줄 씩 기계어로 번역하는 방식이기 때문에 실행 속도는 컴파일 언어보다 느리다
    • 인터프리트 언어에 속한 종류 - 스크립트 언어 
      • Script Language(스크립트 언어)
        - 스크립트 언어는 응용 소프트웨어(어플리케이션)를 제어하는 컴퓨터 프로그래밍 언어를 가리킨다
        - 대부분 인터프리터 방식으로 동작한다

        - 단일 응용프로그램으로 사용되기보다는 응용프로그램 내에서 특정 역할을 수행하는 경우가 많다

        - ex) 웹 페이지 내에 속한 자바스크립트는 웹 브라우저, 즉 클라이언트 측에서 수행된다

        - ex) 시스템에서 내부 특정 프로그램으로 동작(쉘 스크립트)
      • 인터프리트 언어
        • Python, Ruby, Bash, Perl, PHP, R, Erlang, TCL
      • 스크립트 언어
        • AppleScript, JavaScript, jQuery, JSP, PHP, ASP, Perl, Python, Ruby, VBScript, Shell Script, Groovy, Lua
  2. Compiled Language(컴파일 언어)
    • 코드가 실행되기 전 컴파일러를 거쳐서 기계어로 변환되어 실행되는 프로그래밍 언어
    • 컴파일러 종류 - AOT 컴파일러, JIT 컴파일러
      • AOT(Ahead Of Time) - 프로그램으로 만들어지기 전에(실행 시간 이전에)
        - 실행 시간 이전에 전체 코드를 기계어로 바꾸는 방식. 정적 컴파일이라고도 부른다
        - 한번 기계어로 번역되면 코드를 수정할 수 없다
        - 전체 코드를 실행 전에 기계어로 바꾸기 때문에 컴파일 타임은 길다. 하지만 실행 시간은 줄어들고, 최적화를 통해 성능을 향상시킬 수 있는 장점이 있다
        - 플랫폼에 대한 의존도가 높아질 수 있고, 유연성이 떨어질 수 있다는 단점이 존재
        • C, C++, Go, Rust, TypeScript, Object-C
      • JIT(Just In Time) - 즉시(실행 시점에)
        - 코드를 실제로 실행하는 시점에 기계어로 번역하는 방식. 동적 컴파일이라고도 부른다
        - 내부적으로 인터프리트 방식 + 컴파일 방식을 혼합하는 방식이라고 생각해도 된다
        - 실행 시점에 인터프리트 방식으로 기계어코드를 캐싱하여, 같은 함수가 여러번 불릴 때 매번 기계어코드가 생성되는 것을 방지한다
        - 런타임시에 수정된 코드로 기계어를 만들 수 있다 -> 코드 수정 가능
        - 코드를 실행 시점에 기계어로 번역하기 때문에 그 순간 컴파일 타임이 존재하여 초기 실행 시간이 느려질 수 있다
        • Java, C#, Python
  3. Hybrid Language(하이브리드 언어)
    • 컴파일방식과 인터프리트 방식을 둘 다 혼용하는 방식
    • Virtual Machine(Java, Python)에서 인터프리트 되거나 JIT 컴파일을 통해 실행됨
    • Dart 언어의 경우 개발모드일때는 JIT컴파일을, 배포모드일때는 AOT컴파일을 진행할 수 있다. 또한 Dart VM을 통해 코드를 인터프리트 할 수도 있다
      • Java(JVM), C#(.NET), Python(PVM/PyPy), V8(JavaScript Engine), Dart

 

발상/시각 관점(패러다임) - Paradigm

  1. Imperative(명령형) - 코드가 실행 흐름과 상태 변경을 직접 제어
    • Procedural(절차적)
      루틴, 서브루틴 또는 함수의 집합으로 프로그램을 구성하는 방식
      • C, Pascal
    • Object-Oriented(객체지향)
      데이터와 기능을 객체로 캡슐화하여 프로그램을 구성하는 방식
      • C++, Java, C#, Python
  2. Declarative(선언형) - 코드가 원하는 결과의 속성을 선언하지만, 직접 계산하는 방법은 명시하지 않음, SQL도 여기 포함
    • Functional(함수형)
      순수 함수와 불변성을 중시하며, 사이드 이펙트를 최소화하는 방식
      • Kotlin, Scala, Haskell, Erlang
    • Logic(논리형)
      논리적인 명제와 규칙을 바탕으로 문제를 해결하는 방식
      • Prolog
    • Reactive(반응형)
      데이터 흐름과 변화의 전파에 중점을 두어, 비동기 데이터 스트림을 통해 프로그램의 동작을 정의
      • RxJava, RxJS, Rx.NET
  3. ETC - ET Cetra(기타, 확장)
    • Event-Driven(이벤트 중심)
      이벤트(사용자 액션, 시스템 메시지 등)에 반응하여 코드를 실행하는 방식
      • JavaScript, Node.Js
    • Parallel(병렬)
      계산 작업을 동시에 실행하기 위해 여러 프로세서를 사용하는 방식
      • CUDA
    • Meta(메타)
      코드가 다른 코드를 생성, 수정, 조사하는 기법
      • Java, Python, Go, Lisp
    • Component-Based(컴포넌트 기반)
      재사용 가능한 컴포넌트(소프트웨어 모듈)를 사용하여 애플리케이션을 구축하는 방식
      • React, Vue, Angular
    • DSL(도메인 특화)
      특정 문제 영역을 대상으로 하는 프로그래밍 언어들
      • MarkUp(HTML, XML, Markdown), Style Sheet(CSS)

 

자료형 결정 시점 관점 - Type Decision Time

  1. Static Typing(정적 타입)
    • 컴파일 시에 타입을 검사 - 타입 관련 오류를 미리 감지할 수 있어 안정성이 높음
    • 성능 최적화 - 컴파일러가 타입 정보를 사용하여 최적화할 수 있어서, 실행 시간 성능이 향상될 수 있음
    • 복잡성 - 모든 변수에 대해 타입을 지정해야 하기 때문에 코드가 더 길어지고 복잡해질 수 있는 가능성
    • 유연성 부족 - 한 변수에 한 타입만 할당할 수 있으므로, 동적으로 타입을 변경하는 것이 어려움
      • C, C++, Java
  2. Dynamic Typing(동적 타입)
    • 런타입 시에 타입을 검사 - 프로그램이 실행되는 도중에 변수의 타입을 결정하고 검사
    • 유연성 - 변수에 다양한 타입의 값이 할당될 수 있어, 유연한 프로그래밍이 가능
    • 런타임 에러 - 컴파일 시점에 타입 불일치를 감지할 수 없기 때문에 런타임 에러가 발생할 가능성이 높다
    • 성능 비최적화 - 런타임시에 타입을 확인해야 하기 때문에 성능이 상대적으로 느릴 수 있음
      • Python, JavaScript

 

타입 안정성 관점 - Type Safety

Strong/Weak의 Definition(정의)

  • Type Safety(타입 안정성)
  • Memory Safety(메모리 안정성)
  • Static Type-Checking(정적 타입 검사) 또는 Dynamic Type-Checking(동적 타입 검사)

약타입 언어는 아래와 같은 기법들을 넓은 범위에서 허용한다

  • Implicit Type Conversion/Type Coercion(암시적 타입 변환)
    다른 타입 간의 연산이나 할당에서 언어가 자동으로 타입을 변환
    ex) JavaScript - 문자열과 숫자가 더해질 때 자동으로 숫자가 문자열로 변환되는 경우
var x = 3    
var y = '4'
alert(x + y) // "34"

 

  • Type Punning(실제 값과 타입을 무시한 채 형변환 없이 다른 자료형으로 변환하는 것)
    메모리를 한 타입으로 할당받았지만 다른 타입으로 해석하여 사용
    ex) C - 포인터(pointer)와 공용체(union)을 사용하는 경우, 바이트배열로 데이터를 조작해서 다른 타입의 데이터로 해석
    아래 코드의 경우 int자료형으로 할당받다가 나중에 double자료형으로 사용한다
int f(const int* pi, double* pd)
{
    int results = *pi;
    *pd = 3.14159;
    return results;
}

 

  • Strong Typing(강타입)
    • 타입을 엄격하게 다룸(엄격한 타입 검사)
    • 암시적 타입 변환이 제한적
    • Type Punning이 일반적으로 허용되지 않음
      • Python, C#, Swift, Java, Kotlin, Dart, TypeScript, Rust, Go
  • Weak Typing(약타입)
    • 타입을 유연하게 다룸(느슨한 타입 검사)
    • 암시적 타입 변환을 넓게 허용
    • Type Punning이 가능한 언어도 존재
      • C, C++, JavaScript, PHP

==> Python은 Dynamic(동적), Strong(강) Typing 언어이다

# Dynamic Typing
x = 'somestring' # str
x = 50 # int

# Strong Typing
print(x + y)

----------------------------------------------------------------------
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

 

딱히 면접에 나올것같은 크리티컬한 지식은 아니지만, 알아두면 좋을 것 같다ㅎ Compile != Strong

 

메모리 관리 관점 - Memory Management

메모리 관리를 프로그래머가 직접 해야 하는지, 아닌지에 따라서 분류

  • 매니지드 언어(Managed Language)
    • 런타임 환경(Runtime Environment) 또는 가상 머신(Virtual Machine) 위에서 실행됨
    • 메모리 관리(가비지 컬렉션), 타입 검사, 예외 처리 등을 자동으로 처리
      • Java(JVM - JavaVirtualMachine)
        C#(CLR - CommonLanguageRuntime)
        Python(Python Interpreter- CPython, Pypy, PVM - PythonVirtualMachine)
        JavaScript(Chrome V8)
  • 언매니지드 언어(Unmanaged Language)
    • 런타임 환경이나 가상 머신 없이 직접 시스템의 하드웨어 자원을 관리
    • 메모리 할당과 해제, 포인터 연산 등을 개발자가 직접 제어해야 함
    • 높은 성능과 저수준의 시스템 접근이 가능
      • C, C++

 

사용 분야 관점 - Usage

  • 그래픽 (게임 개발, 3D 렌더링, UI/UX Design)
    • C++: Unreal Engine, OpenCV, Cuda
    • C#: Unity Engine, GDI
    • JavaScript/TypeScript: WebGL
  • 네트워크 (웹 개발, 서버 사이드, 클라우드)
    • JavaScript/TypeScript: Node.js/Nest.js, Angular/React/Vue
    • Python: Flaks, Django, FastAPI
    • Java: Spring Framework
    • C#: ASP.NET
    • Go
    • Kotlin, Scala
  • 하드웨어 (임베디드 시스템, 시스템 프로그래밍)
    • C
    • C++
    • Go
  • 데이터 과학/머신러닝
    • Python - Numpy, Pandas, TensorFlow, PyTorch
  • 모바일
    • Java(Legacy) 
    • Kotlin
    • Object-C(Legacy)
    • Swift
    • Dart

 

 


프로그래밍 언어로 나올 수 있는 모든 것들을 정리하고 나니 후련하기도 하고, 신기하기도 하고 배운 것도 많았다

포스팅을 하면서 내가 알고 있는 것에 대한 확신을 얻고, 더 잘 알게 되기도 하면서 내가 몰랐던 부분을 알아가고 지식들을 목차에 맞게 정리하는건 매우 값진 시간이라고 생각한다

최대한 이곳저곳 검색을 통해 맞는 정보만을 전달하려고 노력했으며, 내가 몰랐거나 틀린 부분이 있다면 댓글로 알려주면 감사히 수정하겠다!!


 

https://ko.wikipedia.org/wiki/%EC%BB%B4%ED%8C%8C%EC%9D%BC_%EC%96%B8%EC%96%B4

https://ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%8A%B8_%EC%96%B8%EC%96%B4

http://wiki.hash.kr/index.php/%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8_%EC%96%B8%EC%96%B4

https://ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0

https://jeffrytandiono.medium.com/understanding-compiled-interpreted-hybrid-languages-9764f641faa7

https://dsaint31.tistory.com/496

https://mrale.ph/dartvm/

https://yozm.wishket.com/magazine/detail/1334/

https://en.wikipedia.org/wiki/Programming_paradigm

https://en.wikipedia.org/wiki/Comparison_of_programming_paradigms

https://en.wikipedia.org/wiki/Strong_and_weak_typing

https://tttapa.github.io/Pages/Programming/Cpp/Practices/type-punning.html

https://stackoverflow.com/questions/11328920/is-python-strongly-typed

https://stackoverflow.com/questions/2351190/static-dynamic-vs-strong-weak

 

728x90
반응형

'Program Language > Common' 카테고리의 다른 글

Programming Study Honey Tips (feat. JetBrains/Rust)  (2) 2024.03.12

댓글