정보처리기사 실기 완벽 대비 2편: C, Java, Python 코드 트레이싱 + SQL 실전 — 기출 패턴 총정리

정보처리기사 실기 완벽 대비 2편: C, Java, Python 코드 트레이싱 + SQL 실전

시험 전략: 코드 출력 문제는 매회 6~8문제(약 30~40점)가 출제되며, 패턴이 정해져 있다. C/Java/Python 각 2문제 내외 + SQL 1~2문제가 일반적이다. 이 글의 패턴을 모두 연습하면 코드 문제에서 거의 만점을 받을 수 있다.


1장. C 언어 핵심 문법 + 기출 패턴

1.1 반드시 알아야 할 C 기본

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// ★ printf 서식 지정자
%d  정수       %f  실수       %c  문자       %s  문자열
%o  8진수      %x  16진수     %u  unsigned   %ld long
%5d   5 확보 오른쪽 정렬
%-5d  5 확보 왼쪽 정렬
%.2f  소수점 이하 2자리

// ★ 산술·비교·논리 연산자
+  -  *  /  %  (나머지)
==  !=  >  <  >=  <=
&&(AND)  ||(OR)  !(NOT)

// ★ 증감 연산자
i++  후위 (현재  사용  증가)
++i  전위 (증가  사용)
i--  후위 감소
--i  전위 감소

// ★ 비트 연산자
&  AND     |  OR     ^  XOR     ~  NOT
<<  왼쪽 시프트 (×2)     >>  오른쪽 시프트 (÷2)

// ★ 삼항 연산자
조건 ? 참일때 : 거짓일때

1.2 배열과 반복문 ★★★

