반응형

7. 개발 언어(Java 위주)


[ C언어 포인터란? ]

포인터는 어떤 변수의 주소값을 저장하는 변수입니다. 포인터의 선언은 변수명 앞에 *을 붙이면 가능하고, 어떤 변수의 주소값을 얻기 위해서는 &를 붙이면 됩니다.

#include <stdio.h>

int main() {
    int* p = NULL;
    int num = 10;
    
    p = &num;
    printf("포인터 p의 값: %d \n", p);
    printf("num의 주소: %d \n", &num);
	
    return 0;
}

 

[ Java의 장점과 단점 ]

  • 장점
    • JVM 위에서 동작하기 때문에 운영체제에 독립적이다.
    • 가비지컬렉터가 메모리를 관리해주기 때문에 편리하다.
  • 단점
    • JVM 위에서 동작하기 때문에 실행 속도가 상대적으로 느리다.
    • 다중 상속이나 타입에 업격하는 등 제약이 있는 것이 많다.

 

[ 오버라이딩(Overriding)과 오버로딩(Overloading) ]

 

  • 오버라이딩(Overriding): 상위 클래스가 가지고 있는 메소드를 하위 클래스에서 재정의하여 사용하는 기술
  • 오버로딩(Overloading): 매개변수의 유형과 개수를 변경하면서 같은 이름의 메소드를 여러 개 사용하는 기술
public class Person {
    public void print() {
    	System.out.println("나는 사람입니다");
    }
}

public class Student extends Person {
    // Overriding
    public void print() {
    	System.out.println("나는 학생입니다.");
    }
    
    // Overloading
    public void print(String name) {
    	System.out.println(name + "는 학생입니다");
    }
}

 

 

[ 클래스(Class), 객체(Object), 인스턴스(Instance)의 개념 ]

 

  • 클래스(Class): 객체를 만들어내기 위한 설계도 혹은 틀
  • 객체(Object): 설계도(클래스)를 기반으로 선언된 대상, 클래스의 인스턴스라고도 부름
  • 인스턴스(Instance): 객체에 메모리가 할당되어 실제로 활용되는 실체
// 클래스
public class Person {
    private String name;
}

public class Main {

    public static void main(String[] args) {
        // 객체 = 클래스의 인스턴스
        Person person;
        
        // 인스턴스
        person = new Person();
    }
    
}

 

 

[ 싱글톤 패턴(Singleton Pattern) 구현 및 사용 이유 ]

public class Person {

    private static Person instance;
    
    public static Person getInstance() {
        if(instance == null){
            instance = new Person();
        }
        return instance;
    }
}

 

싱글톤 패턴은 단 하나의 인스턴스를 생성하여 사용하는 디자인패턴입니다. 싱글톤패턴은 아래의 경우에 사용합니다.

  • 해당 인스턴스가 절대적으로 1개만 존재한다는 것을 보증하고 싶은 경우
  • 동일한 인스턴스를 자주 생성해주어야 하는 경우(메모리 낭비의 방지)

하지만 이러한 싱글톤 패턴은 객체 지향 설계의 원칙에 적합하지 않으며, LifeCycle 제어가 힘들고, 멀티스레드 환경에서 여러 개의 객체가 생성되는 문제가 발생할 수 있습니다. 그러한 이유로 멀티스레드 환경이라면 static 앞에 synchronized 키워드를 붙여 동기화 작업을 추가해주어야 합니다.(당연히 성능이 저하됩니다).

 

[ 추상클래스와 인터페이스의 차이 ]

 

  • 추상클래스
    • 단일 상속만이 가능하다.
    • 모든 접근 제어자를 사용할 수 있다.
    • 변수와 상수를 선언할 수 있다.
    • 추상 메소드와 일반 메소드를 선언할 수 있다.
  • 인터페이스
    • 다중 구현이 가능하다.
    • public 접근 제어자만 사용할 수 있다.
    • 상수만 선언할 수 있다.
    • 추상메소드만 선언할 수 있다.

 

 

[ Java의 List, Set, Map 차이 ]

  • List
    • 데이터를 순차적으로 저장한다.
    • 데이터의 중복을 허용한다. 
    • 데이터로 null을 허용한다.
  • Set
    • 순서없이 Key로만 데이터를 저장한다.
    • Key의 중복을 허용하지 않는다.
    • Key로 null을 허용하지 않는다.
  • Map
    • 순서없이 Key, Value로 데이터를 저장한다.
    • Value는 중복을 허용하지만 Key의 중복을 허용하지 않는다.
    • Key로 null을 허용하지 않는다.

 

[ Java의 Vector와 ArrayList 차이 ]

  • Vector
    • 동기화를 지원한다.
    • 속도가 느리지만 병렬 상황에서 안전하다.
    • 크기가 증가하는 경우, 2배 증가함(10 -> 20)
  • ArrayList
    • 동기화를 지원하지 않는다.
    • 속도는 빠르지만 병렬 상황에서 안전하지 않다.
    • 크기가 증가하는 경우, 1.5배 증가함(10 -> 15)

 

 

[ synchornized란? ]

