#gpt
라이브러리
라이브러리는 프로그래밍에서 사용되는 재사용 가능한 코드의 집합입니다. 일반적으로 라이브러리는 특정 기능을 수행하는 함수, 클래스, 인터페이스 등으로 구성되어 있습니다. 프로그래머는 라이브러리를 사용하여 자신이 작성하는 프로그램의 개발 속도를 높일 수 있고, 이미 구현되어 있는 기능을 재사용하여 코드의 중복을 피할 수 있습니다.
→ 즉,
라이브러리는 프로그래밍에서 사용되는 도구 상자라고 생각하시면 됩니다. 이 도구 상자 안에는 여러 가지 기능들이 들어있어요. 예를 들어, 만약에 여러분이 프로그램에서 날짜와 시간을 다루고 싶다면, 날짜와 시간에 관련된 기능들이 포함된 라이브러리를 사용할 수 있어요. 이러한 라이브러리를 가져와서 여러분의 프로그램에 적용하면, 날짜와 시간을 다루는 기능을 손쉽게 사용할 수 있습니다. 라이브러리는 이미 만들어진 코드들의 집합이기 때문에, 새로운 코드를 작성하지 않고도 기능을 추가하거나 문제를 해결할 수 있어요. 이렇게 라이브러리를 사용하면 개발 시간을 단축할 수 있고, 더욱 효율적으로 프로그램을 개발할 수 있답니다.
정적/동적
정적(Static)과 동적(Dynamic)은 프로그래밍에서 변수와 메모리 할당에 관련된 개념입니다.
정적(Static)은 프로그램이 실행되기 전에 변수와 메모리가 정해지고 고정되는 것을 의미합니다. 예를 들어, 정적 변수는 프로그램이 시작될 때 메모리에 할당되고, 해당 변수는 프로그램 실행 도중에는 크기나 위치가 변경되지 않습니다. 정적 변수는 전역 변수(프로그램 전체에서 접근할 수 있는 변수, 어떤 함수나 블록에서 사용할 수 있는 변수)로 사용되기도 하며, 프로그램 전체에서 공유될 수 있습니다.
반면에 동적(Dynamic)은 프로그램이 실행되는 동안 변수와 메모리가 필요에 따라 할당되고 해제되는 것을 의미합니다. 동적 변수는 프로그램 실행 도중에 생성되고 소멸될 수 있으며, 필요에 따라 크기나 위치가 변경될 수 있습니다. 동적 변수는 주로 힙(heap)이라는 메모리 영역에 할당되며, 필요 없어지면 메모리에서 해제됩니다.
소스 코드
-소스 : 원본
-소스 코드 : 프로그램의 원시 코드(사람이 이해하는 형태로 작성된 프그래밍 언어) 컴퓨터가 실행 가능한 형태로 변환되기 전에 작성되는 원본 코드
"소스 코드"와 "컴파일러"는 서로 반대되는 개념입니다.
소스 코드는 프로그램의 원시 코드로, 사람이 이해할 수 있는 형태로 작성된 프로그래밍 언어로 구성되어 있습니다. 소스 코드는 프로그램의 동작 방식을 정의하고 원하는 작업을 구현하는 역할을 합니다.
반면에, "컴파일러"는 소스 코드를 읽어들여 실행 가능한 형태로 변환해주는 프로그램입니다. 컴파일러는 소스 코드를 기계어로 변환하여 컴퓨터가 이해하고 실행할 수 있는 프로그램인 "바이너리 코드"로 변환합니다. 이러한 변환 과정을 "컴파일"이라고 합니다.
따라서, 소스 코드는 프로그램을 작성하기 위한 원본 코드이고, 컴파일러는 이 소스 코드를 읽어들여 컴퓨터가 실행 가능한 형태로 변환해주는 역할을 합니다. 소스 코드와 컴파일러는 프로그램 개발 과정에서 밀접한 관련이 있는 개념입니다.
"소스 코드"와 "디코딩"은 서로 다른 개념입니다.
"소스 코드"는 프로그램의 원시 코드로, 사람이 이해할 수 있는 형태로 작성된 프로그래밍 언어로 구성되어 있습니다. 소스 코드는 프로그램의 동작 방식을 정의하고 원하는 작업을 구현하는 데 사용됩니다.
반면에 "디코딩"은 인코딩된 데이터를 해독하여 원래의 정보를 복원하는 과정을 말합니다. 일반적으로 데이터가 암호화되어있거나 압축되어있을 때, 디코딩을 통해 원래의 형태로 되돌릴 수 있습니다.
소스 코드는 프로그래밍 언어로 작성된 원시 코드이며, 컴파일러나 인터프리터를 통해 실행 가능한 형태로 변환됩니다. 반면에 디코딩은 데이터를 해독하는 과정으로, 암호화된 데이터나 압축된 데이터를 해제하여 원래의 형태로 복원하는 작업을 의미합니다.
따라서, "소스 코드"와 "디코딩"은 서로 다른 개념이며, 다른 문맥에서 사용됩니다.
인터프린터
인터프리터는 소스 코드를 한 줄씩 읽어들여 바로 실행하는 프로그램입니다. 컴파일러와는 달리 소스 코드를 변환하지 않고, 실행 가능한 형태로 변환하지 않고도 바로 실행할 수 있습니다.
인터프리터는 소스 코드를 읽어들이면서 각 줄을 순차적으로 해석하고 실행합니다. 소스 코드를 한 줄씩 해석하고 실행하기 때문에 디버깅이 상대적으로 용이하고, 수정한 코드를 바로 반영하여 실행할 수 있습니다. 하지만 인터프리터는 소스 코드를 한 줄씩 해석하고 실행하기 때문에 컴파일러에 비해 실행 속도가 상대적으로 느릴 수 있습니다.
인터프리터는 다양한 프로그래밍 언어에서 사용됩니다. 예를 들면, Python, JavaScript, Ruby 등의 스크립트 언어는 주로 인터프리터 방식으로 동작합니다. 이러한 언어에서는 소스 코드를 작성하고 바로 실행할 수 있습니다.
요약하자면, 인터프리터는 소스 코드를 한 줄씩 읽어들여 실행하는 프로그램으로, 컴파일러와는 실행 방식과 특징에서 차이가 있습니다.
컴파일러
컴파일러는 소스 코드를 읽어들여 실행 가능한 형태로 변환하는 프로그램입니다. 소스 코드를 기계어로 변환하여 컴퓨터가 이해하고 실행할 수 있는 프로그램인 "바이너리 코드"로 변환합니다.
컴파일러는 소스 코드를 전체적으로 분석하고, 문법적인 오류를 검사한 후에 중간 단계의 코드인 "목적 코드"로 변환합니다. 목적 코드는 컴퓨터가 직접 실행할 수는 없지만, 특정 컴퓨터 아키텍처에서 실행 가능한 형태로 변환됩니다. 이후에 목적 코드는 링커(Linker)를 통해 다른 목적 코드나 라이브러리와 결합되어 최종적으로 실행 파일이 생성됩니다.
컴파일러를 사용하면 소스 코드를 한 번에 전체적으로 변환하기 때문에 실행 속도가 빠릅니다. 또한 변환된 실행 파일은 반복해서 실행할 수 있으며, 컴퓨터의 특정 아키텍처에 최적화된 코드를 생성할 수 있습니다. 하지만 컴파일러는 소스 코드를 수정한 경우에는 다시 전체적으로 컴파일해야 하므로 수정이 빈번한 경우에는 번거로울 수 있습니다.
컴파일러는 다양한 프로그래밍 언어에서 사용됩니다. C, C++, Java, Go 등의 언어는 주로 컴파일러를 사용하여 실행 파일을 생성합니다. 이러한 언어들은 컴파일 단계에서 모든 소스 코드를 변환하고 최적화하여 실행 파일을 생성합니다.
요약하자면, 컴파일러는 소스 코드를 실행 가능한 형태로 변환하는 프로그램으로, 소스 코드를 전체적으로 분석하고 목적 코드로 변환하여 최종적으로 실행 파일을 생성합니다.
객체 - 존재할 수 있는 모든 것
객체는 일반적으로 "존재할 수 있는 모든 것"을 나타낼 수 있습니다. 객체는 현실 세계의 사물, 개념, 추상적인 개체 등을 프로그래밍에서 모델링하여 표현하는 것이기 때문입니다.
객체 지향 프로그래밍에서는 실제로 존재하는 사물이나 개념을 객체로 표현할 수 있을 뿐만 아니라, 개발자가 필요에 따라 추상적인 개념이나 가상의 개체도 객체로 표현할 수 있습니다. 예를 들어, "사람"이라는 개념을 객체로 표현할 수 있고, "은행 계좌"라는 추상적인 개체도 객체로 표현할 수 있습니다.
객체는 데이터와 해당 데이터를 처리하는 메서드(함수)로 구성되어 있으며, 이를 통해 객체의 상태와 동작을 표현할 수 있습니다. 객체는 속성과 행위를 가지고 있으며, 이를 통해 객체들 간의 상호작용이 이루어집니다.
하지만 주의해야 할 점은 "모든 것"을 객체로 표현할 수 있다고 해도, 실제로 모든 것을 객체로 표현할 필요는 없다는 점입니다. 객체 지향 프로그래밍에서는 적절한 객체를 선택하여 프로그램을 설계하고 구현하는 것이 중요합니다.
요약하자면, 객체는 일반적으로 "존재할 수 있는 모든 것"을 프로그래밍에서 모델링하여 표현할 수 있습니다. 객체는 데이터와 메서드로 구성되어 있으며, 현실 세계의 사물, 개념, 추상적인 개체 등을 객체로 표현할 수 있습니다.
절차지향
절차지향 프로그래밍에서 프로시저(Procedure)와 데이터(Data)를 분리한다는 것은 프로그램의 코드를 함수 또는 프로시저로 구성하고, 이러한 함수들은 전역 변수와 같은 데이터를 공유하지 않는다는 의미입니다.
일반적으로 절차지향 프로그래밍에서는 함수나 프로시저를 작성하여 특정 작업을 수행하도록 설계합니다. 이러한 함수들은 입력을 받아들이고, 필요한 연산을 수행한 후 결과를 반환합니다. 함수 내에서 사용되는 데이터는 지역 변수로 선언되며, 함수 호출이 끝나면 해당 변수는 소멸됩니다. 함수 간에 데이터를 공유하기 위해 전역 변수를 사용하는 경우도 있지만, 전역 변수의 사용은 제한적으로 이루어져야 합니다.
따라서, 절차지향 프로그래밍에서 프로시저와 데이터를 분리한다는 것은 함수나 프로시저를 통해 작업을 수행하고, 이들 함수는 지역 변수를 사용하여 필요한 데이터를 처리하며 전역 변수를 최소화하여 데이터와 프로시저를 분리한다는 의미입니다. 이는 코드의 가독성과 유지보수성을 향상시키는 장점을 가지고 있습니다.
쉽게 말하면,
절차지향 프로그래밍에서 프로시저와 데이터를 분리한다는 것은 프로그램을 만들 때, 작업 단계를 함수 또는 프로시저로 나누고, 이들 함수는 따로 저장된 데이터를 사용하지 않는다는 의미입니다.
이해를 돕기 위해 가정을 해보겠습니다. 예를 들어, 여러분이 게임을 만든다고 상상해봅시다. 게임에서는 캐릭터가 움직이고, 공격하고, 아이템을 사용하는 등의 작업을 수행해야 합니다.
절차지향 프로그래밍에서는 이러한 작업을 함수로 나누어 처리합니다. 예를 들어, "캐릭터를 움직이는 함수", "캐릭터를 공격하는 함수", "아이템을 사용하는 함수"와 같은 작업을 수행하는 함수들을 만듭니다. 각 함수는 필요한 데이터를 받아서 작업을 수행하고, 그 결과를 반환합니다.
이때, 함수 내에서 사용되는 데이터는 함수 내부에서만 사용되는 지역 변수로 선언됩니다. 다른 함수에서는 해당 변수에 직접 접근할 수 없으며, 함수 호출이 끝나면 변수는 사라집니다. 이렇게 함수들은 독립적으로 작업을 수행하고, 필요한 데이터를 함수 내부에서 처리하기 때문에 데이터와 함수가 분리되어 있다고 말할 수 있습니다.
이 방식은 코드를 더욱 모듈화하고, 각 함수의 역할과 기능을 명확하게 분리하여 가독성과 유지보수성을 높일 수 있습니다.
객체지향
객체지향 프로그래밍은 일상 생활에서 우리가 자주 접하는 사물이나 개념을 프로그램으로 표현하는 방법입니다.
예를 들어, 우리가 자동차에 대한 프로그램을 만들려고 한다고 가정해봅시다. 객체지향 프로그래밍에서는 자동차를 하나의 객체로 생각합니다. 이 자동차 객체는 속성과 동작으로 이루어져 있습니다.
자동차의 속성은 색깔, 속도, 모델 등입니다. 이러한 속성은 변수로 표현할 수 있습니다. 예를 들어, "red"라는 값을 가지는 변수 color, "60"이라는 값을 가지는 변수 speed, "SUV"라는 값을 가지는 변수 model 등입니다.
또한, 자동차는 동작을 수행할 수 있습니다. 예를 들어, 가속, 감속, 정지 등의 동작을 할 수 있습니다. 이러한 동작은 함수 또는 메서드로 표현할 수 있습니다. 예를 들어, 자동차 객체의 메서드로 "가속하기", "감속하기", "정지하기"와 같은 동작을 정의할 수 있습니다.
이렇게 객체지향 프로그래밍에서는 자동차라는 개념을 자동차 객체로 표현하고, 그 객체는 속성과 동작을 가지며 이를 변수와 메서드로 표현합니다. 이렇게 객체들을 조합하여 프로그램을 만들면, 현실 세계의 개념과 유사하고 이해하기 쉬운 코드를 작성할 수 있습니다.
또한, 객체지향 프로그래밍은 코드의 재사용성과 유지보수성을 높일 수 있습니다. 예를 들어, 자동차 객체를 만들어놓으면 다른 부분에서도 자동차 객체를 활용하여 코드를 작성할 수 있습니다. 이렇게 객체를 재사용함으로써 코드를 간결하게 유지할 수 있습니다.
간단히 말하면, 객체지향 프로그래밍은 일상 생활의 개념을 객체로 표현하여 프로그램을 작성하는 방법이며, 이를 통해 코드의 이해도와 재사용성을 높일 수 있습니다.
절차/객체 비교
절차지향 프로그래밍:
절차지향 프로그래밍은 프로세스를 단계별로 나누고, 각 단계에서 필요한 데이터를 처리하는 방식입니다.
프로세스를 중심으로 프로그램을 작성하며, 데이터와 처리 로직을 분리하여 작성합니다.
대표적인 예로 C 언어가 있습니다.
프로시저(함수)를 중심으로 프로그램을 구성하며, 전역 변수를 사용하여 데이터를 공유합니다.
코드의 순차적인 흐름과 제어 구조가 중요합니다.
객체지향 프로그래밍:
객체지향 프로그래밍은 현실 세계의 개체(Object)를 모델링하여 프로그램을 작성하는 방식입니다.
객체들 간의 상호작용에 초점을 맞추고, 데이터와 해당 데이터를 처리하는 함수(메서드)를 하나의 단위로 묶어서 사용합니다.
대표적인 예로 Java, Python, C++ 등이 있습니다.
객체를 중심으로 프로그램을 구성하며, 객체 간의 메시지 전달을 통해 상호작용합니다.
캡슐화, 상속, 다형성 등의 개념을 활용하여 유연하고 재사용 가능한 코드를 작성할 수 있습니다.
절차지향과 객체지향의 가장 큰 차이는 프로그램의 구조와 설계 방식에 있습니다. 절차지향은 프로세스를 중심으로 데이터와 처리 로직을 분리하여 작성하는 반면, 객체지향은 객체들의 상호작용에 초점을 맞추고 데이터와 관련 메서드를 하나의 단위로 묶어서 사용합니다.
객체지향은 코드의 재사용성과 유지보수성이 높으며, 현실 세계의 개념을 모델링하여 프로그램을 작성할 수 있습니다. 절차지향은 단순하고 직관적인 프로그램을 작성할 수 있으며, 처리 흐름과 제어 구조가 중요시됩니다.
이는 큰 프로젝트나 복잡한 시스템을 개발할 때 객체지향이 유리하며, 작은 규모의 간단한 프로그램을 개발할 때는 절차지향이 적합할 수 있습니다.
절차지향과 객체지향의 차이를 예시를 통해 살펴보겠습니다.
절차지향 예시:
절차지향 방식으로 프로그램을 작성할 때, 예를 들어 "학생의 성적을 계산하는 프로그램"을 작성한다고 가정해봅시다.
데이터: 학생의 이름, 국어 점수, 영어 점수, 수학 점수
처리 로직: 각 과목별 점수를 합산하여 총점과 평균을 계산하는 과정
이 경우, 프로세스를 중심으로 다음과 같이 프로그램을 작성할 수 있습니다.
데이터를 입력받는다.
입력받은 데이터를 바탕으로 각 과목별 점수를 합산한다.
총점과 평균을 계산한다.
계산된 결과를 출력한다.
이처럼 절차적인 단계를 따라가며 데이터를 처리하는 방식이 절차지향 프로그래밍의 특징입니다.
객체지향 예시:
객체지향 방식으로 위의 예시를 작성한다면, 다음과 같이 객체와 메서드로 구성된 프로그램을 작성할 수 있습니다.
객체: 학생(Student) 객체
메서드: 점수 입력(inputScores()), 총점 계산(calculateTotal()), 평균 계산(calculateAverage()), 결과 출력(printResult())
이 경우, 학생 객체를 생성하고 메서드를 호출하여 다음과 같이 프로그램을 작성할 수 있습니다.
학생 객체를 생성한다.
inputScores() 메서드를 호출하여 데이터를 입력받는다.
calculateTotal() 메서드를 호출하여 총점을 계산한다.
calculateAverage() 메서드를 호출하여 평균을 계산한다.
printResult() 메서드를 호출하여 결과를 출력한다.
객체지향 프로그래밍은 데이터와 해당 데이터를 처리하는 메서드를 하나의 단위로 묶어서 사용하며, 객체들 간의 상호작용을 중심으로 프로그램을 작성하는 방식입니다.
이렇게 예시를 통해 구체적으로 설명드린 것이 절차지향과 객체지향의 차이입니다. 객체지향은 객체들 간의 상호작용을 중심으로 프로그램을 작성하며, 데이터와 처리 로직을 하나의 단위로 묶어 유연하고 재사용 가능한 코드를 작성할 수 있습니다.
인터페이스
인터페이스는 일종의 계약(Contract)으로, 클래스가 어떤 메서드를 가져야 하는지를 정의합니다. 즉, 인터페이스는 메서드의 집합으로 이루어져 있으며, 해당 인터페이스를 구현하는 클래스는 반드시 인터페이스에서 정의한 메서드를 구현해야 합니다.
인터페이스는 객체의 속성(Attribute)을 정의하는 것이 아니라, 객체의 동작(메서드)을 정의하는 역할을 합니다. 객체의 속성은 클래스 내에 변수(멤버 변수)로 정의되는 반면, 인터페이스는 메서드의 형식만을 정의합니다.
인터페이스는 객체가 가져야 하는 동작의 명세를 제공하여, 해당 인터페이스를 구현하는 클래스가 동일한 동작을 수행할 수 있도록 합니다. 이러한 동작은 메서드로 표현되며, 인터페이스는 이러한 메서드들의 집합입니다.
따라서, 인터페이스는 객체의 동작을 추상화하고, 다양한 클래스가 동일한 동작을 수행하도록 규정하는 역할을 합니다. 객체의 속성(멤버 변수)을 정의하기 위해서는 클래스를 사용하고, 객체의 동작(메서드)을 정의하기 위해서는 인터페이스를 사용합니다.
요약하자면, 인터페이스는 객체의 동작(메서드)을 추상화하여 정의하는 역할을 하며, 객체의 속성(멤버 변수)을 정의하기 위해서는 클래스를 사용합니다.
마우스로 클릭하는 것도 인터페이스에 해당합니다. 인터페이스는 사용자와 컴퓨터 또는 기기 사이의 상호작용을 가능하게 하는 수단이나 방법을 의미합니다. 마우스는 컴퓨터와 사용자 사이의 인터페이스 역할을 수행하는 입력 장치 중 하나로, 사용자가 컴퓨터에게 명령을 전달하거나 조작을 할 수 있도록 도와줍니다. 마우스로 클릭하는 동작은 사용자가 컴퓨터에게 특정 명령을 전달하는 방식 중 하나입니다. 사용자가 마우스를 클릭하면 컴퓨터는 해당 클릭 동작을 감지하고, 클릭된 위치나 클릭 종류에 따라 다양한 동작을 수행할 수 있습니다. 예를 들어, 마우스로 클릭하여 파일을 열거나 앱을 실행하는 등의 동작을 수행할 수 있습니다. 따라서 마우스 클릭은 사용자와 컴퓨터 간의 인터페이스 동작으로 볼 수 있으며, 사용자가 컴퓨터에게 명령을 전달하는 중요한 수단 중 하나입니다.
.java와 .class 차이