1
2
3
4
5
6
7
8
9
10
11
12
// [패턴 1] 배열 순회
#include <stdio.h>
int main() {
    int a[] = {1, 2, 3, 4, 5};
    int sum = 0;
    for (int i = 0; i < 5; i++) {
        if (a[i] % 2 == 1)    // 홀수만
            sum += a[i];
    }
    printf("%d", sum);         // 출력: 9 (1+3+5)
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// [패턴 2] 이중 반복문 + 별 찍기 유형
#include <stdio.h>
int main() {
    int i, j;
    for (i = 0; i < 5; i++) {
        for (j = 0; j <= i; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}
// 출력:
// *
// **
// ***
// ****
// *****
1
2
3
4
5
6
7
8
9
10
11
// [패턴 3] while + 자릿수 분리 ★★★
#include <stdio.h>
int main() {
    int n = 12345, sum = 0;
    while (n > 0) {
        sum += n % 10;    // 마지막 자리 추출
        n /= 10;          // 마지막 자리 제거
    }
    printf("%d", sum);     // 출력: 15 (1+2+3+4+5)
    return 0;
}

1.3 포인터 ★★★ (매회 출제)

1
2
3
4
5
6
7
// ★★★ 포인터 기본
int a = 10;
int *p = &a;      // p는 a의 주소를 저장
printf("%d", *p);  // 10 (역참조: 주소가 가리키는 값)
printf("%d", a);   // 10
*p = 20;           // a의 값을 20으로 변경
printf("%d", a);   // 20
1
2
3
4
5
6
7
8
9
10
11
12
// [패턴 4] 포인터와 배열 ★★★
#include <stdio.h>
int main() {
    int a[] = {10, 20, 30, 40, 50};
    int *p = a;           // p = a[0]의 주소
    printf("%d\n", *p);       // 10
    printf("%d\n", *(p+1));   // 20 (a[1])
    printf("%d\n", *(p+3));   // 40 (a[3])
    p += 2;
    printf("%d\n", *p);       // 30 (a[2])
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// [패턴 5] 포인터 교환 ★★★
#include <stdio.h>
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}
int main() {
    int x = 3, y = 5;
    swap(&x, &y);
    printf("%d %d", x, y);  // 출력: 5 3
    return 0;
}

1.4 문자열 ★★

1
2
3
4
5
// ★ 문자열 = 문자 배열 + '\0' (널 종료)
char str[] = "Hello";  // {'H','e','l','l','o','\0'}

// strlen(str) = 5 (널 문자 미포함)
// sizeof(str) = 6 (널 문자 포함)
1
2
3
4
5
6
7
8
9
10
11
12
// [패턴 6] 문자열 길이/역순 ★★
#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "HELLO";
    int len = strlen(str);    // 5
    for (int i = len - 1; i >= 0; i--) {
        printf("%c", str[i]);
    }
    // 출력: OLLEH
    return 0;
}
1
2
3
4
5
6
7
8
9
10
// [패턴 7] ASCII 코드 활용
// 'A' = 65, 'a' = 97, '0' = 48
#include <stdio.h>
int main() {
    char c = 'A';
    c = c + 32;           // 대문자 → 소문자
    printf("%c\n", c);    // 출력: a
    printf("%d\n", c);    // 출력: 97
    return 0;
}

1.5 재귀 함수 ★★★

1
2
3
4
5
6
7
8
9
10
// [패턴 8] 팩토리얼 ★★
#include <stdio.h>
int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}
int main() {
    printf("%d", factorial(5));  // 출력: 120 (5×4×3×2×1)
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
// [패턴 9] 피보나치 ★★
#include <stdio.h>
int fib(int n) {
    if (n <= 1) return n;
    return fib(n-1) + fib(n-2);
}
int main() {
    printf("%d", fib(6));  // 출력: 8
    // fib: 0,1,1,2,3,5,8,...
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
// [패턴 10] 재귀 호출 순서 추적 ★★★
#include <stdio.h>
void func(int n) {
    if (n <= 0) return;
    printf("%d ", n);       // ← 재귀 호출 전에 출력
    func(n - 1);
}
int main() {
    func(5);
    return 0;
}
// 출력: 5 4 3 2 1
1
2
3
4
5
6
7
// printf 위치가 재귀 호출 '후'면 역순!
void func(int n) {
    if (n <= 0) return;
    func(n - 1);
    printf("%d ", n);       // ← 재귀 호출 후에 출력
}
// func(5) 호출 시 출력: 1 2 3 4 5

1.6 구조체 ★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// [패턴 11] 구조체
#include <stdio.h>
struct Student {
    char name[20];
    int score;
};
int main() {
    struct Student s = {"Kim", 90};
    struct Student *p = &s;
    printf("%s %d\n", s.name, s.score);    // Kim 90
    printf("%s %d\n", p->name, p->score);  // Kim 90
    // 구조체 포인터는 -> (화살표 연산자) 사용
    return 0;
}

1.7 switch-case ★★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// [패턴 12] switch-case + break 함정 ★★
#include <stdio.h>
int main() {
    int n = 2;
    switch(n) {
        case 1: printf("A");
        case 2: printf("B");     // 여기서 시작
        case 3: printf("C");     // break 없으면 fall-through!
        case 4: printf("D");
            break;               // 여기서 멈춤
        default: printf("E");
    }
    return 0;
}
// 출력: BCD (break 없으면 아래로 계속 실행!)

2장. Java 핵심 문법 + 기출 패턴

2.1 반드시 알아야 할 Java 기본

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ★ 출력
System.out.println("줄바꿈 있음");
System.out.print("줄바꿈 없음");
System.out.printf("%d, %s, %.2f", 10, "hello", 3.14);

// ★ 형변환
int a = (int) 3.7;    // a = 3 (소수점 버림)
double b = 5;          // b = 5.0 (자동 변환)
int c = 7 / 2;         // c = 3 (정수 나눗셈)
double d = 7.0 / 2;    // d = 3.5

// ★ String 메서드
String s = "Hello";
s.length()           // 5
s.charAt(0)          // 'H'
s.substring(1, 3)    // "el" (1번~2번 인덱스)
s.toUpperCase()      // "HELLO"
s.toLowerCase()      // "hello"
s.equals("Hello")    // true
s.indexOf("ll")      // 2
s.replace("l", "L")  // "HeLLo"

2.2 클래스와 상속 ★★★ (매회 출제)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// [패턴 1] 기본 상속 + 오버라이딩 ★★★
class Parent {
    int x = 10;
    void show() {
        System.out.println("Parent: " + x);
    }
}
class Child extends Parent {
    int x = 20;
    void show() {             // 오버라이딩
        System.out.println("Child: " + x);
    }
}
public class Main {
    public static void main(String[] args) {
        Parent p = new Child();  // 업캐스팅
        p.show();                // Child: 20 (오버라이딩된 메서드 실행)
        System.out.println(p.x); // 10 (변수는 참조타입 기준!)
    }
}
// ★ 메서드는 실제 객체 타입(Child), 변수는 참조 타입(Parent)
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
// [패턴 2] super와 this ★★
class A {
    int x;
    A(int x) {
        this.x = x;
    }
    void print() {
        System.out.println("A: " + x);
    }
}
class B extends A {
    int y;
    B(int x, int y) {
        super(x);           // 부모 생성자 호출
        this.y = y;
    }
    void print() {
        super.print();       // 부모 메서드 호출
        System.out.println("B: " + y);
    }
}
public class Main {
    public static void main(String[] args) {
        B b = new B(10, 20);
        b.print();
    }
}
// 출력:
// A: 10
// B: 20

2.3 추상 클래스와 인터페이스 ★★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// [패턴 3] 추상 클래스 ★★
abstract class Shape {
    abstract double area();   // 추상 메서드 (구현 X)
    void info() {
        System.out.println("도형");
    }
}
class Circle extends Shape {
    double r;
    Circle(double r) { this.r = r; }
    double area() {           // 반드시 구현
        return 3.14 * r * r;
    }
}
public class Main {
    public static void main(String[] args) {
        Shape s = new Circle(5);
        System.out.printf("%.2f", s.area());  // 78.50
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// [패턴 4] 인터페이스 ★★
interface Printable {
    void print();             // public abstract 자동
}
interface Loggable {
    void log();
}
class Document implements Printable, Loggable {
    public void print() {
        System.out.println("Print");
    }
    public void log() {
        System.out.println("Log");
    }
}
public class Main {
    public static void main(String[] args) {
        Document d = new Document();
        d.print();    // Print
        d.log();      // Log
    }
}

2.4 배열과 반복 ★★

1
2
3
4
5
6
7
8
9
10
11
12
// [패턴 5] 배열 정렬·합계
public class Main {
    public static void main(String[] args) {
        int[] arr = {5, 3, 8, 1, 2};
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max)
                max = arr[i];
        }
        System.out.println(max);  // 출력: 8
    }
}
1
2
3
4
5
6
7
8
9
10
11
// [패턴 6] 2차원 배열
public class Main {
    public static void main(String[] args) {
        int[][] a = { {1,2,3}, {4,5,6}, {7,8,9} };
        int sum = 0;
        for (int i = 0; i < 3; i++) {
            sum += a[i][i];      // 대각선: a[0][0], a[1][1], a[2][2]
        }
        System.out.println(sum);  // 출력: 15 (1+5+9)
    }
}

2.5 static, final ★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// [패턴 7] static 변수 ★
class Counter {
    static int count = 0;      // 클래스 변수 (모든 인스턴스가 공유)
    Counter() {
        count++;
    }
}
public class Main {
    public static void main(String[] args) {
        new Counter();
        new Counter();
        new Counter();
        System.out.println(Counter.count);  // 출력: 3
    }
}

2.6 예외 처리 ★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// [패턴 8] try-catch-finally
public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        try {
            System.out.println(arr[5]);       // 예외 발생!
            System.out.println("A");          // 실행 안 됨
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("B");          // 예외 처리
        } finally {
            System.out.println("C");          // 항상 실행
        }
        System.out.println("D");              // 정상 실행
    }
}
// 출력:
// B
// C
// D

2.7 컬렉션 ★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// [패턴 9] ArrayList
import java.util.ArrayList;
public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        list.remove(1);          // 인덱스 1 제거 (20)
        System.out.println(list); // [10, 30]
        System.out.println(list.get(0)); // 10
        System.out.println(list.size()); // 2
    }
}

