KarelOOP2
작성중
목차 |
개요
Karel은 자바로 프로그래밍을 처음 배우는 학생들을 교육하기 위한 목적으로 스탠포드 대학에서 만든 라이브러리이다.
자바의 장점
자바는 다른 언어와 비교해서 다음과 같은 장점이 있다.
- 객체지향개념을 충실히 반영하고 있다.[1]
- 메모리를 직접 다루는 포인터 대신에 레퍼런스를 지원하여 메모리 참조를 잘못해서 발생하는 오류를 줄일 수 있다.[2]
- 프로그래머가 메모리에 만든 객체를 명시적으로 적지 않아도 가비지(garbage)가 되면 자비지 수집기(garbage collector)가 자동으로 메모리에 사용하지 않는 메모리를 반환한다.[3]
- 자바 가상기계(JVM; Java Virtual Machine)에서 실행되기 때문에 바이트코드 수준에서 호환성이 있다.[4]
- 스레드를 언어에서 기본적으로 제공하여, 스레드 프로그램을 작성하는 방법이나 동작 등에 일관성이 있다.
- 한 클래스에 속한 모든 코드는 클래스 내부에 모두 기술하여야 할 뿐만 아니라, 하나의 파일에 모두 기술하여야 한다. 그러므로 코드를 읽기가 쉽다.
- 안드로이드 스마트 폰에서 기본 언어로 자바가 채택되었다.[5]
자바를 배울 때 어려운 점
자바는 처음 배우는 학생들에게 다음과 같은 어려움이 있다.
KarelOOP2는 객체지향기법을 이용한 Karel 버전 2이다. 프로그램을 작성하기 위해서 아래 라이브러리를 다운로드 받아서 프로젝트에 포함시켜야 한다.
개요
- onInit() - Start button을 누르기 전에 불리는 메소드이다.
- onStart() - Start button을 누르면 실행되는 메소드이다. 기존 버전의 run() 메소드와 동일하다.
/* * Copyright 2020 Sangwon Park @ HUFS DISLab */ package hufs.dislab.test; import hufs.dislab.karel.IKarel; import hufs.dislab.karel.IKarelProgram; import hufs.dislab.karel.SimpleKarel; public class SimpleProgram extends IKarelProgram { IKarel karel; @Override protected void onInit() { karel = getIKarel(); } @Override protected void onStart() { moveToWall(); } public void moveToWall() { while (karel.frontIsClear()) karel.move(); } public static void main(String[] args) { IKarelProgram.main(args, new SimpleKarel()); } }
각주
- ↑ 객체지향개념에서 가장 중요한 클래스를 지원한다. 또한 재사용성을 증가시키는 다양한 기법을 제공한다. 먼저 이미 존재하는 코드를 재사용하기 위한 기본적인 기법으로 자바는 다른 객체지향언어와 동일하게 계승을 지원한다. 또한 알고리즘의 재사용성을 증가시키기 위하여 추상 클래스(abstract class)와 추상 메소드를 지원한다. 이 외에도 구현과 인터페이스를 분리하기 위하여 인터페이스(interface)를 지원한다. 이와 더불어 메소드는 C++의 가상 함수(virtual function)처럼 실행시에 해당 객체에 속한 메소드를 호출해주는 동적 바인딩(dynamic binding)을 한다.
- ↑ C, C++에서는 포인터 변수를 사용할 수 있다. 포인터 변수에 저장되는 것은 메모리 주소인데, 이 메모리 주소는 산술 연산을 통해 주소를 계산한 다음, 이 주소를 포인터 변수에 저장할 수 있다. 이때 계산을 잘못하여 포인터 변수에 저장된 주소가 유효하지 않은 것이라면 심각한 문제가 발생할 수 있다. 첫째 사용하고 있지 않은 혹은 해당 변수의 값을 저장한 곳이 아니 메모리를 참조할 경우, 엉뚱한 변수나 위치의 값을 변경할 수 있다. 둘째, 현재 실행중인 프로세스의 메모리 범위(virtual address space)를 벗어난 메모리를 접근할 경우 보안에 문제가 발생할 수 있기 때문에, 운영체제는 이러한 경우 잘못된 연산을 수행한 해당 프로세스를 강제로 종료시킨다. 이러한 메모리 참조를 잘못하여 발생하는 버그는 전체 버그 중에 많은 부분을 차지하기 때문에 자바에서는 포인터를 제공하지 않는다.
- ↑ 사용자가 임의의 시점에 메모리를 할당하는 방법으로 C에서는 malloc 함수를 제공하고, C++에서는 new 연산자를 제공한다. 예를 들어
Person* person = (Person*)malloc(sizeof(struct Person)); /* C 스타일 */ Person* person = new Person(); // C++ 스타일
와 같이 메모리를 할당한다. 이때 C에서는 Person이 구조체(struct)로 정의되었고, C++에서는 클래스로 정의되었다고 가정하자.
이 메모리가 더 이상 필요없을 경우 C에서는 free 함수를 이용해서 반환하고, C++에서는 delete 연산자를 이용하여 메모리를 반환한다. 이 예는 아래와 같다.
free(person); /* C 스타일 */ delete person; // C++ 스타일
만약 free나 delete를 이용하여 반환하지 않는 경우의 예를 통해 메모리 관리에서 발생하는 문제점을 알아보자.
Person* person = (Person*)malloc(sizeof(struct Person)); /* 객체1*/ person = (Person*)malloc(sizeof(struct Person)); /* 객체2 */
위 코드에서 객체1을 생성한 후 반환하지 않고 객체2를 동일 변수로 가리키게 되면 객체1은 더 이상 참조할 수 없게 된다. 하지만 이 객체는 반환을 하지 않았기 때문에 메모리에서 공간을 차지하고 있게 된다. 하지만 사용할 수 없는(접근할 수 없는) 메모리가 있게 되어 메모리를 낭비하게 되는 것이며, 이를 메모리 누수(memory leak)가 발생했다고 한다. 메모리 누수가 없도록 하려면 아래 코드와 같이 작성해야 한다.
Person* person = (Person*)malloc(sizeof(struct Person)); /* 객체1*/ free(person); /* 객체1 반환 */ person = (Person*)malloc(sizeof(struct Person)); /* 객체2 */
이와 같은 문제로 인하여 자바에서는 객체1과 같이 더 이상 참조할 수 없는 메모리를 가비지(garbage)라고 하며 이는 자동으로 제거된다. 이러한 제거는 즉시 일어나는 것이 아니고, 언제 제거될지 예측할 수 없다. 현재의 JVM은 힙 메모리가 부족할 때 가비지 수집기가 가비지를 제거한다.
- ↑ C 프로그램을 컴파일하면 특정 머신에서 실행할 수 있는 기계어가 생성된다. 기계어는 CPU 마다 형식이나 명령어 종류가 다르다. 또한 운영체제(OS)에 따라 프로그램을 메모리에 적재(로드)하는 방법이 다르다. 이처럼 CPU와 OS를 합하여 특정 머신이라고 부른다. 예를 들어 인텔칩에서 실행할 수 있는 기계어와 ARM 칩에서 실행할 수 있는 기계어 형식이 다르다. 이 뿐만 아니라 동일 CPU라고 하더라도 OS가 달라도 생성되는 기계어 코드 형식이 달라진다. 예를 들어 인텔칩을 사용하는 것으로 Windows, Mac, Linux가 있지만 각각의 기계에서 실행되는 기계어 코드가 다른 기계에서 실행되지 않는다. 그 이유는 기계어를 메모리에 로드할 때 사용하는 자료구조 등 방법에 차이가 있기 때문이다. 즉, 보통 프로그램을 컴파일하면 해당 머신에서 동작하는 기계어가 만들어진다. 하지만 자바는 특정 머신에 독립적인 기계어가 생성되므로 기존의 기계어와 구분짓기 위해서 자바의 기계어를 바이트코드라고 부른다.
- ↑ 현재는 Kotlin도 지원하고 있음