키로거

in Algorithm, Greedy

백준 5397: 문제링크

  • 문제유형 :

  • 설명

    1. 스택을 두 개 생성하고, 스택 두 개의 중앙을 커서라고 생각한다.

    2. 문자 입력: 왼쪽 스택에 삽입

    3. ‘-‘ 입력 : 왼쪽 스택에서 삭제

    4. ‘<’ 입력 : 왼쪽 스택에서 오른쪽 스택으로 이동

    5. ‘>’ 입력 : 오른쪽 스택에서 왼쪽 스택으로 이동

  • 풀이

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    test_case = int(input())

    for _ in range(test_case):
    left_stack = []
    right_stack = []
    data = input()
    for i in data:
    if i == '-':
    if left_stack:
    left_stack.pop()
    elif i == '<':
    if left_stack:
    right_stack.append(left_stack.pop())
    elif i == '>':
    if right_stack:
    left_stack.append(right_stack.pop())
    else:
    left_stack.append(i)
    left_stack.extend(reversed(right_stack))
    print(''.join(left_stack))

Comment and share

백준 1874: 문제링크

  • 문제유형 : 큐, 구현, 그리디

  • 설명

    1. queue의 head의 값이 최대값과 동일한 지 확인한다.

    2. 동일하면 지정한 값과 동일한 지 확인한다.

      아니면 값을 queue의 tail로 보낸다

    3. 지정한 값과 동일하면 출력 아니면 값을 제거한다.

  • 풀이

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    test_case = int(input())

    for _ in range(test_case):
    n, m = list(map(int, input().split(' ')))
    queue = list(map(int, input().split(' '))
    queue = [(i, idx) for idx, i in enumerate(queue)]

    count = 0

    while True:
    if queue[0][0] == max(queue, key=lambda x : x[0])[0]:
    count += 1
    if queue[0][1] == m:
    print(count)
    break
    else:
    queue.pop(0)
    else:
    queue.append(queue.pop(0))

Comment and share

백준 1874: 문제링크

  • 문제유형 : 스택, 그리디

  • 설명

    1. 스택에 특정 수에 도달할 때까지 push한다.

    2. 스택이 특정 수에 도달하면 pop한다.

    3. 수의 배열을 완성하면 출력하고 불가능하면 NO를 출력한다

  • 풀이

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    n = int(input())

    count = 1
    stack = []
    result = []

    for i in range(1, n + 1): # 데이터 개수만큼 반복
    data = int(input())

    while count <= data: # 입력 받은 데이터에 도달할 때 까지 삽입
    stack.append(count)
    count += 1
    result.append('+')

    if stack[-1] == data: # 스택의 최상위 원소가 데이터와 같을 때 출력
    stack.pop()
    result.append('-')
    else: # 불가능한 경우
    print('NO')
    exit(0)

    print('\n'.join(result)) # 가능한 경우

Comment and share

백준 2789 : 문제링크

  • 문제유형 : 배열, 완전탐색

  • 설명

    1. 완전탐색으로 가능한 숫자 조합을 모두 구한다.

    2. 만들어진 조합의 합을 구한다.

    3. 합이 M을 넘지 않았을 때 최대값을 비교하여 갱신한다.

  • 풀이

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    n, m = list(map(int, input().split(' ')))
    data = list(map(int, input().split(' ')))

    result = 0
    length = len(data)

    count = 0
    for i in range(0, length):
    for j in range(i + 1, length):
    for k in range(j + 1, length):
    sum_value = data[i] + data[j] + data[j]
    if sum_value <= m:
    result = max(result, sum_value)

    print(result)

Comment and share

음계

in Algorithm

백준 2920 : 문제 링크

  • 문제 유형 : 배열, 구현

  • 설명

    1. 오름차순 변수 ascending, 내림차순 변수 descending 둘 다 True로 설정

    2. 한 문자라도 내림차순이면 ascending False

      한 문자라도 오름차순이면 descending False

    3. 둘 다 False이면 mixed

  • 풀이
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    a = list(map(int, input().split())

    ascending = True
    descending = True

    for i in range(1, 8):
    if a[i] > a[i-1]:
    descending = False
    elif a[i] < a[i-1]:
    ascending = False

    if ascending:
    print('ascending')
    elif descending:
    print('descending')
    else:
    print('mixed)

Comment and share

SELECT

정의 : 데이터를 검색할때 사용되는 문법

SELECT FROM

  • 기본 포멧

    SELECT <column_name_1>, <column_name_2>, ... FROM <table_name>

  • 전체 컬럼 데이터 조회

    1
    2
    sql> SELECT *
    FROM world.country
  • code, name 세개의 컬럼 데이터 조회

    1
    sql> SELECT code, name FROM world.country
  • 데이터 베이스 선택 : FROM 절에 world. 을 사용할 필요가 없다.

    1
    2
    sql> USE world;
    sql> SELECT * FROM country
  • alias : 컬럼의 이름을 변경할수 있습니다.

    1
    sql> SELECT code as country_code, name as country_name FROM country
  • 데이터 베이스, 테이블, 컬럼 리스트 확인

    1
    2
    3
    sql> SHOW DATABASES;
    sql> SHOW TABLES;
    sql> DESC city;

WHERE

특정 조건을 주어 데이터를 검색하는데 사용되는 문법

  • 비교연산 - 인구가 1억이 넘는 국가를 출력

    1
    SELECT * FROM country WHERE Population >= 100000000
  • 논리 연산 : AND, OR - 인구가 7000만에서 1억인 국가를 출력

    1
    2
    SELECT * FROM country
    WHERE Population >= 70000000 AND Population <= 100000000
  • 범위 연산 : BETWEEN

    • 인구가 7000만에서 1억인 국가를 출력

      1
      2
      SELECT * FROM country
      WHERE Population BETWEEN 70000000 AND 100000000
    • 아시아와 아프리카 대륙의 국가 데이터를 출력

      1
      2
      SELECT * FROM country
      WHERE Continent = "Asia" OR Continent = "Africa"
  • 특정 조건을 포함 : IN, NOT IN

    • 아시아와 아프리카 대륙의 국가 데이터를 출력

      1
      2
      SELECT * FROM country
      WHERE Continent IN ("Asia", "Africa")
    • 아시아와 아프리카 대륙의 국가가 아닌 데이터를 출력

      1
      2
      SELECT * FROM country
      WHERE Continent NOT IN ("Asia", "Africa")
    • 아시아와 아프리카 대륙의 국가가 아닌 데이터를 출력 (논리연산 사용)

      1
      2
      SELECT * FROM country
      WHERE Continent != "Asia" AND Continent != "Africa"
  • 특정 문자열이 포함된 데이터 출력 : LIKE

    • 정부형태에 Republic이 포함된 데이터 출력
      1
      2
      SELECT * FROM country
      WHERE GovernmentForm LIKE "%Republic%"

ORDER BY

특정 컬럼의 값으로 데이터 정렬에 사용되는 문법

  • 오름차순 인구순으로 국가의 리스트를 출력 (ASC는 생략이 가능)

    1
    SELECT * FROM country ORDER BY population ASC
  • 내림차수 인구순으로 국가의 리스트를 출력

    1
    SELECT * FROM country ORDER BY population DESC
  • 국가 코드를 알파벳 순으로 정렬하고 같은 국가 코드를 가지면 인구순으로 내림차순으로 정렬

    1
    SELECT * FROM city ORDER BY CountryCode ASC, Population DESC

LIMIT

LIMIT은 조회하는 데이터의 수를 제한할수 있습니다.

  • 인구가 많은 상위 5개 국가 데이터를 출력

    1
    SELECT * FROM country ORDER BY population DESC LIMIT 5
  • 인구가 많은 상위 6위 ~ 8위의 3개 국가 데이터를 출력

    1
    SELECT * FROM country ORDER BY population DESC LIMIT 5, 3

GRUOP BY, HAVING

GROUP BY는 여러개의 동일한 데이터를 가지는 특정 컬럼을 합쳐주는 역할을 하는 명령입니다.

SQL에는 아래와 같은 그룹함수가 있습니다.
COUNT, MAX, MIN, AVG, VAR_SAMP, STDDEV

  • COUNT

    • city 테이블의 CountryCode를 묶고 각 코드마다 몇개의 데이터가 있는지 확인
      1
      2
      sql> SELECT CountryCode, COUNT(CountryCode) FROM city
      GROUP BY CountryCode
    • countrylanguage 테이블에서 전체 언어가 몇개 있는지 구하시오.
      • DISTINCT 중복을 제거해주는 문법
        1
        2
        sql > SELECT COUNT(DISTINCT(Language)) as language_count
        FROM countrylanguage
  • MAX

    • 대륙별 인구수와 GNP 최대 값을 조회
      1
      2
      3
      4
      5
      6
      7
      8
              sql> SELECT continent, MAX(Population) as Population, MAX(GNP) as GNP
      FROM country GROUP BY continent
      ```
      - MIN
      - 대륙별 인구수와 GNP 최소 값을 조회 (GNP와 인구수가 0이 아닌 데이터 중에서)
      ```
      sql> SELECT continent, MIN(Population) as Population, MIN(GNP) as GNP FROM country
      WHERE GNP != 0 AND Population != 0 GROUP BY continent
  • SUM

    • 대륙별 총 인구수와 총 GNP
      1
      2
      3
      sql> SELECT continent, SUM(Population) as Population, SUM(GNP) as GNP
      FROM country
      WHERE GNP != 0 AND Population != 0 GROUP BY continent
  • AVG

    • 대륙별 평균 인구수와 평균 GNP 결과를 인구수로 내림차순 정렬
      1
      2
      3
      4
      sql> SELECT continent, AVG(Population) as Population, AVG(GNP) as GNP
      FROM country
      WHERE GNP != 0 AND Population != 0 GROUP BY continent
      ORDER BY Population DESC
  • HAVING

    GROUP BY에서 반환되는 결과에 조건을 줄수 있습니다.

    • 대륙별 전체인구를 구하고 5억이상인 대륙만 조회

      1
      2
      3
      sql> SELECT continent, SUM(Population) as Population FROM country
      GROUP BY continent
      HAVING Population > 500000000
    • 대륙별 평균 인구수, 평균 GNP, 1인당 GNP한 결과를 1인당 GNP가 0.01 이상인 데이터를 조회하고 1인당 GNP를 내림차순으로 정렬

      1
      2
      3
      4
      5
      sql> SELECT continent, AVG(Population) as Population, AVG(GNP) as GNP, AVG(GNP) / AVG(Population) * 1000 as AVG
      FROM country
      WHERE GNP != 0 AND Population != 0 GROUP BY continent
      HAVING AVG > 0.01
      ORDER BY AVG DESC
  • WITH ROLLUP

    • 고객과 스탭별 매출과 고객별 매출의 총합을 출력
      1
      2
      sql> SELECT customer_id, staff_id, SUM(amount) as amount FROM payment
      GROUP BY customer_id, staff_id WITH ROLLUP

Comment and share

데이터 베이스 모델링

개념적 모델링

업무분석해서 핵심 데이터의 집합을 정의하는 과정

논리적 모델링

개념적 모델링을 상세화 하는 과정

물리적 모델링

논리적 모델링을 DBMS에 추가하기 위해 구체화하는 과정

자료형, 키 값등 설정

Comment and share

MYSQL 설치 (AWS에서 작업)

  1. AWS EC2 인스턴스에 Ubuntu OS에 MySQL 5.7.x 버전 설치

  2. EC2 인스턴스 생성

    • t2.micro
    • Ubuntu 18.04 버전
    • 보안그룹에서 3306 포트 추가
  3. EC2 인스턴스에 접속

  4. pem 파일 400 권한으로 변경

    1
    $ ssh -i (PEM File location) ubuntu@(AWS Public IP)
  5. apt-get 업데이트

    1
    2
    $ sudo apt-get update -y 
    $ sudo apt-get upgrade -y
  6. MySQL Server 설치

    1
    $ sudo apt-get install -y mysql-server mysql-client
  7. MySQL secure 설정

    1
    2
    3
    4
    5
    6
    $ sudo mysql_secure_installation 
    Would you like to setup VALIDATE PASSWORD plugin? N
    New password: rada
    Re-enter new password: rada Remove anonymous users? Y
    Disallow root login remotely? N
    Remove test database and access to it? Reload privilege tables now? Y
  8. MySQL 패스워드 설정

    1
    2
    3
    4
    5
    6
    $ sudo mysql
    mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITHmysql_native_password BY 'rada';
    mysql> FLUSH PRIVILEGES;
    mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;
    mysql> exit
  9. 설정한 패스워드를 입력하여 접속

    1
    2
    $ mysql -u root -p  
    Enter password: rada
  10. 외부접속 설정

    1
    $ sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
    • bind-address를 127.0.0.1을 0.0.0.0 으로 변경

      bind-address = 0.0.0.0 (모든 IP에서 접속가능)

  11. 외부접속 패스워드 설정

    1
    mysql> grant all privileges on *.* to root@'%' identified by 'rada';
  12. 서버 시작 종료 상태 확인

    1
    2
    3
    4
    $ sudo systemctl start mysql.service
    $ sudo systemctl stop mysql.service
    $ sudo systemctl restart mysql.service
    $ sudo systemctl status mysql.service
  13. 설정 후 서버 재시작으로 설정 내용 적용

    1
    $ sudo systemctl restart mysql.service
  14. password 변경 : rada로 패스워드를 변경하는 경우

    1
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'rada';

샘플 데이터 추가 (Local에서 작업)

  1. 서버로 sql 파일을 전송

    1
    $ scp -i ~/.ssh/rada.pem ~/Desktop/sql/* ubuntu@15.164.231.87:~/
  2. 데이터 베이스 생성

    1
    2
    3
    4
    5
    $ mysql -u root -p
    sql> create database world;
    sql> create database sakila;
    sql> create database employees;
    sql> quit
  3. 데이터 베이스에 데이터 추가

    1
    2
    3
    4
    $ mysql -u root -p world < world.sql
    $ mysql -u root -p sakila < sakila-schema.sql
    $ mysql -u root -p sakila < sakila-data.sql
    $ mysql -u root -p employees < employees.sql

Mysql Workbench 사용법

Comment and share

Design Patterns

디자인 패턴이란

  • 자주 발생하는 문제를 해결하기 위해 설계된 재사용 가능한 해결책
    • Don’t reinvent the wheel
  • 소프트웨어 설계 문제를 쉽게 해결할 수 있도록 패턴화된 설계 방식
  • 팀원들이 공유할 수 있는 공통의 언어가 되어 소통을 원활하게 함

디자인 패턴의 구조

  • 문맥 (Context)
    • 패턴이 적용될 수 있는 문제 상황을 기술
  • 문제 (Problem)
    • 패턴이 적용되어 해결되어야 하는 여러 설계 이슈를 기술
  • 해결 (Solution)
    • 문제를 해결하는 설계 구성 요소와 구성 요소 사이의 관계를 기술

디자인 패턴의 종류

  • Gang of four 패턴

    • 생성 패턴 (Creational patterns)
      • 객체의 생성 방식에 관련된 패턴
      • Abstract Factory, Factory Method, Singleton …
    • 구조 패턴 (Structural patterns)
      • 클래스/객체를 조합한 구조를 가지는 패턴
      • Composite, Decorator …
    • 동작 패턴 (Behavioral patterns)
      • 클래스/객체 사이의 동작 분배에 관련된 패턴
      • Observer, State, Strategy, Template Method, Command …
  • 동시성 패턴 (Concurrency patterns)

    • Scheduling, Monitor, Lock …
  • 아키텍처 패턴 (Architecture patterns)

    • Model-View-Controller, Model-View-Presenter, Model-View-ViewModel …
  • 기타 패턴

    • Dependency injection, Lazy loading, Mock object …

대표적인 디자인 패턴

  • 싱글톤 패턴

    • 단 하나의 객체만 존재할 수 있는 클래스를 구현하는 패턴
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
    if(instance == null) {
    instance = new Singleton();
    }
    return instance;
    }
    }
  • 팩토리 패턴

    • 구상 클래스 객체를 전담하여 생성하는 클래스를 구현하는 패턴
    • 팩토리 메소드 패턴 (ref)

    img1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    interface Shape {
    void draw();
    }

    class Rectangle implements Shape {
    @Override
    public void draw() {
    System.out.println("Inside Rectangle::draw() method.");
    }
    }

    class Square implements Shape {
    @Override
    public void draw() {
    System.out.println("Inside Square::draw() method.");
    }
    }

    class Circle implements Shape {
    @Override
    public void draw() {
    System.out.println("Inside Circle::draw() method.");
    }
    }

    class ShapeFactory {


    Shape getShape(String shapeType){
    if(shapeType == null){
    return null;
    }
    if(shapeType.equalsIgnoreCase("CIRCLE")){
    return new Circle();

    } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
    return new Rectangle();

    } else if(shapeType.equalsIgnoreCase("SQUARE")){
    return new Square();
    }

    return null;
    }
    }
    class FactoryPatternDemo {
    public static void main(String[] args) {
    ShapeFactory shapeFactory = new ShapeFactory();

    Shape shape1 = shapeFactory.getShape("CIRCLE");
    shape1.draw();

    Shape shape2 = shapeFactory.getShape("RECTANGLE");

    shape2.draw();

    Shape shape3 = shapeFactory.getShape("SQUARE");

    shape3.draw();
    }
    }
    • 추상 팩토리 패턴 (ref)

    img2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    public interface Shape {
    void draw();
    }

    class RoundedRectangle implements Shape {
    @Override
    public void draw() {
    System.out.println("Inside RoundedRectangle::draw() method.");
    }
    }

    class RoundedSquare implements Shape {
    @Override
    public void draw() {
    System.out.println("Inside RoundedSquare::draw() method.");
    }
    }

    class Rectangle implements Shape {
    @Override
    public void draw() {
    System.out.println("Inside Rectangle::draw() method.");
    }
    }

    abstract class AbstractFactory {
    abstract Shape getShape(String shapeType) ;
    }

    class ShapeFactory extends AbstractFactory {
    @Override
    public Shape getShape(String shapeType){
    if(shapeType.equalsIgnoreCase("RECTANGLE")){
    return new Rectangle();
    }else if(shapeType.equalsIgnoreCase("SQUARE")){
    return new Square();
    }
    return null;
    }
    }

    class RoundedShapeFactory extends AbstractFactory {
    @Override
    public Shape getShape(String shapeType){
    if(shapeType.equalsIgnoreCase("RECTANGLE")){
    return new RoundedRectangle();
    }else if(shapeType.equalsIgnoreCase("SQUARE")){
    return new RoundedSquare();
    }
    return null;
    }
    }

    class FactoryProducer {
    public static AbstractFactory getFactory(boolean rounded){
    if(rounded){
    return new RoundedShapeFactory();
    }else{
    return new ShapeFactory();
    }
    }
    }

    class AbstractFactoryPatternDemo {
    public static void main(String[] args) {
    AbstractFactory shapeFactory = FactoryProducer.getFactory(false);

    Shape shape1 = shapeFactory.getShape("RECTANGLE");
    shape1.draw();
    Shape shape2 = shapeFactory.getShape("SQUARE");
    shape2.draw();

    AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);

    Shape shape3 = shapeFactory1.getShape("RECTANGLE");
    shape3.draw();
    Shape shape4 = shapeFactory1.getShape("SQUARE");
    shape4.draw();
    }
    }
  • 데코레이터 패턴

    • 생성자를 이용해 객체에 일정한 기능을 추가하는 패턴 (ref)

    img3

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    interface Shape {
    void draw();
    }

    class Rectangle implements Shape {

    @Override
    public void draw() {
    System.out.println("Shape: Rectangle");
    }
    }

    class Circle implements Shape {

    @Override
    public void draw() {
    System.out.println("Shape: Circle");
    }
    }

    abstract class ShapeDecorator implements Shape {
    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape){
    this.decoratedShape = decoratedShape;
    }

    public void draw(){
    decoratedShape.draw();
    }
    }

    class RedShapeDecorator extends ShapeDecorator {

    public RedShapeDecorator(Shape decoratedShape) {
    super(decoratedShape);
    }

    @Override
    public void draw() {
    decoratedShape.draw();
    setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape){
    System.out.println("Border Color: Red");
    }
    }

    class DecoratorPatternDemo {
    public static void main(String[] args) {

    Shape circle = new Circle();

    Shape redCircle = new RedShapeDecorator(new Circle());

    Shape redRectangle = new RedShapeDecorator(new Rectangle());
    System.out.println("Circle with normal border");
    circle.draw();

    System.out.println("\nCircle of red border");
    redCircle.draw();

    System.out.println("\nRectangle of red border");
    redRectangle.draw();
    }
    }
  • 옵저버 패턴

    • Observable 객체의 변화를 Observer에서 알 수 있도록 하는 패턴 ref

    img4

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    class Subject {
    private List<Observer> observers = new ArrayList<Observer>();
    private int state;

    public int getState() {
    return state;
    }

    public void setState(int state) {
    this.state = state;
    notifyAllObservers();
    }

    public void attach(Observer observer){
    observers.add(observer);
    }

    public void notifyAllObservers(){
    for (Observer observer : observers) {
    observer.update();
    }
    }
    }

    abstract class Observer {
    protected Subject subject;
    public abstract void update();
    }

    class BinaryObserver extends Observer{

    public BinaryObserver(Subject subject){
    this.subject = subject;
    this.subject.attach(this);
    }

    @Override
    public void update() {
    System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) );
    }
    }

    class OctalObserver extends Observer{

    public OctalObserver(Subject subject){
    this.subject = subject;
    this.subject.attach(this);
    }

    @Override
    public void update() {
    System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) );
    }
    }

    class HexaObserver extends Observer{

    public HexaObserver(Subject subject){
    this.subject = subject;
    this.subject.attach(this);
    }

    @Override
    public void update() {
    System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() );
    }
    }

    class ObserverPatternDemo {
    public static void main(String[] args) {
    Subject subject = new Subject();

    new HexaObserver(subject);
    new OctalObserver(subject);
    new BinaryObserver(subject);

    System.out.println("First state change: 15");
    subject.setState(15);
    System.out.println("Second state change: 10");
    subject.setState(10);
    }
    }

Comment and share

애노테이션 (Annotations)

애노테이션이란

  • 애노테이션의 사전적인 의미는 주석
  • JVM, 컴파일러, 프레임워크 등에게 전달하는 메타데이터로 사용됨

기본 애노테이션

애노테이션 설명 비고
@Override 상속하여 오버라이드된 메소드
@Deprecated 앞으로 사라질 예정임을 표기
@SuppressWarnings 컴파일러에게 특정 경고 메세지를 무시하도록 한다. eg. @SuppressWarnings(“unused”)
@FunctionalInterface 함수형 인터페이스임을 표기 (Lambda)

애노테이션의 구성 요소

  • 애노테이션의 작성
    • 추상 메소드와 유사한 형태로 구현
1
2
3
4
5
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) // 메타 애노테이션
@Retention(RetentionPolicy.SOURCE) // 메타 애노테이션
public @interface SuppressWarnings { // 애노테이션 선언
String [] value(); // 애노테이션 속성
}
  • 애노테이션의 사용
    • key=value 형태로 애노테이션에 속성의 값 전달
1
2
3
4
5
@SuppressWarnings(value = {"unused", "rawtypes"}) // 키 = 값 배열
@SuppressWarnings(value = "unused") // 값이 하나인 경우 배열 생략 가능
@SuppressWarnings({"unused", "rawtypes"}) // 속성이 value 하나인 경우 키 생략 가능

@CustomAnnotation(key1 = "value1", key2 = {"value2", "value3"}) // 속성이 여러개인 경우 키를 여러개 사용
  • Target 설정

    • 애노테이션을 사용할 수 있는 대상을 설정

    • ElementType 열거형 상수 사용

      ElementType 범위
      TYPE 클래스, 인터페이스, 애노테이션, 열거형
      FIELD 필드(멤버 변수), 열거형 상수
      METHOD 메소드
      PARAMETER 메소드의 파라미터
      CONSTRUCTOR 생성자
      LOCAL_VARIABLE 로컬 변수
      ANNOTATION_TYPE 애노테이션
      PACKAGE 패키지
  • Retention 설정

    • 애노테이션 정보를 언제까지 유지할 것인지 설정

    • RetentionPolicy 열거형 상수 사용

    • reflection: java.lang.reflect API

      RetentionPolicy 범위
      SOURCE 컴파일러가 사용. 빌드된 .class 파일에는 포함되지 않음
      CLASS .class 파일에 포함되나, VM이 사용하지 않으며 reflection에 정보를 포함하지 않음
      RUNTIME .class에 포함, VM에서 인식, reflection에 정보를 포함

사용자 정의 애노테이션

  • 사용자 정의 애노테이션 구현

    1
    2
    3
    4
    5
    6
    @Retention(RUNTIME)
    @Target(FIELD)
    public @interface CustomAnnotation {
    String value();
    String valueTwo() default "기본값";
    }
  • 사용자 정의 애노테이션 사용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class CustomAnnotationUsage {
    @CustomAnnotation("game")
    String gameName = "여러분의 틱택토";
    @CustomAnnotation(value = "server", valueTwo = "localhost")
    String serverIP;
    @CustomAnnotation("game")
    String gameMode = "AI vs. AI";
    @CustomAnnotation(value = "server", valueTwo = "8888")
    String serverPort;
    }
  • Reflection을 이용하여 애노테이션에 할당된 값 사용

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class CustomAnnotationTest {
    public static void main(String[] args) throws Exception {
    CustomAnnotationUsage obj = new CustomAnnotationUsage();
    Map<String, Object> gameProp = new HashMap<>();
    Map<String, Object> serverProp = new HashMap<>();

    Field[] fields = CustomAnnotationUsage.class.getDeclaredFields();
    for (Field field: fields) {
    CustomAnnotation annotation = field.getDeclaredAnnotation(CustomAnnotation.class);
    if (field.get(obj) == null) {
    field.set(obj, annotation.valueTwo());
    }
    if (annotation.value().equals("game")) {
    gameProp.put(field.getName(), field.get(obj));
    } else {
    serverProp.put(field.getName(), field.get(obj));
    }
    }

    System.out.println(gameProp);
    System.out.println(serverProp);

    }
    }

Comment and share

Yechan Kim

author.bio


author.job