annotation

자바에서의 컴파일 시간 vs 실행시간

그러니까 내 생각에는 컴파일 시간 - 자바가 우리 가 적은 코드 기계어로 해석하는 시간
실행시간-기계어로 해석된 게 jvm에서 진짜 실행되는 시간.
+) 그래서 오버로딩은 컴파일 시간에서 다형성 지원
오버라이딩은 실행시간에서의 다형성 지원(pg 242참)
생성자와 일반 메소드 차이





위에는 일반 메소드,. (반환을 해주니까)
public string tostring()




즉, 원하는 거 한 번에 쉽게 출력해주는 기능 같음.
알고리즘과 코딩의 차이

동적바인딩, 정적 바인딩
정적 바인딩(Static Binding)은 컴파일 시간에 메서드나 변수의 바인딩이 결정되는 것을 말합니다. 컴파일러는 변수의 타입을 기반으로 어떤 메서드를 호출할지를 결정합니다.
정적 바인딩은 주로 정적 메서드(static method)와 인스턴스 변수가 포함된 클래스의 메서드를 호출할 때 사용됩니다. 정적 메서드는 클래스 수준에서 정의되며, 인스턴스 변수에 접근할 수 없습니다. 따라서 정적 메서드는 컴파일 시간에 호출될 메서드가 결정되므로 정적 바인딩을 사용합니다.
예를 들어, 다음과 같은 코드가 있다고 가정해봅시다:
```java
public class MyClass {
public static void staticMethod() {
System.out.println("정적 메서드 호출");
}
public void instanceMethod() {
System.out.println("인스턴스 메서드 호출");
}
}
public class Main {
public static void main(String[] args) {
MyClass.staticMethod(); // 정적 메서드 호출 (정적 바인딩)
MyClass obj = new MyClass();
obj.instanceMethod(); // 인스턴스 메서드 호출 (동적 바인딩)
}
}
```
위의 예시에서 `MyClass`의 `staticMethod()`는 정적 메서드이므로 정적 바인딩이 발생합니다. 컴파일 시간에 `MyClass.staticMethod()`로 호출될 메서드가 결정되기 때문입니다.
반면에 `obj.instanceMethod()`은 인스턴스 메서드이므로 동적 바인딩이 발생합니다. 인스턴스화된 객체의 타입에 따라 호출될 메서드가 결정되기 때문입니다.
요약하자면, 정적 바인딩은 컴파일 시간에 호출될 메서드가 결정되는 것을 의미하며, 주로 정적 메서드에 적용됩니다.
Share article