3장. Python 핵심 문법 + 기출 패턴

3.1 반드시 알아야 할 Python 기본

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# ★ 출력
print("Hello")             # 줄바꿈 있음
print("A", end="")         # 줄바꿈 없음
print("A", "B", "C")       # A B C (공백으로 구분)
print(f"{x} + {y} = {x+y}") # f-string

# ★ 자료형
a = 10        # int
b = 3.14      # float
c = "hello"   # str
d = True      # bool
e = [1,2,3]   # list
f = (1,2,3)   # tuple (수정 불가)
g = {1,2,3}   # set (중복 제거)
h = {"a":1}   # dict

# ★ 나눗셈
7 / 2    # 3.5 (실수 나눗셈)
7 // 2   # 3   (정수 나눗셈, 몫)
7 % 2    # 1   (나머지)
2 ** 3   # 8   (거듭제곱)

3.2 리스트 ★★★ (매회 출제)

1
2
3
4
5
6
7
8
9
# [패턴 1] 리스트 슬라이싱 ★★★
a = [10, 20, 30, 40, 50]
print(a[0])      # 10
print(a[-1])     # 50 (뒤에서 첫 번째)
print(a[1:4])    # [20, 30, 40] (1번~3번)
print(a[:3])     # [10, 20, 30] (처음~2번)
print(a[2:])     # [30, 40, 50] (2번~끝)
print(a[::2])    # [10, 30, 50] (2칸씩)
print(a[::-1])   # [50, 40, 30, 20, 10] (역순)
1
2
3
4
5
6
7
8
9
10
# [패턴 2] 리스트 메서드 ★★★
a = [3, 1, 4, 1, 5]
a.append(9)       # [3,1,4,1,5,9] — 끝에 추가
a.insert(0, 7)    # [7,3,1,4,1,5,9] — 0번에 7 삽입
a.pop()           # 9 반환, [7,3,1,4,1,5] — 마지막 제거
a.pop(0)          # 7 반환, [3,1,4,1,5] — 0번 제거
a.remove(1)       # [3,4,1,5] — 첫 번째 1 제거
a.sort()          # [1,3,4,5] — 오름차순 정렬
a.reverse()       # [5,4,3,1] — 역순
len(a)            # 4
1
2
3
4
5
6
7
8
9
# [패턴 3] 리스트 컴프리헨션 ★★★
a = [x for x in range(10) if x % 2 == 0]
print(a)    # [0, 2, 4, 6, 8]

