정보처리기사 실기 완벽 대비 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;
풀이:
- WHERE 성적 >= 80 → 박민수(78) 제외
- GROUP BY 학과: 컴퓨터(김철수85, 이영희92, 정다연95), 전자(최수진88)
- HAVING COUNT(*) >= 2 → 전자(1명) 제외
- 결과:
1
2
3
4
5
┌──────┬────┬──────────┐
│학과 │인원│평균 │
├──────┼────┼──────────┤
│컴퓨터│3 │90.666... │
└──────┴────┴──────────┘
2편 마무리: 코드 문제는 패턴이 반복된다. 위 패턴들을 손으로 직접 풀어보고, 변수 추적표를 그리는 연습을 반복하면 실전에서 거의 만점을 받을 수 있다. 1편(이론)과 2편(코드)을 합치면 60점 합격선은 충분히 넘길 수 있다.