스택 프레임
메소드가 호출되면 스택(Stack) 영역에는 해당 메소드만을 위한 독립적인 공간인 스택 프레임이 생성된다.
Java & Unity, C# Developer
메소드가 호출되면 스택(Stack) 영역에는 해당 메소드만을 위한 독립적인 공간인 스택 프레임이 생성된다.
메소드가 호출되면 스택(Stack) 영역에는 해당 메소드만을 위한 독립적인 공간인 스택 프레임이 생성된다.
C# 언어의 NullReferenceException 예외를 처리하는 현대적 연산자들은 다음과 같다.
C# 프로그래밍은 공용 타입 시스템(Common Type System, CTS)이 자리잡고 있다. 이는 .NET 환경에서 동작하는 모든 언어(C#, VB.NET, F# 등)가 동일한 데이터 타입을 공유하고 서로 소통할 수 있게 만드는 언어적 규약이다.
콘솔 애플리케이션 환경에서 가비지 컬렉터의 메모리 할당부터 해제, 그리고 어떻게 처리하는지 실시간으로 출력하는 예제 코드는 다음과 같다.
TCP 연결은 단순히 연결/해제가 아닌 약 11개의 세밀한 상태를 거친다.
C# 언어에서 Windows API나 기존 C/C++ 언어 라이브러리를 직접 호출해야할 때 P/Invoke를 사용한다.
C# 9.0 이후 레코드(Record)는 데이터 자체를 다루기 위해 설계되었다.
대리자는 클래스 외부에서 마음대로 호출하거나 초기화할 수 있다는 위험이 있다. 이를 해결하기 위해 이벤트가 존재한다.
런타임에 객체의 실제 타입을 찾는 동적 바인딩(Dynamic Binding)의 원리는 다음과 같다.
현대 C# 프로그래밍에서 NullReferenceException 예외를 방지하는 연산자이다. 안전 연산자를 조합하면 수십 줄의 조건부를 단 한 줄로 줄일 수 있으며, 이는 가독성 뿐만 아니라 실수 가능성을 차단한다.
이전 C# 프로그래밍에서 문자열을 자르거나 배열의 일부를 복사할 때마다 새로운 객체가 힙에 생성되었다. 이는 곧 가비지 컬렉터의 일거리가 늘어남을 의미했으며, 최신 .NET은 이를 해결하기 위해 슬라이싱(Slicing) 개념을 도입했다.
모니터링을 할 때 먼저 확인해야 할 데이터들이다. 이 지표들이 나쁘면 프로그램의 응답 속도가 급격히 떨어진다.
가비지 컬렉션은 비관리 리소스가 얼마나 무거운지 모른다. 따라서 메모리 누수와 리소스 부족의 원인을 판별할 줄 알아야 한다.
참조 횟수 계산(Reference Counting)은 가장 고전적인 방식으로 객체마다 나를 참조하는 곳이 몇 군데인지 기록하는 카운터를 둔다.
세대별 가비지 컬렉션은 새로 생성된 객체일 수록 수명이 짧을 확률이 높다는 것과 오래된 객체일 수록 앞으로도 계속 살아남을 확률이 높다는 것 그리고 오래된 객체가 새로운 객체를 참조하는 경우는 드물다라는 것과 같이 경험적으로 증명된 가설을 바탕으로 설계되었다.
가비지 컬렉터(Garbage Collector)는 .NET 애플리케이션의 자동 메모리 관리자이다. C++ 같은 프로그래밍 언어에서는 개발자가 new 키워드로 할당한 메모리를 반드시 delete 키워드로 직접 해제해야 했으나, C# 언어에서는 가비지 컬렉터가 더 이상 사용되지 않는 객체를 스스로 찾아내어 메모리를 회수한다.
C# 언어 네트워크 프로그래밍에는 비동기를 위한 async/await 키워드가 있다.
TCP 프로토콜은 데이터가 끊이지 않고 흐르는 스트림과 같다.
TCP(Transmission Control Protocol)는 데이터를 반드시 전달하는 신뢰성을 보장한다. 이를 위해 내부적으로 다음과 같은 복잡한 일을 수행한다.
WinForm 컨트롤은 단일 스레드 아파트먼트(Single Thread Apartment, STA) 모델을 따르며, 이는 컨트롤을 생성한 스레드만이 해당 컨트롤을 조작할 수 있다는 철칙이다.
WinForm 이벤트는 프로그램과 사용자 사이의 대화 수단이다.
스레드(Thread)는 프로세스 내에서 실행되는 최소 단위의 작업 흐름이다. C# 언어에서는 System.Threading.Thread 클래스를 통해 제어하며 ThreadState 열거형을 통해 여러 상태 변화를 확인할 수 있다.
프로세스(Process)는 실행 중인 프로그램의 인스턴스를 말하며, 운영체제로 부터 독립된 메모리 영역을 할당받아 실행된다. C# 언어에서는 System.Diagnostics 네임 스페이스에 포함된 Process 클래스를 통해 시스템 내의 프로세스를 제어하고 관리할 수 있다.
C# 언어에서 파일과 디렉터리 작업을 수행하는 것은 System.IO 네임 스페이스를 통해 이루어진다. 이는 파일 시스템 정보 조회, 파일 내용 읽기 및 쓰기, 데이터 직렬화 등 모든 입출력 관련 기능을 제공한다.
dynamic 키워드는 컴파일 타임에 타입 검사를 건너뛰고, 런타임에 타입 검사를 수행하도록 하는 기능이다. 이는 정적 타입 언어인 C# 언어에 동적 언어의 유연성을 도입하기 위해 사용한다.
리플렉션(Reflection)은 C# 언어 프로그램 실행 시점에 자신의 타입 정보(메타 데이터)를 검사하고, 이를 사용하여 동적으로 객체를 생성하거나 메소드를 호출하는 프로그래밍 기법이다.
대리자(Delegate)는 특정 매개 변수 목록과 반환 타입을 가진 메소드를 가리키는 객체로, 함수 포인터와 유사하지만 C# 언어에서는 타입 안정성과 객체 지향적 특징을 가진다.
C# 언어에서 예외(Exception)는 프로그램 실행 중 발생하는 오류 상황을 객체화한 것이다. 예외 처리는 프로그램이 이러한 예상치 못한 상황에서도 비정상적으로 종료되는 것을 막고, 안정적으로 복구할 수 있도록 돕는 메커니즘이다.
C# 언어에서 컬렉션(Collection)이란, 같은 타입의 데이터 모음으로 자료 구조(Data Structure)의 일종을 말한다. .NET에서 제공하는 다양한 컬렉션 자료구조가 존재한다.
C# 언어에서 일반화 프로그래밍(Generic Programming)은 데이터 타입을 타입 매개 변수(Type Parameter)로 일반화하여, 하나의 코드 구조를 다양한 데이터 타입에서 재사용할 수 있도록 하는 프로그래밍 기법으로, 제네릭(Generics)이라고 불린다.
C# 언어에서 배열(Array)은 동일한 타입의 요소들을 연속된 메모리 공간에 모아 놓은 자료 구조이며, 참조 타입에 해당한다.
프로퍼티 혹은 속성(Property)은 클래스나 구조체의 필드에 안전하게 접근하고 값을 설정하기 위한 캡슐화된 메커니즘이다. 속성은 외부에서는 필드처럼 보이지만, 내부적으로는 메소드처럼 동작한다.
인터페이스(Interface)는 C# 언어 객체 지향에서 클래스가 구현해야 하는 기능(행위)의 집합을 정의하는 참조 타입으로, 다중 상속의 문제를 피하면서 다형성을 실현하는 핵심이다.
C# 언어의 클래스는 객체 지향의 핵심 요소로 개념 및 구조는 다음과 같다.
C# 언어에서 메소드(Method)는 클래스나 구조체 내에 정의되며, 특정 작업을 수행하는 코드 블록이다. 객체의 행위(Behavior)를 정의하는 핵심 요소이다. 메소드의 구조 및 정의는 다음과 같다.
C# 언어에서 문자열(String) 타입은 일반적으로 사용되는 데이터 타입 중 하나이며, 기술적으로는 참조 타입이지만 값 타입처럼 동작하는 독특한 특성을 가지고 있다. 문자열의 기본 정의 및 특징은 다음과 같다.
공용 타입 시스템(Common Type System, CTS)은 C# 언어를 포함한 .NET 프레임워크 또는 .NET 코어를 기반으로 하는 모든 언어가 서로 호환되며 일관성 있게 동작할 수 있도록 정의된 표준이다. .NET 환경 내에서 데이터 타입, 동작 방식, 선언 규칙 등을 통합하고 표준화하는 역할을 수행한다.
C# 언어가 제공하는 기본 데이터 타입에는 모두 15가지가 있다. 이들은 크게 숫자 타입, 논리 타입, 문자열 타입, 오브젝트 타입으로 나뉜다. 이 중에서 문자열 타입과 오브젝트 타입은 참조 타입에 해당하며, 나머지는 모두 값 타입이다.
#의 유래C/C++ 언어가 AT&T 벨 연구소에서 출생한 반면, C# 언어는 마이크로소프트의 엔더스 헤일스버그가 만들었으며, 마이크로소프트는 인터넷 서비스는 모든 종류의 기기에서 사용할 수 있어야 한다라는 기조로 .NET 비전을 발표했다.
(Java 8 이후부터)람다(Lambda) 표현식은 함수형 프로그래밍 스타일을 자바에 적용하기 위한 핵심 요소로, 람다 대수(Lambda Calculus)에서 유래했다.
(Java 7 이후부터)포크/조인 프레임워크는 java.util.concurrent 패키지에 속하며, 분할 정복 알고리즘을 기반으로 대규모 작업을 효율적으로 병렬 처리하여 멀티 코어 시스템의 성능을 극대화하는 것을 목표로 한다. 프레임워크는 작업을 작은 단위로 재귀적으로 분할하고, 그 서브 작업들의 결과를 합치는 방식으로 전체 결과를 도출한다.
작업의 처리 순서와 흐름을 결정하는 중요한 개념으로, 멀티 스레드 환경이나 네트워크 통신에서 두 방식의 차이는 시스템의 성능과 안정성에 큰 영향을 미친다.
객체지향 프로그래밍에서 유연하고 유지 보수하기 쉬운 소프트웨어 시스템을 설계하기 위한 5가지 기본 원칙의 약자로 각 원칙은 독립적이지만, 함께 적용될 때 응집도를 높이고 결합도는 낮추는 효과를 극대화한다.
클래스는 객체를 생성하기 위한 설계도 또는 도구이다.
리플렉션(Reflection)은 자바 프로그램이 런타임에 자신의 구조를 검사하고, 심지어 동적으로 변경할 수 있도록 하는 기능으로, java.lang.reflect 패키지에 포함된 클래스들을 사용하여 구현한다.
자바 클래스 멤버는 static 키워드의 유무에 따라 객체 멤버(Non-Static)와 클래스 멤버(Static)로 구분되며, 이는 메모리 관리 및 접근 방식에서 근본적인 차이를 발생시킨다.
자바에서 float 타입 사용이 줄어드는 가장 결정적인 이유는 부족한 정밀도 때문이다.
서버-클라이언트 1:1 채팅 예제는 클라이언트에서부터 시작하여 클라이언트와 서버가 순서대로 번갈아 가면서 메시지를 주고 받았다. 이 예제를 참고하여 순서에 상관없이 자유롭게 서버와 클라이언트가 메시지를 주고 받을 수 있도록 스레드를 이용하여 스윙 프로그램으로 재작성하라.
| 요소 | 제약 조건 및 규칙 |
|---|---|
| 통신 방식 | 순서에 상관 없이(스레드를 이용한 비동기 수신/발신 구현) 자유롭게 메시지를 주고 받는다. |
| GUI 요소 | 상대방으로부터 받은 메시지 출력: JTextArea상대방에게 보낼 메시지 입력: JTextField |
| 메시지 전송 | JTextField 클래스에 입력 후 <Enter> 키를 입력하면 즉시 전송한다. |
| 접속 및 실행 | ChatServer 객체를 먼저 실행 후, ChatClient 객체를 실행하여 접속한다. |
| 프로그램 종료 | 어느 한쪽에서 "bye"를 입력하거나 창을 닫으면 상대방에게 종료를 알리고 프로그램이 종료된다. |
소켓 통신은 개발자가 TCP/IP 네트워크를 이용하여 통신 프로그램을 작성하도록 지원하는 기반 기술이다. 소켓은 통신하는 두 응용 프로그램 간의 통신 링크의 각 끝단으로서, TCP/IP의 네트워크 기능을 활용하여 다른 컴퓨터의 소켓과 데이터를 주고 받으며, 특정 포트에 연결되어 해당 응용 프로그램을 식별한다.
스윙 컴포넌트와 멀티 스레드 개념을 이용하는 아바타와 괴물 게임을 아래 제시된 규칙과 제약 조건을 모두 충족하여 AvatarChaseGame, GamePanel, MonsterThread 3개의 클래스를 설계하고 구현하라.
스레드의 상태는 다음과 같이 총 6가지이며, JVM에 의해 관리된다.
Thread 클래스의 경로명은 java.lang.Thread이고, Thread 클래스를 상속받아 개발자의 스레드 코드를 만들 수 있으며, 스레드를 만들고 유지 관리하기 위해 다음과 같은 메소드를 제공한다.
영어 단어와 한글 단어로 구성되는 Word 클래스를 작성하고, 프로그램 내에서 미리 여러 개의 Word 객체를 Vector<Word> 컬렉션에 삽입한다. 그리고 다음 결과와 같이 랜덤하게 사용자에게 문제를 던진다. 백터 내에 정답이 아닌 단어를 랜덤하게 3개를 선택하고 정답과 함께 4개의 보기를 출력한다.
기존의 클래스와 유사하지만, 클래스 이름 다음에 일반화된 타입(Generic Type)의 매개 변수를 “<>” 다이아몬드 연산자에 추가한다는 차이가 있다.
Vector 클래스는 배열을 가변 크기로 다룰 수 있게 하고, 객체의 삽입, 삭제, 이동이 쉽도록 구성한 컬렉션 클래스이다. 삽입되는 요수의 개수에 따라 자동으로 크기를 조절하고, 요소의 삽입과 삭제에 따라 자동으로 요소들의 자리를 이동한다. 자바 내부에서 크기를 구성하는 방식은 다음과 같다.
배열은 여러 개의 데이터를 다루는 데 편리한 자료 구조이지만, 삽입과 삭제가 빈번하고, 데이터의 크기를 예측할 수 없는 응용 프로그램에서 사용하기에 불편하다. 이와 반대로 컬렉션은 배열이 가진 고정 크기의 단점을 극복하긷 위해 객체들을 쉽게 삽입, 삭제, 검색할 수 있는 가변 크기의 컨테이너이다. 컬렉션을 위한 자바 인터페이스와 클래스는 다음과 같다.
java.lang 패키지에 포함된 클래스로서 String 클래스는 문자열을 나타낸다. 문자열 리터럴은 자바 컴파일러에 의해 모두 String 객체로 처리된다.
byte, short, int, long, char, double, float 등 8개의 기본 타입을 객체로 다루기 위해 JDK에 만들어진 8개 클래스를 통칭하여 래퍼(Wrapper) 클래스라고 한다. JDK의 일부 클래스는 객체만을 다루기 때문에 3, ‘a’ 등 기본 타입의 데이터를 사용할 수 없으므로 기본 타입의 값을 객체로 만들어 사용할 수 있도록 한다. 객체 생성 예제 코드는 다음과 같다.
개발자마다 자신의 디렉터리에 클래스를 배치한다면 파일의 디렉터리가 서로 달라 다른 파일로 인식된다. 이러한 디렉터리를 자바에서는 패키지(Package)라고 부르며, 하나의 패키지는 관련된 클래스 파일들이 들어 있는 디렉터리로 볼 수 있다. 파일의 디렉터리는 다음과 같이 점(.)을 찍어 표현한다.
추상 클래스 및 상속 개념을 이용하는 물고기 사냥 미니 게임을 아래 제시된 규칙과 제약 조건을 모두 충족하여 Bear, Fish FishHuntingMinigame 3개의 클래스를 설계하고 구현하라.
상속의 몇 가지 특징은 다음과 같다.
자바에서는 객체를 생성하는 new 연산자는 있지만 객체를 소멸시키는 연산자는 없다. 이런 이유로 자바에서는 개발자가 마음대로 객체를 소멸시킬 수 없다.
try-catch 문을 이용하여 정수를 0으로 나누는 경우에 오류 안내문을 출력하고 다시 입력 받는 프로그램의 예제 코드는 다음과 같다.
객체가 생성될 때 객체의 초기화를 위해 실행되는 메소드로, 자바, C++, C#, Python 등 모든 객체 지향 언어에 존재한다.
자바 응용 프로그램의 실행히 시작되는 특별한 메소드로, 다음과 같은 특징을 가지고 있다.
프로그램의 실행에 영향을 미치지 않으며, 프로그램에 대한 설명이나 특이 사항을 자유롭게 기록하기 위해 사용한다.
JDK(Java Development Kit)는 자바 개발자를 위한 소프트웨어로, 자바 컴파일러 등의 개발 도구와 JRE(Java Runtime Environment)로 구성된다. JRE는 자바 응용 프로그램이 실행될 때 개발자가 활용할 수 있는 API와 자바 가상 머신을 포함한다. 개발자의 경우 JDK와 JRE가 필요하며, 일반 사용자의 경우 JRE가 필요하다.
자바는 하드웨어, 운영체제 등 플랫폼에 종속되지 않는 독립적인 바이트 코드로 컴파일되며 자바 가상 머신만 있으면 프로그램의 실행이 가능하다.