b = [x**2 for x in range(1, 6)]
print(b)    # [1, 4, 9, 16, 25]

c = [x for x in "Hello" if x.isupper()]
print(c)    # ['H']

3.3 딕셔너리 ★★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# [패턴 4] 딕셔너리 ★★
d = {"a": 1, "b": 2, "c": 3}
print(d["a"])           # 1
print(d.get("d", 0))   # 0 (없으면 기본값)
d["d"] = 4              # 추가
print(d.keys())         # dict_keys(['a','b','c','d'])
print(d.values())       # dict_values([1,2,3,4])

for k, v in d.items():
    print(k, v)
# a 1
# b 2
# c 3
# d 4

3.4 함수와 람다 ★★

1
2
3
4
5
6
# [패턴 5] 함수
def func(a, b=10):    # b 기본값 10
    return a + b

print(func(5))        # 15 (5+10)
print(func(5, 20))    # 25 (5+20)
1
2
3
4
5
6
7
8
9
10
# [패턴 6] 람다 + map/filter ★★
a = [1, 2, 3, 4, 5]

# map: 모든 요소에 함수 적용
b = list(map(lambda x: x**2, a))
print(b)    # [1, 4, 9, 16, 25]

# filter: 조건에 맞는 요소만
c = list(filter(lambda x: x % 2 == 0, a))
print(c)    # [2, 4]

