College Board CED V.1 Effective Fall 2025 · 25점 / 90분 / 45% · 한국 학생 빈출 감점 정리
📌 시험 정보 (Section II — Free-Response)
FRQ 4문항 / 90 minutes / 시험 비중 45% / 총점 25점 · 모두 Practice 2 (Develop Code) 평가 (Skills 2.A·2.B·2.C)
• Q1: Methods and Control Structures (7 points) — Part A 4점 (iterative/conditional + class method 호출) + Part B 3점 (String 메서드 호출)
• Q2: Class Design (7 points) — class header + instance variables + constructor + method 모두 작성
• Q3: Data Analysis with ArrayList (5 points) — ArrayList 사용·분석·조작 1 method
• Q4: 2D Array (6 points) — 2D 배열 사용·분석·조작 1 method
• 평균 시간: 4문항 × 22.5분. 시험 전체 3시간 = Section I (Multiple-Choice 42문항 / 90 minutes / 55%) + Section II (Free-Response 4문항 / 90 minutes / 45%)
• 계산기 사용 불가. Java Quick Reference 1장 제공 (CED p.150).
🛠️ 5 Computational Thinking Practices (CED 분류)
Section I Multiple-Choice는 Practices 1~5 모두 평가. Section II Free-Response는 Practice 2 (Develop Code)만 집중 평가.
• Practice 1: Design Code — 2–10% (적합한 알고리즘 설계)
• Practice 2: Develop Code — 22–38% (FRQ 4문항 모두 해당)
• Practice 3: Analyze Code — 37–53% (MCQ 최다 비중, 코드 trace)
• Practice 4: Document Code and Computing Systems — 10–15%
• Practice 5: Use Computers Responsibly — 2–10% (윤리·사회적 영향)
① 채점 원리 — College Board가 어떻게 점수를 주는가
AP CSA FRQ 채점은 Stat의 holistic E/P/I rubric과 다릅니다. CSA는 "포인트 합산(point-by-point)" 방식입니다. 각 문항은 sub-task별로 1점씩 분리 채점되고, 25점 만점이 그대로 누적됩니다.
CSA FRQ 채점 단계
단계
판정 기준
의미
Earned (점수 획득)
해당 sub-task의 코드가 지정된 동작을 정확히 수행하고 syntax도 통과
1점씩 누적. 부분 점수 사냥이 가능
Not Earned
코드가 컴파일 안 됨 / 잘못된 동작 / 빠짐
해당 sub-task 0점. 다른 sub-task는 영향 없음
Consistent with
앞 sub-task에서 틀린 변수·return 값이 있어도, 그 잘못된 값에 일관되게 반응한 코드는 점수 인정
한 줄 실수가 전체를 망가뜨리지 않도록 College Board가 보호
✅ 핵심 통찰 — 한국 학생용
CSA는 "전부 맞히지 않아도 부분점수가 살아남는다". 막혀도 멈추지 말고 method header + return 문이라도 적어 두면 1점씩 챙길 수 있습니다. compile 안 되는 답안에는 점수가 거의 없다는 점도 기억.
Computational Thinking Practice 2 — Develop Code
Skill
이름
FRQ 평가 위치
Skill 2.A
Write program code to create objects of a class and call methods.
Write program code to define new types by creating classes.
Q2 primary focus (Class Design)
Skill 2.C
Write program code to satisfy method specifications using expressions, conditional statements, and iterative statements.
Q1·Q3·Q4 primary focus (메서드 본문 구현)
4 Units of Instruction (CED V.1)
Unit 1: Using Objects and Methods (15-25%, MCQ)
Unit 2: Selection and Iteration (25-35%, MCQ) — Q1에서 핵심
Unit 3: Class Creation (10-18%, MCQ) — Q2에서 핵심
Unit 4: Data Collections (30-40%, MCQ) — Q3·Q4에서 핵심
📌 Common Errors (College Board 공개)
매년 Chief Reader Report에 "Common Errors"가 공개됩니다. CSA 빈출은 return 누락, ==로 String 비교, ArrayList traversal 중 remove, 2D 배열 row/col 혼동, private로 시작 안 해 컴파일 실패 등. 이 가이드 ⑦번 섹션에 한국 학생 기준 Top 10으로 정리했습니다.
② Q1 — Methods and Control Structures (Skill 2.A·2.B·2.C, 7점)
📌 Q1 정체 (CED p.146 원문)
"Students will write two methods or one constructor and one method of a given class based on provided specifications and examples. In Part A (4 points), the method or constructor will require students to write iterative or conditional statements, or both, as well as statements that call methods in the specified class. In Part B (3 points), the method or constructor will require calling String methods."
예시 — Username 생성기 시나리오 (CED 스타일)
한 SNS 사이트가 새 사용자 username을 자동 생성한다. UsernameGenerator 클래스는 사용자 이름과 시도 번호를 받아 username을 만들고, 중복이면 번호를 1씩 올린다.
Part A (4점) — generate 메서드: 1부터 maxAttempts까지 반복하며 isAvailable(String) 메서드를 호출해 사용 가능한 username을 찾고, 발견되면 그 username을 반환한다. 끝까지 못 찾으면 "unavailable"을 반환.
Part B (3점) — buildUsername(String name, int n):name의 첫 3글자(소문자) + n을 이어붙인 String을 반환. 만약 name 길이가 3 미만이면 name 전체를 사용.
📋 채점 분배 (Part A — 4점)
1
method header 정확: public String generate(int maxAttempts) — return type / 접근제어자 / 매개변수 일치
Implement2.C
1
iterative statement: 1부터 maxAttempts까지 도는 for 또는 while 루프. 경계 정확 (i <= maxAttempts).
Implement2.C
1
class method 호출 + conditional: isAvailable(...) 호출 결과를 if로 분기. 호출에 적절한 String 인자를 전달.
Implement2.A
1
두 가지 return 모두 정확: 발견 시 그 username return, 끝까지 못 찾으면 "unavailable" return. 둘 중 하나만 맞으면 0점 (단일 sub-task).
Implement2.C
📋 채점 분배 (Part B — 3점)
1
method header + return type: public String buildUsername(String name, int n)Implement2.C
1
String 메서드 정확 호출: name.substring(0, 3) 또는 name.length()로 길이 체크 후 substring. toLowerCase() 적용.
Implement2.A
1
concatenation + return: 잘라낸 prefix와 n을 String으로 이어붙여 반환. +가 String이면 자동 변환되는 점 활용.
Implement2.C
총점7점 (Part A 4 + Part B 3)
✅ Q1 모범답안 — CED Develop Code 스타일 · Java 표준
Part A — generate 메서드 (4점):
publicStringgenerate(int maxAttempts) {
for (int i = 1; i <= maxAttempts; i++) {
String candidate = buildUsername(baseName, i);
if (isAvailable(candidate)) {
return candidate;
}
}
return"unavailable";
}
채점 포인트: Part A는 ① header ② loop ③ if + isAvailable 호출 ④ 두 return 모두 정확. Part B는 ① header ② substring/length/toLowerCase 정확 호출 ③ String + int concat 후 return.
💡 Q1에서 배울 점
Part A는 iterative + conditional + 클래스 내 메서드 호출 3박자가 핵심. 한 가지라도 빠지면 1점씩 깎임
Part B의 String 메서드는 CED Java Quick Reference에 명시된 것만 사용: length, substring, indexOf, equals, compareTo. (charAt도 자주 등장)
변수명 오타 (case sensitive) → undefined identifier → compile 실패
loop 경계 off-by-one: i < maxAttempts로 쓰면 마지막 시도 누락 (최소 1점 손실)
③ Q2 — Class Design (Skill 2.B, 7점)
📌 Q2 정체 (CED p.146 원문)
"Students will be instructed to design and implement a class based on provided specifications and examples. … The class must include a class header, instance variables, a constructor, a method, and implementation of the constructor and required method."
예시 — CupcakeMachine 클래스 (CED Course Overview Sample)
The CupcakeMachine class represents a cupcake vending machine. Constructor에 int (보유 컵케익 수, ≥0)와 double (개당 가격 dollar, >0.0) 두 매개변수를 받는다.
takeOrder(int n): 주문 수량 n (양의 정수)을 받아 처리한다.
충분한 컵케익이 있으면 주문번호와 비용 문자열을 반환 (예: "Order number 1, cost $3.5")하고, 보유 수량을 차감하며 주문번호를 1씩 증가
부족하면 "Order cannot be filled" 반환. 수량과 주문번호 모두 변경되지 않음
예시: c1 = new CupcakeMachine(10, 1.75) 생성 → c1.takeOrder(2) → "Order number 1, cost $3.5" → c1.takeOrder(3) → "Order number 2, cost $5.25" → c1.takeOrder(10) → "Order cannot be filled" → c1.takeOrder(1) → "Order number 3, cost $1.75"
📋 채점 분배 (7점)
1
class header: public class CupcakeMachine — 접근제어자 + class 키워드 + 정확한 이름
Implement2.B
1
적절한 instance variables 선언: private int cupcakes;, private double cost;, private int orderCount; — private로 선언 (encapsulation), 타입 정확
Implement2.B
1
constructor 시그니처 정확: public CupcakeMachine(int c, double p) — 클래스 이름과 정확히 일치, 매개변수 타입 순서 일치
Implement2.B
1
constructor 본문: 매개변수를 instance variable에 정확히 복사 (this.cupcakes = c; 등). orderCount를 0으로 초기화
Implement2.B
1
takeOrder method header 정확: public String takeOrder(int n)Implement2.C
1
충분 case 처리: if (n <= cupcakes) → orderCount 증가, cupcakes -= n, return 문자열 (주문번호 + cost) 정확
Implement2.C
1
부족 case 처리: else에서 "Order cannot be filled" 반환. state 변경 없음 (cupcakes·orderCount 그대로)
Implement2.C
총점7점
✅ Q2 모범답안 — CED Course Overview Sample 기반
public classCupcakeMachine {
privateint cupcakes; // 보유 수량privatedouble cost; // 개당 가격privateint orderCount; // 누적 주문번호publicCupcakeMachine(int c, double p) {
this.cupcakes = c;
this.cost = p;
this.orderCount = 0;
}
publicStringtakeOrder(int n) {
if (n <= cupcakes) {
orderCount++;
cupcakes -= n;
double total = n * cost;
return"Order number " + orderCount
+ ", cost $" + total;
} else {
return"Order cannot be filled";
}
}
}
채점 체크리스트: ① public class CupcakeMachine ② private int + double + int 3개 instance var ③ constructor 시그니처 ④ constructor 본문 (state 초기화) ⑤ takeOrder header ⑥ 충분 case (state 변경 + return) ⑦ 부족 case (state 보존 + return).
💡 Q2에서 배울 점
encapsulation — instance var는 무조건 private. public으로 선언하면 1점 깎임
Constructor는 매개변수를 모두 instance var에 저장하는 게 기본. 하나라도 빠지면 0점
state-changing method: 충분 case에서 cupcakes -= n, orderCount++ 누락 시 다음 호출에서 잘못된 결과 → 큰 감점
Return 문자열 포맷은 예시 출력과 정확히 일치해야 함. "Order number "의 공백·쉼표·달러 기호 모두 syntax-sensitive
⚠️ Q2 빈출 감점 (한국 학생)
instance var public 선언 → encapsulation 점수 0점
constructor 이름 오기 (cupcakeMachine 소문자, CupcakeMaker 등) → 컴파일 실패, 1점 손실 + 다른 점수도 위험
constructor 매개변수 → instance var 대입 누락 → 다음 메서드 동작 망가짐 → 도미노 감점
takeOrder가 void로 선언됨 → return 못함 → 5~6점 손실
state 변경 누락 (충분 case에서 cupcakes 차감 안 함) → 두 번째 주문부터 잘못된 결과
"return" 문자열 포맷 mismatch ("Order #1" vs "Order number 1") → return 점수 0점
④ Q3 — Data Analysis with ArrayList (Skill 2.C, 5점)
📌 Q3 정체 (CED p.146 원문)
"Students will write one method of a given class based on provided specifications and examples. The method requires students to use, analyze, and manipulate data in an ArrayList structure."
예시 — 학생 점수 ArrayList 처리
한 클래스가 학생 점수 목록을 ArrayList<Integer> scores로 저장한다. 메서드 removeBelow(int threshold)를 작성하라:
조건 정확: if (scores.get(i) < threshold) — <=로 잘못 쓰면 경계값(=threshold) 처리 오류. 자동언박싱 활용.
Implement2.C
1
정확한 return 값: 제거 횟수를 카운트하는 count 변수 또는 (originalSize - scores.size()). 메서드 끝에 return count;Implement2.C
총점5점
✅ Q3 모범답안 — ArrayList 안전 traversal 패턴
방법 1 — 뒤에서 앞으로 (가장 안전):
publicintremoveBelow(int threshold) {
int count = 0;
for (int i = scores.size() - 1; i >= 0; i--) {
if (scores.get(i) < threshold) {
scores.remove(i);
count++;
}
}
return count;
}
방법 2 — 앞에서 뒤로, 인덱스 보정:
publicintremoveBelow(int threshold) {
int count = 0;
int i = 0;
while (i < scores.size()) {
if (scores.get(i) < threshold) {
scores.remove(i); // i 증가 X — 같은 위치 재검사
count++;
} else {
i++;
}
}
return count;
}
주의:for (int s : scores)로 enhanced for 안에서 scores.remove() 호출 시 ConcurrentModificationException 발생 → 시험에서 즉시 큰 감점.
💡 Q3에서 배울 점
ArrayList 제거 패턴은 뒤에서 앞으로가 가장 안전. 인덱스 shift 걱정 없음
ArrayList.size() ↔ 배열 .length ↔ String .length() — 3가지 모두 다름
"Students will write one method of a given class based on provided specifications and examples. The method requires students to use, analyze, and manipulate data in a 2D array structure."
예시 — 좌석 배치 행렬 분석
한 영화관의 좌석 점유를 int[][] seats로 저장한다 (0 = 비어 있음, 1 = 점유). seats는 직사각형이라 가정 (각 row 길이 동일). 메서드 countFullRows()를 작성하라:
method header: public int countFullRows() — return type / 매개변수 없음 / 정확한 이름
Implement2.C
1
outer loop (row 순회): for (int r = 0; r < seats.length; r++) — row 개수는 seats.length (대괄호 없음)
Implement2.C
1
inner loop (col 순회): for (int c = 0; c < seats[r].length; c++) — column 개수는 seats[r].lengthImplement2.C
1
인덱스 정확 + 원소 접근: seats[r][c] — row 먼저, col 나중. seats[c][r]로 뒤집으면 ArrayIndexOutOfBoundsException 위험
Implement2.A
1
조건 + 누적 로직 정확: 한 row가 전부 1인지 판단 (flag 변수 또는 inner loop 내 break/continue). 조건 만족 시 카운터 증가
Implement2.C
1
정확한 return: return count; 메서드 마지막. 카운터 변수가 모든 경로에서 초기화돼야 함
Implement2.C
총점6점
✅ Q4 모범답안 — 2D 배열 row-major traversal
방법 1 — flag 변수 사용 (가장 깔끔):
publicintcountFullRows() {
int count = 0;
for (int r = 0; r < seats.length; r++) {
boolean isFull = true;
for (int c = 0; c < seats[r].length; c++) {
if (seats[r][c] == 0) {
isFull = false;
break; // 더 볼 필요 없음
}
}
if (isFull) {
count++;
}
}
return count;
}
방법 2 — enhanced for (정연이가 익숙하다면):
publicintcountFullRows() {
int count = 0;
for (int[] row : seats) {
boolean isFull = true;
for (int v : row) {
if (v == 0) { isFull = false; break; }
}
if (isFull) count++;
}
return count;
}
주의: 2D 배열은 seats.length = row 수, seats[r].length = 그 row의 col 수. seats[0].length로 col을 구할 수도 있지만 ragged array일 수 있어 row마다 새로 구하는 게 안전.
💡 Q4에서 배울 점
row-major traversal: 바깥 loop = row, 안쪽 loop = col. 인덱스도 arr[row][col] 순서
경계 표기 정확: arr.length = row 수, arr[r].length = col 수. arr[r].length()는 String 문법 (X)
"각 row가 ___을 만족하는지"는 flag 변수 + break가 가독성·점수 모두 유리
2D 배열도 일반 배열처럼 .length 사용 (ArrayList의 .size()와 다름)