Java에서 지원하는 synchronized 키워드는 여러 쓰레드가 하나의 자원을 이용하고자 할 때, 한 스레드가 해당 자원을 사용중인 경우, 데이터에 접근할 수 없도록 막는 키워드입니다. synchronized 키워드를 이용하면 병렬 상황에서 자원의 접근을 안전하게 하지만, 자원을 이용하지 않는 쓰레드는 락에 의한 병목현상이 발생하게 됩니다.

  • 메소드 synchronized: 한 시점에 하나의 쓰레드만이 해당 메소드를 실행할 수 있다.
  • 변수 synchronized: 한시점에 하나의 쓰레드만이 해당 변수를 참조할 수 있다.

 

 

[ Java8 ]

Java8에서는 함수형 프로그래밍을 위한 stream API와 Lambda, 함수형 인터페이스 등과 Null-safe한 작업을 위한 Optional API, Date와 Time API 등이 추가되었습니다.

 

 

[ Stream API의 장점과 단점 ]

 

  • 장점
    • 코드를 간결하게 작성하여 가독성을 높일 수 있다.
    • 병렬스트림과 같은 기술을 이용하면 처리 속도를 많이 높일 수 있다.
  • 단점
    • 잘못 사용하면 기존의 Java 방식보다 오히려 성능이 떨어질 수 있다.
    • 코드들이 추상화되어 있어 실수가 발생할 수 있다.

 

 

[ 람다(Lambda)와 람다(Lambda)의 사용법 ]

람다는 불필요한 코드를 줄이고, 가독성을 높이기 위한 익명 함수로써, 함수의 이름과 반환타입 없이 손쉽게 함수를 선언할 수 있습니다. 람다는 아래와 같이 괄호와 화살표로 표현할 수 있으며, 람다의 반환값은 함수형 인터페이스이므로, 이를 이용해주어야 합니다.

@FunctionalInterface
interface MyFunctionalInterface {
    String test();
}

public class Lambda {

    public static void main(String[] args) throws Throwable {
        String str = "This is My String";
        
        // Labmda Expression
        MyFunctionalInterface fi = () -> str.replaceAll("\\s+", "");
        System.out.println(fi.test());
    }

}

 

Java8의 Stream API를 이용하면서 람다를 사용해 본 경험이 있습니다.

public static String quiz2() {
    String result = Stream.of("TONY", "a", "hULK", "B", "america", "X", "nebula", "Korea")
            .filter(w -> w.length() > 1)
            .map(String::toUpperCase)
            .map(w -> w.substring(0, 1))
            .collect(Collectors.joining(" "));
            
    return result;
}

 

 

[ Java의 동작 과정 ]

  1. Java 소스 파일을 javac로 컴파일하여 class파일(Java 바이트 코드)을 생성함
  2. 클래스로더가 컴파일된 Java 바이트 코드를 런타임 데이터 영역(Runtime Data Areas)로 로드함
  3. 실행 엔진(Execution Engine)이 자바 바이트코드를 실행함

 

 

[ JVM의 구조 ]

JVM의 구조 중 메모리 구조는 다음과 같이 구성됩니다.

  • Method Area(메소드 영역): 클래스 변수의 이름, 타입, 접근 제어자 등과 같은 클래스와 관련된 정보를 저장한다. 그 외에도 static 변수, 인터페이스 등이 저장된다.
  • Heap Area(힙 영역): new를 통해 생성된 객체와 배열의 인스턴스를 저장하는 곳이다. 가비지 컬렉터는 힙 영역을 청소하며 메모리를 확보한다.
  • Stack Area(스택 영역): 메소드가 실행되면 스택 영역에 메소드에 대한 영역이 1개 생긴다. 이 영역에 지역변수, 매개변수, 리턴값 등이 저장된다.
  • PC register(PC 레지스터): 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장한다.(CPU의 레지스터와 다르다.)
  • Native Method Stack(네이티브 메소드 스택): 자바 외의 언어(C, C++ 등)로 작성된 코드를 위한 메모리 영역이다. JNI를 통해 사용된다.

 

 

[ 가비지 컬렉터(Garbage Collector)란? ]

'더이상 참조되지 않는 메모리'인 가비지를 청소해주는 JVM의 실행 엔진의 한 요소입니다. JVM은 new와 같은 연산에 의해 새롭게 생성된 객체들 중에서 더이상 참조되지 않는 객체를 정리해줍니다. 가비지 컬렉터는 Heap 영역을 위주로 탐색하며 메모리를 정리해줍니다.

 

[ 다형성과 캡슐화 ]

다형성(Polymorphism)

객체지향 기법에서 메시지에 의해 객체가 연산을 수행하게 될 때 하나의 메세지에 대해 객체가 가지고 있는 고유한 방법으로 응답할 수 있는 능력

캡슐화(encapsulation)

서로 관련성이 많은 데이터와 이에 관련된 함수 등을 한 묶음으로 처리하는 기법

 

  • [ JSON & XML ]
  • JSON은 종료 태그를 사용하지 않습니다.
  • JSON의 구문이 XML의 구문보다 더 짧습니다.
  • JSON 데이터가 XML 데이터보다 더 빨리 읽고 쓸 수있다.
  • XML은 배열을 사용할 수 없지만, JSON은 배열을 사용할 수 있습니다.
  • XML은 XML파서로 파싱되며, JSON은 자바스트립트 표준 함수인 eval()함수로 파싱됩니다.

 

 

반응형

+ Recent posts