3.5 문자열 ★★

1
2
3
4
5
6
7
8
9
10
# [패턴 7] 문자열 메서드
s = "Hello World"
print(s.upper())          # HELLO WORLD
print(s.lower())          # hello world
print(s.split())          # ['Hello', 'World']
print(s.replace("l","L")) # HeLLo WorLd
print(s.count("l"))       # 3
print(s.find("World"))    # 6 (인덱스)
print(s.strip())          # 양쪽 공백 제거
print("-".join(["a","b","c"]))  # a-b-c

3.6 클래스 ★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# [패턴 8] Python 상속 ★
class Animal:
    def __init__(self, name):
        self.name = name
    def speak(self):
        return "..."

class Dog(Animal):
    def speak(self):           # 오버라이딩
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

animals = [Dog("Rex"), Cat("Kitty")]
for a in animals:
    print(f"{a.name}: {a.speak()}")
# Rex: Woof!
# Kitty: Meow!

3.7 기타 자주 나오는 패턴

1
2
3
4
5
6
7
# [패턴 9] set(집합) 연산 ★
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b)    # {3, 4}      교집합
print(a | b)    # {1,2,3,4,5,6} 합집합
print(a - b)    # {1, 2}      차집합
print(a ^ b)    # {1, 2, 5, 6} 대칭 차집합
1
2
3
4
5
# [패턴 10] 진수 변환 ★
print(bin(10))    # 0b1010 (2진수)
print(oct(10))    # 0o12   (8진수)
print(hex(10))    # 0xa    (16진수)
print(int("1010", 2))   # 10 (2진수→10진수)

4장. SQL 실전 ★★★

4.1 SELECT 기본

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- 전체 조회
SELECT * FROM 학생;

-- 조건 조회
SELECT 이름, 학과 FROM 학생 WHERE 학과 = '컴퓨터';

-- 정렬
SELECT * FROM 학생 ORDER BY 성적 DESC;  -- 내림차순
SELECT * FROM 학생 ORDER BY 학과 ASC, 성적 DESC;  -- 복합 정렬

-- DISTINCT (중복 제거)
SELECT DISTINCT 학과 FROM 학생;

-- LIKE 패턴 매칭
SELECT * FROM 학생 WHERE 이름 LIKE '김%';    -- 김으로 시작
SELECT * FROM 학생 WHERE 이름 LIKE '%수';    -- 수로 끝남
SELECT * FROM 학생 WHERE 이름 LIKE '_진%';   -- 두 번째 글자가 진

-- BETWEEN, IN
SELECT * FROM 학생 WHERE 성적 BETWEEN 80 AND 90;
SELECT * FROM 학생 WHERE 학과 IN ('컴퓨터', '전자');

-- IS NULL / IS NOT NULL
SELECT * FROM 학생 WHERE 연락처 IS NULL;

4.2 집계 함수 + GROUP BY ★★★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- 집계 함수
SELECT COUNT(*) FROM 학생;                    -- 전체 행 수
SELECT COUNT(DISTINCT 학과) FROM 학생;         -- 학과 수
SELECT SUM(성적) FROM 학생;                    -- 합계
SELECT AVG(성적) FROM 학생;                    -- 평균
SELECT MAX(성적) FROM 학생;                    -- 최대
SELECT MIN(성적) FROM 학생;                    -- 최소

-- GROUP BY + HAVING ★★★
SELECT 학과, AVG(성적) AS 평균
FROM 학생
GROUP BY 학과
HAVING AVG(성적) >= 80;

