분류
1. 개요
차정우(배우 주상욱)가 타자를 치고 있다.
차정우: 한 줄로 짤 코드를 누가 열 줄로 만들어놨어요? 에러 찾기 힘들게. (잠시 뒤) 코드가 길어서 프로그램만 무거워졌잖습니까? 이러니까 서비스가 버벅대지.
드라마 앙큼한 돌싱녀에서 차정우 역을 맡은 주상욱이 천재 프로그래머의 실력을 보여주는 엄청난 타자 속도로 서비스를 복구하는 장면이다...
물론 훼이크다.
여기서의 웃음포인트는 두 가지인데, 처음에는 열심히 다다닥 코드를 치면서 말한 주상욱의 대사이다. 이게 왜 말도 안되는 소리냐면, 단순히 코드가 길어진다고 프로그램이 버벅대는 건 정말 프로그래밍의 기초도 모른다는 소리인데,[1] 저런 소릴 지금 속칭 천재 프로그래머이자 떠오르는 소프트웨어 회사의 사장이라는 사람이 하다니(...) 마치 판사가 되겠다는 사람이 법이 뭔지 모르는것과 똑같은 소리이다.
게다가, 동영상을 일시정지하고 모니터 화면에 띄워진 코드를 보면 고작 Java를 이용한 구구단 출력 예제다.
참고로 저 코딩 화면은 Notepad++에 띄워진 소스 코드를 백스페이스 꾹 눌러 지우는 장면을 촬영하고 그걸 거꾸로 돌린 것이다. 그래도 한글 워드프로세서가 아닌 프로그래머들이 애용(?)하는 에디터를 띄워놓은 건 칭찬할 만 하다. 비전공자는 저런 에디터가 있단 사실을 잘 모른다. 작가가 그래도 프로그래머가 어떻게 일하는지 조금은 공부했다는 반증. 아예 몰랐으면 cmd창 띄워놓고 dir /s 나 누르고 있었거나 더 심하게는 "명령을 찾을 수 없습니다" 에러메시지가 죽 내려가는 막장 화면을 보여줬을 수도 있다.
엄청난 타자의 정체(...)
|
위의 주석에 '게임 로딩 부분
자바 파일에는 public class 선언부가 딱 하나만 들어갈 수 있으므로(한 파일에 public class선언부가 두 개 이상되면 컴파일 에러가 난다) 174번째줄 위쪽은 같은 내용을 반복해서 복붙한 것일 가능성이 있다. 겨우 구구단 하나 출력하자고 private 클래스를 백 줄 넘게 작성했을 가능성은 거의 없다는 걸 생각해보면 그렇다. 코드 내부에서 다른 사용자 정의 객체를 생성하는 줄이 하나도 안 보이는 걸로 봐서 더더욱.
차정우의 코드를 분석하고 한 줄로 만든[아카이브] 사람이 있다.
위에 링크가 깨졌는데 이 코드다.
for(int i = 0; i < 36; i++) System.out.format(“%d X %d = %2d%c”, i%4+2, i/4+1, (i%4+2) * (i/4+1), i%4/3*4+9);
2. 제가 직접 한 번 해보겠습니다
위 코드의 174번째줄 위쪽이 뭔진 알 수 없지만 일단 화면에 나온 코드만 복원(?)해보면 이렇게 된다.
위 파일을 GuguClass.java 파일로 저장하고(대소문자 주의) javac GuguClass.java 해서 컴파일한 뒤에(JDK를 설치해야 함. 이거 설치하는거도 한 스트레스 하니까 정말 관심있는 사람만 해봅시다) java GuguClass 하면 결과를 볼 수 있다.
결과:
근데 이 코드에는 중복이 있으므로 더 줄일 수 있다.
차정우씨, 중복 코드가 있어서 프로그램만 무거워졌잖습니까? 이러니까 서비스가 버벅대지.
근데 3회 이하의 중복 코드는 중복해서 써놓는게 프로그램 수행 속도가 더 빠르다는 건 함정.
그냥 컴파일러한테 빠른 실행에 최적화하라고 시키면 알아서 코드를 손봐주신다. 고건 몰랐지?
결과는 같음.
더 줄일 수도 있다. 한 줄을 한 번에 찍는 방법이다.줄 수는 줄었지만 글자수는 늘었다.
더 줄일수도 있다 한줄이긴 한줄이다.
자바로는 이 이상 줄이긴 어려워 보인다. 문단 1에 한 줄로 만들었다는 사람은 Haskell을 사용한 듯 한데 언어를 바꿔치기하는 건 반칙.[4]
왜 반칙이냐면, 소스코드는 줄어들겠지만 두 언어를 모듈 수준에서 통합하기 위한 링커 스크립트가 무지막지하게 들어가기 때문이다. scala, clojure 등의 언어는 클래스 수준 호환성을 보장해서 링커 스크립트가 따로 필요없지만 이것도 빌드 스크립트가 길어지는 건 막을 수 없다.
public class GuguClass {
public static void main(String[] args) {
System.out.format("%n < gugu>%n");
for(int j=1; j<=9; j++) {
System.out.println();
for(int i=2; i<=5; i++) { // 2~ 5
System.out.format("%d X %d = %2d ", i, j, i * j);
}
}
System.out.println(); // 줄바꿈
for(int j=1; j<=9; j++) {
System.out.println();
for(int i=6; i<=9; i++) { // 6~ 9
System.out.format("%d X %d = %2d ", i, j, i * j);
}
}
System.out.println(); // 줄바꿈
}
}
위 파일을 GuguClass.java 파일로 저장하고(대소문자 주의) javac GuguClass.java 해서 컴파일한 뒤에(JDK를 설치해야 함. 이거 설치하는거도 한 스트레스 하니까 정말 관심있는 사람만 해봅시다) java GuguClass 하면 결과를 볼 수 있다.
결과:
< gugu>
2 X 1 = 2 3 X 1 = 3 4 X 1 = 4 5 X 1 = 5
2 X 2 = 4 3 X 2 = 6 4 X 2 = 8 5 X 2 = 10
2 X 3 = 6 3 X 3 = 9 4 X 3 = 12 5 X 3 = 15
2 X 4 = 8 3 X 4 = 12 4 X 4 = 16 5 X 4 = 20
2 X 5 = 10 3 X 5 = 15 4 X 5 = 20 5 X 5 = 25
2 X 6 = 12 3 X 6 = 18 4 X 6 = 24 5 X 6 = 30
2 X 7 = 14 3 X 7 = 21 4 X 7 = 28 5 X 7 = 35
2 X 8 = 16 3 X 8 = 24 4 X 8 = 32 5 X 8 = 40
2 X 9 = 18 3 X 9 = 27 4 X 9 = 36 5 X 9 = 45
6 X 1 = 6 7 X 1 = 7 8 X 1 = 8 9 X 1 = 9
6 X 2 = 12 7 X 2 = 14 8 X 2 = 16 9 X 2 = 18
6 X 3 = 18 7 X 3 = 21 8 X 3 = 24 9 X 3 = 27
6 X 4 = 24 7 X 4 = 28 8 X 4 = 32 9 X 4 = 36
6 X 5 = 30 7 X 5 = 35 8 X 5 = 40 9 X 5 = 45
6 X 6 = 36 7 X 6 = 42 8 X 6 = 48 9 X 6 = 54
6 X 7 = 42 7 X 7 = 49 8 X 7 = 56 9 X 7 = 63
6 X 8 = 48 7 X 8 = 56 8 X 8 = 64 9 X 8 = 72
6 X 9 = 54 7 X 9 = 63 8 X 9 = 72 9 X 9 = 81
근데 이 코드에는 중복이 있으므로 더 줄일 수 있다.
public class GuguClass {
public static void gugu(int c) {
for(int j=1; j<=9; j++) {
System.out.println();
for(int i=c; i<=c+3; i++) {
System.out.format("%d X %d = %2d ", i, j, i * j);
}
}
System.out.println(); // LF
}
public static void main(String[] args) {
System.out.format("%n < gugu>%n");
gugu(2); gugu(6);
}
}
결과는 같음.
더 줄일 수도 있다. 한 줄을 한 번에 찍는 방법이다.
public class GuguClass {
public static void gugu(int c) {
for(int j=1; j<=9; j++) {
System.out.format("%d X %d = %2d %d X %d = %2d %d X %d = %2d %d X %d = %2d\n", c, j, c++ * j, c, j, c++ * j, c, j, c++ * j, c, j, c * j);
c-=3;
}
System.out.println();
}
public static void main(String[] args) {
System.out.format("%n < gugu>%n");
gugu(2); gugu(6);
}
}
public class GuguClass {public static void main(String[] args) {System.out.format("%n < gugu>%n");for(int j=1; j<=9; j++) {System.out.println();for(int i=2; i<=5; i++) { /* 2~ 5*/System.out.format("%d X %d = %2d ", i, j, i * j);}} System.out.println(); /* 줄바꿈*/ for(int j=1; j<=9; j++) {System.out.println(); for(int i=6; i<=9; i++) { /* 6~ 9*/System.out.format("%d X %d = %2d ", i, j, i * j);}}System.out.println(); /* 줄바꿈*/}}
자바로는 이 이상 줄이긴 어려워 보인다. 문단 1에 한 줄로 만들었다는 사람은 Haskell을 사용한 듯 한데 언어를 바꿔치기하는 건 반칙.[4]
왜 반칙이냐면, 소스코드는 줄어들겠지만 두 언어를 모듈 수준에서 통합하기 위한 링커 스크립트가 무지막지하게 들어가기 때문이다. scala, clojure 등의 언어는 클래스 수준 호환성을 보장해서 링커 스크립트가 따로 필요없지만 이것도 빌드 스크립트가 길어지는 건 막을 수 없다.
3. 관련 문서
[1] 라인이 길다고 좋다는 뜻은 아니나, 프로그램의 상황에서 맞춰 얼마나 잘 짰는 가가 중요하다. 일반적인 라이브러리 함수 호출 한줄 보다, 프로그램의 상황에 맞춰 수십줄 늘여 쓴 코드가 더 효율적일 수 있다.[2] 대다수의 프로그래머들은 다크 테마를 얻은 IDE를 사용한다. IntelliJ IDEA라던가, Visual Studio Code라던가.[아카이브] https://web.archive.org/web/20140424044432/http://www.deculture.co.kr/archives/1522[4] ghci에서 바로 입력할 때는 main = ...으로 하지 말고 let main = ...으로 임시 선언한 후 다음줄에서 다시 main을 실행하면 제대로 출력 될 것이다.