본문 바로가기

개발 일지/TIL

[ #9 ] TIL

✏️ 0425      


[ 특강 ] 알고리즘 세션 1

코딩테스트 연습 문제

Java 문법 종합반 강의_3주차


알고리즘 세션 1

    내가 아는 알고리즘은... 유튜브 알고리즘....?

 

자료 구조와 알고리즘은 서로 뗄 수 없는 관계!

그렇기에 알고리즘에 적절한 자료 저장법을 선택해야 한다

자료 구조에 대해 먼저 학습하고 알고리즘을 보면 훨씬 좋다

 

 

알고리즘
어떤 작업을 수행하기 위해 입력을 받아서 원하는 출력을 만들어내는 과정

 

자료 구조
데이터 값의 모임, 데이터 간의 관계, 데이터에 적용 할 수 있는 함수나 명령을 의미
어떤 자료 구조를 선택하느냐에 따라 효율적인 알고리즘 사용이 가능

 

 

프로그램은 알고리즘을 컴퓨터가 이해하고 실행할 수 있는 특정 프로그래밍 언어로 표현한 것

 

프로그램 = 알고리즘 + 자료구조

 

라는 말이 되겠다

 

  • 알고리즘의 필요성
    • 복잡한 문제를 효율적, 효과적으로 해결
    • 문제 풀이의 과정을 더 안전하고, 빠르고, 수행하기 쉽도록 도와준다 (메모리 절약, 시간 단축)
    • 알고리즘 풀이를 코딩 테스트에 이용하는 경우가 많다
    • 알고리즘 풀이 사이트 또는 대회를 이용해서 자신의 점수를 올려 어필 가능
  • 활용 예시 
    • 포털 사이트의 검색 기능
    • 데이터베이스의 조회 쿼리
    • 데이터 정렬
    • 운영 체제의 메모리 관리
    • 가장 빠른 길 찾기

게임 매칭 시스템도 알고리즘으로 구현되어 있다고 한다 (와웅)

 

 

  • 자료구조의 필요성
    • 효율적인 데이터 관리 : 효율적인 저장과 검색을 가능하기 하여 처리 시간 단축, 성능 향상
    • 데이터 조작 : 데이터가 논리적으로 구성되어 접근하기 쉬워진다
    • 데이터 추상화 : 구현 세부 정보를 숨기고 조작의 논리적 측면에 집중할 수 있도록 도와준다
    • 재사용성 : 여러 응용 프로그램에서 재사용할 수 있어서 개발 시간과 노력 절약
    • 알고리즘 최적화 : 적절한 데이터 구조는 알고리즘의 효율성에 상당한 영향을 줄 수 있다
    • 라이브 코딩 테스트 : 면접에서 구현해보라고 시켜볼 때 당황하지 않고 해결 가능성 향상
  • 자료 구조의 형태
    • 배열 (Array)
    • 연결 리스트 (Linked list) : 각 노드가 다음 순서의 노드를 연결한 형태
    • 해시 테이블 (Hash table) : 해시 함수 사용, 키와 인덱스
    • 그래프 (Graph) : 각 노드들이 그물망처럼 간선으로 연결된 형태
    • 스택 (Stack) : 마지막으로 입력한 값이 제일 먼저 출력되는 형태
    • 큐 (Queue) : 제일 먼저 입력한 값이 가장 먼저 출력되는 형태
    • 트리 (Tree) : 각 노드가 부모-자식 관계처럼 간선으로 연결된 형태, 같은 부모를 갖는 노드는 형제 관계, 또 다른 작은 형태의 트리인 서브트리도 가질 수 있다

 


 

코딩테스트 연습

 

앞으로 매일 오전 9시 ~ 10시까지 코딩 테스트 연습문제를 풀고 제출하게 되었다

 

이렇게 하루에 꼭 해야하는 루틴은

알고리즘 문제, SQL 문제, TIL 3가지가 되겠다

 

데일리 루틴 리스트에 다같이 기록이 되고 눈에 보여서 상당히.. 뭐랄까

열심히 해야겠다는 생각이 든다

오늘 TIL 작성 안하신 분 화려하게 당첨된 걸 보고.....

 

하루에 빠짐없이 꼭 하도록 노력하기

 

알고리즘과 SQL 문제를 푼 내용에 대한 것은

따로 카테고리를 추가해서 정리해보려고 한다

 

 


 

Java 문법 종합반_3주차

    이상하다... 강의가 분명 10~20분정도인데 왜 1시간 넘게 지나있지??

 

인스턴스 멤버와 클래스 멤버

클래스를 구성하는 요소는 필드, 생성자, 메서드가 있는데

그중에 필드와 메서드를 모아서 멤버라고 한다

 

필드 = 멤버 + 메서드

 

여태 강의 내에서 사용했던 멤버는 인스턴스 멤버이고

인스턴스 멤버와 클래스 멤버는 필드와 메서드의 선언하는 방법에 따라 구분 가능하다

 

 

인스턴스 멤버

객체의 인스턴스 필드는 각각의 인스턴스마다 고유한 값을 가질 수 있다

=> 독집적으로 별도의 멤버를 가질 수 있다

 

객체가 인스턴스할 때마다 객체의 메서드들은 매번 인스턴스에 포함되어 생성되나?

놉❌

 

매번 저장한다면 중복 저장으로 메모리 효율이 매우 떨어지기 때문에

메서드는 메서드 영역에 두고서 모든 인스턴스를 공유해서 사용한다

대신 객체를 생성, 인스턴스를 통해서 메서드를 사용될 수 있도록 제한 걸어둔 것이다

 

생성과 사용을 분리해서 생각하면 좋다

 

 

클래스 멤버

클래스는 Java의 클래스 로더에 의해 메서드 영역에 저장되고 사용된다

이때 클래스 멤버는 메서드 영역의 클래스와 같은 위치고 고정적으로 위치하고 있는 멤버

그렇기에 클래스 멤버는 객체의 생성 필요 없이 바로 사용이 가능하다

Car car = new Car();  // 객체 생성 필요없음

 

공용적인 데이터를 저장할 때 사용

어떤 클래스가 고유값을 가질 때, 변하지 않을 때, 인스턴스 필드를 사용하지 않고 실행되는 메서드가 존재할 때

static 키워드를 사용해서 클래스 멤버로 선언하는 것이 좋다

 

public class Car {
    static String company = "GENESIS"; // 자동차 회사 : GENESIS
    String model; // 자동차 모델

        // 이하 생략

    static String setCompany(String companyName) {
        // System.out.println("자동차 모델 확인: " + model); // 인스턴스 필드 사용 불가
        company = companyName;
        return company;
    }
}

클래스 필드와 클래스 메서드

 

// 클래스 필드 company 확인
System.out.println(Car.company + "\n");  // GENESIS
// 클래스 필드 변경 및 확인
Car.company = "Audi";
System.out.println(Car.company + "\n");  // Audi

// 클래스 메서드 호출
String companyName = Car.setCompany("Benz");
System.out.println("companyName = " + companyName); // Benz

 

클래스 멤버는 이처럼 객체 생성 없이 바로 사용 가능한 모습을 볼 수 있다

 

// 참조형 변수 사용
Car car = new Car(); // 객체 생성

car.company = "Ferrari";
System.out.println(car.company + "\n");  // Ferrari

String companyName2 = car.setCompany("Lamborghini");
System.out.println("companyName2 = " + companyName2);  // Lamborghini

 

참조형 변수를 사용해서 클래스 멤버에 접근은 가능하지만 추천하지 않고

클래스 이름으로 접근하는 것이 좋다

 

static String setCompany(String companyName) {
    // System.out.println("자동차 모델 확인: " + model); // 인스턴스 사용 불가
    company = companyName;
    return company;
}

 

사용 시, 주의할 점

클래스 멤버로 선언된 메서드는 인스턴스 멤버를 사용할 수 없다

인스턴스 멤버로 선언된 메서드는 클래스 멤버를 사용할 수 있다

클래스 멤버는 객체 생성 없이 바로 사용이 가능하므로

위의 model 처럼 객체가 생성되어야 존재할 수 있는 인스턴스 멤버를 사용할 수 없다

 

 

지역변수 및 상수

 

  • 지역변수
    • 메서드 내부에서 선언한 변수를 의미

반되대는 의미를 가진

전역변수는 어떤 변수 영역 내에서도 접근할 수 있는 변수를 의미

 

지역변수는 해당 메서드가 실행할 때마다 독립적인 값을 지정하고 관리하며

위에서 말했듯이 메서드 내부에서 정의될 때 생성된다

지역변수의 특징 중 하나는 해당 메서드가 종료되면 소멸, 초기화 된다

 

public class Main {
    public static void main(String[] args) {
        // 해당 코드가 실행되는 이유
        // public Main() {} => 기본 생성자가 내부에 존재하고 있다 => 생략가능
        Main main = new Main();
        System.out.println(main.getNumber());  // 2
        System.out.println(main.getNumber());  // 2
    }

    // 메서드 선언
    public int getNumber() {
        int number = 1;
        number += 1;
        return number;
    }
}

 

출력을 이어서 두번 진행했지만 동일한 값이 출력되는 것이 확인가능하다

=> 지역변수가 메서드가 종료되는 동시에 초기화 되었기 때문

 

 

  • 상수
    • 불변의 값

이전 강의에서 비슷한 걸 배운 적이 있다

 

final 필드!

최종적 이라는 의미이며

초기값이 저장되면 해당값을 프로그램이 실행하는 도중에는 절대 수정할 수 없다

그렇기에 반드시 초기값을 지정해야 한다

 

주로 static final 로 사용하며

공용적으로 쓰는 불변의 값이다

인스턴스마다 상수를 저장할 필요가 없다

 

static final String COMPANY = "GENESIS";

 

대부분의 변수 이름을 지정할 때는 카멜 표기법(Camel Case)을 사용하지만

상수의 경우, 오로지 대문자로 이루어진 이름으로 사용한다고 한다

 

 

생성자

 

생성자 ( Constructor )
객체가 생성될 때 호출되며 객체가 초기화 하는 역할을 수행

 

 

public Car() {} // 선언
Car car = new Car(); // 호출

 

기본 생성자는 선언할 때 괄호( ) 안에 아무것도 넣지 않는 생성자를 의미
모든 클래스는 반드시 생성자가 하나 이상 존재한다

 

 

ublic Car(String modelName, String colorName, double priceValue) {
    model = modelName;
    color = colorName;
    price = priceValue;
}
Car car = new Car(); // 오류 발생
  • 필드 초기화
    객체를 만들 때 인스턴스마다 다른 데이터를 가지는 필드는 생성자를 통해서 초기화하는 것이 좋다
    반대로 인스턴스마다 동일한 데이터를 가지는 필드는 초기값을 대입하는 것이 좋다
  • 주의할 점
    생성자를 통해 필드 값을 초기화하고 기본 생성자를 작성하지 않았는데
    기본 생성자를 호출한다면 오류가 발생한다

 

  • 생성자 오버로딩

오버로딩을 생성자에도 적용할 수 있지만

public Car(String modelName, String colorName, double priceValue)
public Car(String colorName, String modelName, double priceValue)

 

이름의 순서만 바뀌고 매개변수의 개수, 타입, 순서가 동일하면

이름이 달라도 오버로딩 되지 않고 오류가 발생한다 (주의)

 

 

this &  this()

 

this
자기 자신의 인스턴스

 

객체 내부 생성자 및 메서드에서 객체 내부 멤버에 접근하기 위해 사용될 수 있다

// (1)
public Car(String model, String color, double price) {
    model = model;
    color = color;
    price = price;
}
// (2)
public Car(String model, String color, double price) {
    this.model = model;
    this.color = color;
    this.price = price;
}

 

(1) 의 경우

생성자를 선언할때 매개변수와 필드명이 동일할 경우, 오류가 발생하진 않지만
자기 자신에게 값을 대입하는 상황이 되어버린다

 

그렇기에 (2) 처럼 this 키워드를 통해

변수명에 해당하는 객체의 필드에 접근하여 받아온 매개변수의 값을 객체의 필드에 대입하여 저장할 수 있다

 

Car returnInstance() {
    return this;
}

 

객체의 메서드에 리턴 타입이 인스턴스 자신의 클래스 타입이라면

return this를 사용하여 인스턴스 자신의 주소를 반환할 수 있다

 

 

this()
this 의 생성자
인스턴스 자신의 생성자를 호출

 

 

생성자 오버로딩을 사용할때 객체의 필드를 초기화하는 코드의 중복을 줄여줄 수 있다

public Car(String model) {
    this(model, "Blue", 50000000);
}

public Car(String model, String color) {
    this(model, color, 100000000);
}

public Car(String model, String color, double price) {
    this.model = model;
    this.color = color;
    this.price = price;
}

 

 

사용 시, 주의할 점
this() 키워드를 사용해서 다른 생성자를 호출할 때는 반드시 해당 생성자의 첫 줄에 작성되어야 한다

public Car(String model) {
    System.out.println("model = " + model);
    this(model, "Blue", 50000000);
}

 

this() 키워드로 다른 생성자를 호출 이전에 코드가 존재한다면 오류가 발생한다

 

 

접근 제어자

 

제어자
클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여

 

 

접근 제어자 public, protected, default, private
그 외 제어자 static, final, abstract

 

하나의 대상에 여러 개의 제어자를 조합해서 사용할 수 있으나, 접근 제어자는 단 하나만 사용할 수 있다

 

 

  • 접근 제어자
    멤버 또는 클래스에 사용, 외부에서 접근하지 못하도록 제한
    클래스, 멤버 변수, 메서드, 생성자에 사용되고, 지정되어 있지 않다면 default
public 접근 제한이 없다
protected 같은 패키지 내에서,
다른 패키지의 자손 클래스에서 접근 가능
default 같은 패키지 내에서만 접근 가능
private 같은 클래스 내에서만 접근 가능

 

  • 사용 가능한 접근 제어자
클래스 public, default
메서드 & 멤버 변수 public, protected, default, private
지역변수 ✖️

 

  • 접근 제어자를 이용한 캡슐화 (은닉성)
    클래스 내부에 선언된 데이터를 보호하기 위해서 사용
    유효한 값을 유지하도록, 함부로 변경하지 못하도록 접근을 제한하는 것이 필요
  • 생성자의 접근 제어자
    인스턴스의 생성을 제한할 수 있다
    일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자와 일치

 

  • 그 외 제어자
    • static, final, abstract

하나의 대상에 여러 개의 제어자를 조합해서 사용할 수 있으나, 접근 제어자는 단 하나만 사용할 수 있다

 

 

⭐ Getter & Setter

 

객체의 무결성, 변경이 없는 상태를 유지하기 위해 접근 제어자를 사용

직접적인 값의 조회, 세팅을 방지하기 위해

 

  • Getter
    • 외부에서 객체의 private 한 필드(클래스 내부에서만 읽을 수 있는 필드)를 읽을 필요가 있을 때
    • 메서드 이름의 규칙 : get + 필드 이름(첫 글자 대문자)
    • 사용 방법 : 인스턴스 메서드 호출과 동일
  • Setter
    • 외부에서 객체의 private 한 필드를 저장/수정할 필요가 있을 때
    • 메서드 이름 규칙과 사용 방법은 Getter 과 동일

⭐⭐⭐  Getter & Setter 는 반드시 한 번 더 보고 넘어가기 ⭐⭐⭐

 

 

  • 제어자의 조합
    사용 가능한 제어자
클래스 public, default, final, abstract
메서드 public, protected, default, private, final, abstract, static
멤버 변수 public, protected, default, private, final, static
지역변수 final

 

  • 제어자 사용 시 주의 사항
    • 메서드에 static 과 abstract 를 함께 사용할 수 없다
    • 클래스에 abstract 와 final 을 동시에 사용할 수 없다
    • abstract 메서드의 접근 제어자가 private 일 수 없다
    • 메서드에 private 와 final 을 같이 사용할 필요는 없다

 

import & package

 

 

package
클래스의 일부분이면서 클래스를 식별해 주는 용도
하위 패키지를 도트(.)로 구분

 

 

  • 접근 방법
// 전체 경로를 명시해서 클래스에 접근하는 방법
week03.packageExample.pk1.Car car1 = new week03.packageExample.pk1.Car();
week03.packageExample.pk2.Car car2 = new week03.packageExample.pk2.Car();
import week03.packageExample.pk1.Car;

public class Main {
    public static void main(String[] args) {
        // import 해서 클래스에서 접근하는 방법
        Car car1 = new Car();
        car1.horn();
    }
}

 

다른 패키지에 있는 같은 이름의 클래스를 import 으로 둘 다 가져오면 충돌이 일어난다

동일한 이름을 가진 두 개의 클래스를 인식할 때, 어떤 클래스를 사용해야 할지 혼동이 생기기 때문

둘 중 하나 선택하라고 한다

 

import week03.packageExample.pk1.Car;

Car car1 = new Car();
week03.packageExample.pk2.Car car2 = new week03.packageExample.pk2.Car();

 

하지만 요러케 하나는 import 로 불러오고, 다른 하나는 경로를 적어서 불러오면 가능하긴 하다

근데 다른 패키지에 같은 이름으로 존재하는 파일을 만들까..? 싶긴 하다

나도 헷갈리고.. 프로그램도 헷갈리고..

 

 

후기

 

강의... 어렵다

근데 강의보다 오늘 들은 알고리즘이 더 어려웠던 것 같기도?

 

이해 안되면 계속 돌려보고 돌려보고 돌려보는 중인데 이게 맞나 싶기도 하다

처음 보다 진도 나가는 속도가 줄어들기도 했고 나만 이런 건지 모르겠다!

 

그치만 하나 하나 배워가는 건 너무 즐겁다 머리가 아프지만 😅

내일도 화이팅!

'개발 일지 > TIL' 카테고리의 다른 글

[ #11 ] TIL  (0) 2024.04.30
[ #10 ] TIL  (0) 2024.04.27
[ #8 ] TIL  (0) 2024.04.24
[ #7 ] TIL  (2) 2024.04.23
[ #6 ] TIL  (0) 2024.04.22