-- ★ 실행 순서: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
-- ★ WHERE는 그룹화 전 필터, HAVING은 그룹화 후 필터

4.3 JOIN ★★★

1
2
3
4
5
6
7
8
9
학생 테이블:                  성적 테이블:
┌────┬─────┬──────┐         ┌────┬────┬─────┐
│학번│이름  │학과  │         │학번│과목│점수 │
├────┼─────┼──────┤         ├────┼────┼─────┤
│100 │김철수│컴퓨터│         │100 │DB  │90   │
│200 │이영희│전자  │         │100 │OS  │85   │
│300 │박민수│컴퓨터│         │200 │DB  │95   │
│400 │최수진│기계  │         │500 │DB  │70   │
└────┴─────┴──────┘         └────┴────┴─────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-- INNER JOIN (교집합: 양쪽 모두 있는 것만)
SELECT A.이름, B.과목, B.점수
FROM 학생 A INNER JOIN 성적 B ON A.학번 = B.학번;
-- 결과: 김철수-DB-90, 김철수-OS-85, 이영희-DB-95
-- (학번 300, 400, 500은 매칭 안 됨)

-- LEFT JOIN (왼쪽 테이블 전부 + 매칭되는 오른쪽)
SELECT A.이름, B.과목, B.점수
FROM 학생 A LEFT JOIN 성적 B ON A.학번 = B.학번;
-- 결과: 김철수-DB-90, 김철수-OS-85, 이영희-DB-95,
--       박민수-NULL-NULL, 최수진-NULL-NULL

-- RIGHT JOIN (오른쪽 테이블 전부 + 매칭되는 왼쪽)
SELECT A.이름, B.과목, B.점수
FROM 학생 A RIGHT JOIN 성적 B ON A.학번 = B.학번;
-- 결과: 김철수-DB-90, 김철수-OS-85, 이영희-DB-95,
--       NULL-DB-70 (학번 500)

-- FULL OUTER JOIN (양쪽 모두)
-- MySQL에서는 LEFT JOIN UNION RIGHT JOIN으로 구현

4.4 서브쿼리 ★★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- WHERE 절 서브쿼리
SELECT 이름 FROM 학생
WHERE 학번 IN (SELECT 학번 FROM 성적 WHERE 점수 >= 90);
-- 점수가 90 이상인 학생의 이름

-- FROM 절 서브쿼리 (인라인 뷰)
SELECT A.학과, A.평균
FROM (SELECT 학과, AVG(성적) AS 평균 FROM 학생 GROUP BY 학과) A
WHERE A.평균 >= 80;

-- EXISTS
SELECT 이름 FROM 학생 A
WHERE EXISTS (SELECT 1 FROM 성적 B WHERE A.학번 = B.학번);
-- 성적 테이블에 데이터가 있는 학생만

4.5 DML (INSERT, UPDATE, DELETE) ★

1
2
3
4
5
6
7
8
9
10
11
-- INSERT
INSERT INTO 학생(학번, 이름, 학과) VALUES (500, '정다연', '컴퓨터');
INSERT INTO 학생 VALUES (500, '정다연', '컴퓨터');  -- 전체 컬럼 순서대로

-- UPDATE
UPDATE 학생 SET 학과 = '소프트웨어' WHERE 이름 = '김철수';
-- ★ WHERE 없으면 전체 행 수정!

-- DELETE
DELETE FROM 학생 WHERE 학과 = '기계';
-- ★ WHERE 없으면 전체 행 삭제!

4.6 DDL (CREATE, ALTER, DROP) ★

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE 학생 (
    학번 INT PRIMARY KEY,
    이름 VARCHAR(20) NOT NULL,
    학과 VARCHAR(30) DEFAULT '미정',
    CONSTRAINT fk_학과 FOREIGN KEY(학과) REFERENCES 학과(학과명)
);

ALTER TABLE 학생 ADD 연락처 VARCHAR(15);
ALTER TABLE 학생 MODIFY 이름 VARCHAR(50);
ALTER TABLE 학생 DROP COLUMN 연락처;
ALTER TABLE 학생 RENAME COLUMN 이름 TO 성명;

DROP TABLE 학생 CASCADE;
TRUNCATE TABLE 학생;

4.7 DCL + TCL ★

1
2
3
4
5
6
7
8
9
10
11
-- 권한 부여
GRANT SELECT, INSERT ON 학생 TO user1 WITH GRANT OPTION;

-- 권한 회수
REVOKE INSERT ON 학생 FROM user1 CASCADE;

-- 트랜잭션
COMMIT;              -- 확정
ROLLBACK;            -- 취소
SAVEPOINT sp1;       -- 저장점 생성
ROLLBACK TO sp1;     -- sp1으로 복원

5장. 코드 트레이싱 실전 비법

5.1 손으로 풀기 노하우

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
┌─────────────────────────────────────────────────────────────────────┐
│              코드 문제 풀이 비법                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. 변수 추적표를 반드시 그려라                                     │
│     ┌─────┬───┬───┬───┐                                           │
│     │ 단계│ i │ j │sum│                                            │
│     ├─────┼───┼───┼───┤                                           │
│     │  1  │ 0 │ 0 │ 0 │                                           │
│     │  2  │ 0 │ 1 │ 1 │                                           │
│     │ ... │...│...│...│                                            │
│     └─────┴───┴───┴───┘                                           │
│                                                                     │
│  2. 포인터는 주소와 값을 분리해서 추적                              │
│     p → [주소: 0x100] → [값: 10]                                   │
│                                                                     │
│  3. 재귀는 호출 스택을 그려라                                       │
│     func(3)                                                         │
│       └→ func(2)                                                    │
│            └→ func(1)                                               │
│                 └→ return 1                                         │
│            return 2 * 1 = 2                                         │
│       return 3 * 2 = 6                                              │
│                                                                     │
│  4. Java 상속은 "실제 객체 타입"이 핵심                             │
│     Parent p = new Child();                                         │
│     p.method() → Child의 method 실행 (오버라이딩)                  │
│     p.field   → Parent의 field (변수는 참조 타입)                  │
│                                                                     │
│  5. Python은 인덱스와 슬라이싱 규칙 정확히 암기                    │
│     [start:stop:step] — stop은 미포함!                             │
│                                                                     │
│  6. switch-case에서 break 없으면 fall-through!                     │
│                                                                     │
│  7. 후위 연산자(i++) vs 전위 연산자(++i) 차이 주의                 │
│     a = i++ → a에 현재 i 대입 후 i 증가                           │
│     a = ++i → i 증가 후 a에 대입                                   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5.2 자주 틀리는 함정 모음

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
┌─────────────────────────────────────────────────────────────────────┐
│                  시험 함정 TOP 10                                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. C에서 배열 인덱스는 0부터 시작                                  │
│     int a[5] = {1,2,3,4,5}; → a[0]=1, a[4]=5                     │
│                                                                     │
│  2. C에서 / 는 정수끼리면 정수 나눗셈                               │
│     7 / 2 = 3 (소수점 버림)                                        │
│                                                                     │
│  3. Java에서 String == 비교는 주소 비교                             │
│     equals()로 내용 비교해야 함                                     │
│                                                                     │
│  4. Python에서 // 는 정수 나눗셈 (몫)                               │
│     7 // 2 = 3, -7 // 2 = -4 (내림!)                              │
│                                                                     │
│  5. for (i=0; i<5; i++) → 0,1,2,3,4 (5번 실행)                    │
│     for (i=1; i<=5; i++) → 1,2,3,4,5 (5번 실행)                   │
│                                                                     │
│  6. Python range(1, 5) → 1,2,3,4 (5 미포함!)                      │
│                                                                     │
│  7. switch-case에서 break 누락 → fall-through                     │
│                                                                     │
│  8. Java 오버라이딩 vs 오버로딩                                     │
│     오버라이딩: 부모 메서드 재정의 (이름+파라미터 동일)             │
│     오버로딩: 같은 이름, 다른 파라미터                              │
│                                                                     │
│  9. SQL에서 WHERE vs HAVING                                        │
│     WHERE: GROUP BY 전 필터                                        │
│     HAVING: GROUP BY 후 필터 (집계 함수 사용 가능)                 │
│                                                                     │
│  10. SQL NULL 비교는 = 가 아니라 IS NULL                           │
│      WHERE 연락처 = NULL (❌)                                      │
│      WHERE 연락처 IS NULL (✅)                                     │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

6장. 실전 종합 문제

종합 1. C 코드 출력

1
2
3
4
5
6
7
8
#include <stdio.h>
int main() {
    int a = 5, b = 3, c;
    c = a > b ? a : b;
    a = c > 4 ? c * 2 : c + 2;
    printf("%d %d %d", a, b, c);
    return 0;
}

풀이:

  • c = 5 > 3 ? 5 : 3 → c = 5
  • a = 5 > 4 ? 5*2 : 5+2 → a = 10
  • 출력: 10 3 5

종합 2. Java 코드 출력

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
    int value = 10;
    void display() { System.out.println("A: " + value); }
}
class B extends A {
    int value = 20;
    void display() { System.out.println("B: " + value); }
}
public class Main {
    public static void main(String[] args) {
        A obj = new B();
        obj.display();
        System.out.println(obj.value);
    }
}

풀이:

  • obj의 참조 타입 A, 실제 타입 B
  • obj.display() → B의 display() 실행 (오버라이딩) → B: 20
  • obj.value → A의 value (변수는 참조 타입) → 10
  • 출력: B: 20 (줄바꿈) 10

종합 3. Python 코드 출력

1
2
3
4
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [x for x in a if x % 3 == 0]
c = list(map(lambda x: x * 2, b))
print(sum(c))

풀이:

  • b = [3, 6, 9] (3의 배수)
  • c = [6, 12, 18] (각각 ×2)
  • sum(c) = 36
  • 출력: 36

종합 4. SQL 결과

1
2
3
4
5
6
7
8
9
10
학생 테이블:
┌────┬──────┬──────┬─────┐
│학번│이름  │학과  │성적 │
├────┼──────┼──────┼─────┤
│1   │김철수│컴퓨터│85   │
│2   │이영희│컴퓨터│92   │
│3   │박민수│전자  │78   │
│4   │최수진│전자  │88   │
│5   │정다연│컴퓨터│95   │
└────┴──────┴──────┴─────┘
1
2
3
4
5
6
SELECT 학과, COUNT(*) AS 인원, AVG(성적) AS 평균
FROM 학생
WHERE 성적 >= 80
GROUP BY 학과
HAVING COUNT(*) >= 2
ORDER BY 평균 DESC;

풀이:

  1. WHERE 성적 >= 80 → 박민수(78) 제외
  2. GROUP BY 학과: 컴퓨터(김철수85, 이영희92, 정다연95), 전자(최수진88)
  3. HAVING COUNT(*) >= 2 → 전자(1명) 제외
  4. 결과:
1
2
3
4
5
┌──────┬────┬──────────┐
│학과  │인원│평균      │
├──────┼────┼──────────┤
│컴퓨터│3   │90.666... │
└──────┴────┴──────────┘

2편 마무리: 코드 문제는 패턴이 반복된다. 위 패턴들을 손으로 직접 풀어보고, 변수 추적표를 그리는 연습을 반복하면 실전에서 거의 만점을 받을 수 있다. 1편(이론)과 2편(코드)을 합치면 60점 합격선은 충분히 넘길 수 있다.