J2ME쪽 JSR모음

java core 2005. 1. 24. 19:20

The J2ME Universe Today

The current universe of configurations, profiles and optionalpackages is shown in the diagram below. The tables immediately followingprovide more details about the abbreviations in the figure.

J2ME Overview
J2ME Overview
Configurations
JSR 30 CLDC 1.0 Connected, Limited Device Configuration
JSR 139 CLDC 1.1 Connected, Limited Device Configuration 1.1
JSR 36 CDC Connected Device Configuration
JSR 218 CDC 1.1 Connected Device Configuration 1.1
Profiles
JSR 37 MIDP 1.0 Mobile Information Device Profile
JSR 118 MIDP 2.0 Mobile Information Device Profile 2.0
JSR 75 PDAP PDA Profile
JSR 46 FP Foundation Profile
JSR 219 FP 1.1 Foundation Profile 1.1
JSR 129 PBP Personal Basis Profile
JSR 217 PBP 1.1 Personal Basis Profile 1.1
JSR 62 PP Personal Profile
JSR 215 PP 1.1 Personal Profile 1.1
JSR 195 IMP Information Module Profile
JSR 228 IMP-NG Information Module Profile - Next Generation
Optional Packages
JSR 75 PIM PDA Optional Packages for the J2ME Platform
JSR 82 BTAPI Java APIs for Bluetooth
JSR 120 WMA Wireless Messaging API
JSR 205 WMA 2.0 Wireless Messaging API 2.0
JSR 135 MMAPI Mobile Media API
JSR 164   JAIN SIMPLE Presence
JSR 165   JAIN SIMPLE Instant Messaging
JSR 172   J2ME Web Services
JSR 177 SATSA Security and Trust Services API for J2ME
JSR 179   Location API for J2ME
JSR 180 SIP SIP API for J2ME
JSR 184 3D Mobile 3D Graphics API for J2ME
JSR 186   JAIN Presence
JSR 187   JAIN Instant Messaging
JSR 190   Event Tracking API for J2ME
JSR 209   Advanced Graphics and User Interface Optional Package for J2ME Platform
JSR 211 CHAPI Content Handling API
JSR 213   Micro WSCI Framework for J2ME
JSR 214   Micro BPSS for J2ME Devices
JSR 226   Scalable 2D Vector Graphics API
JSR 229   Payment API
JSR 230   Data Sync API
JSR 232   Mobile Operational Management
JSR 234   Advanced Multimedia Supplements
JSR 238   Mobile Internationalization API
JSR 239   Java Bindings for OpenGL ES
JSR 246   Device Management API
JSR 253   Mobile Telephony API (MTA)

As the diagram shows, J2ME has two main branches.The first is based on the Connected, Limited Device Configuration (CLDC). This configuration is for small wireless devices with intermittent network connections, like pagers, mobile phones, and Personal Digital Assistants (PDAs).The Mobile Information Device Profile (MIDP), which is based on CLDC, was the first finished profile and thus the first finished J2ME application environment.MIDP-compliant devicesare widely available.

The other major branch of the J2ME tree is based on the Connected Device Configuration (CDC). This configuration is for larger devices (in terms of memory and processingpower) with robust networkconnections. Set-top boxes and internet appliances are good examples of CDCdevices, although high-end PDAs like the Sharp Zaurus also fit thisconfiguration well. The Foundation Profile extends CDC and serves as the basis for several other profiles. It provides fundamental APIs gleaned from J2SE, including classes and interfaces from java.lang, java.io, java.security, java.util, and more. For a list of J2ME terms and definitions, see our glossary.

Optional packages bubble like a froth above the CLDCand CDC branches of J2ME. These provide all sorts of capabilitiesranging from Bluetooth communication through web services and instantmessaging. Look in the table for links to the specifications themselves.

For a thorough look at J2ME, see:

The world of wireless Java technology also includes Java Card, for smart cards. For more information on Java Card, see:


About Stacks and JSR 185

Devices implement a complete software stack, which usually consists of aconfiguration, a profile, and optional APIs. First generation J2ME mobile phonesusually implemented the following software stack:

Example J2ME Stack
Example J2ME Stack

Given the plethora of configurations, profiles, and especially optionalpackages, how does a developer know what to expect on a device? JSR 185,Java Technology for the Wireless Industry, addresses this question byassembling other building blocks into a complete applicationenvironment. JSR 185 mandates CLDC 1.0 or 1.1, MIDP 2.0, and WMA. Supportfor MMAPI is optional. This helps nail things down for developers; on aJTWI device, the developer has a clear understanding of what APIs willbe available. The following figure shows a JSR 185 stack:

JSR 185 Stack
JSR 185 Stack

For more information on JSR 185, see:


The Scope of Wireless Java Technology

Wireless Java technology is the intersection of two vast worlds, wireless data communications and the Java platform. Wireless Java technology spans parts ofJava Card, J2ME, J2SE, and J2EE. That said, some commonmisconceptions about wireless Java technology need clearing up:

  • Wireless Java technology and J2ME are not the same thing. On the onehand, J2ME encompasses more than just wireless devices. While some parts of J2ME are expressly designed for wireless devices, other parts are not--CDC devices are likely to have standard Ethernet connections. On the flip side, wireless Javatechnology isnot confined to J2ME alone. You could have a laptop or palmtop computer running J2SE applications, connecting to other computers via an 802.11 LAN.

  • MIDP is not all of J2ME.MIDP is the first finished profile and has the first installed base of devices out in the world, so people sometimes assume that you are talking about MIDP whenever you talk about J2ME. As you can see from the diagram above, though, J2ME has many facets; MIDP just happened to cross the finishline first.

  • MIDP is not all of wireless Java technology.The Java platform offers plenty of choices forwireless programming: Personal Profile, J2SE on wireless devices, even thePDA Profile.

For other perspectives on wireless Java technology, select:


Why Use the Java Platform for Wireless Development?

The Java platform is an excellent choice for wireless development for many reasons. Here are three compelling advantages:

  • The Java platform is safe. Java code always executes within the confines of theJava Virtual Machine1, which provides a safe environment for executing downloaded code. A binary application could freeze a device or crash it (imagine a blue screen on your mobile phone!) By contrast, at worst a Javaapplications can bring down only the Virtual Machine, not the device itself.
  • The Java language encourages robust programming. The garbage collector saves programmers countless hours of hunting down memory leaks. Likewise, the Javalanguage's exception mechanisms encourage programmers to create robust applications.
  • Portability is a big win for wireless Java technology. A single executablecan run on multiple devices. For example, when you write a MIDlet (a MIDP application) it will run on any device that implements the MIDP specification. Given the dizzying profusion of wireless devices, not havingto maintain a plethora of implementationsis a big advantage. Even if a Javaapplication makes use of vendor specific APIs, applications writtenusing the Java programming language are inherently easier to modify foranother device than applications written in C or C++.

    A second benefit ofportability is the ease of delivering applicationsto a device over the wireless network (sometimes called Over-the-air, or OTA, provisioning). Binary applications can be moved from a server onto a device, too, but not safely.Because Java code runs inside the Java Virtual Machine1, code that is downloaded from the network can be run safely. Binary code cannot be contained at execution time andis much less safe.
For more information on the motivations for using the Java platform for wirelessdevelopment, select:

The Market for Wireless Services

The market for wireless applications and services is huge. This market can be divided into two segments:

  • The consumer segment consists of games, location-based services, productivity applications, and other generally useful applications. In the near term, these applications will be controlled and distributed by wireless carriers.

  • The custom business segment will require custom development ofwireless clients to connect to existing enterprise applications. Many of these will be wireless applications that use middleware to access company databases.

Where to Go Next

Perhaps the best next step toward getting a good grip on wireless Javatechnology is to create some:

  • Wireless Development Tutorial Part I
    Learn how to set up a development environment for buildingJ2ME client applications. You'll install the tools, then build andrun a simple MIDlet. This article has all the information you need to getstarted with J2ME development.
  • Wireless DevelopmentTutorial Part II
    In this article, you'll learn how to set up a Java servlet developmentenvironment, either Tomcat or the J2EE Reference Implementation server.You'll write a servlet and create a MIDlet that makes a networkconnection to the servlet.

'java core' 카테고리의 다른 글

Threads from aritma  (0) 2005.02.12
Reference object model from java world  (0) 2005.01.28
Garbage collection from javaworld  (0) 2005.01.28
자바 코드 컨벤션  (0) 2005.01.24
Java 코딩 지침  (0) 2005.01.24
Posted by '김용환'
,

Java 코딩 지침

java core 2005. 1. 24. 19:17

Java 코딩 지침

본 문서는 Geotechnical Software 에서 작성한 2004 년 1월 버전의 Geosoft 의 Java Programming Style Guidelines 문서를 근간으로 하여 Sun 의 코딩 표준 권고안 및 기타 표준안들을 참고하여 작성한 것입니다. 개선된 사항을 반영하기 위하여 예고없이 변경될 수 있으며 본 문건을 통해 발생한 문제에 대해 책임을 지지 않습니다.


목 차


1 들어가기

본 문서는 Java 개발자 커뮤니티 내에서 보편적인 Java 코딩 권고안들을 나열하고 있습니다. 이 권고안들은 이미 널리 표준으로 받아들여지고 있는 몇몇 문건들(예를 들면, [1], [2], [3], [4], [5])에 기반을 두고 있으며, 전세계의 수 많은 소프트웨어 전문가들의 피드백을 받아들여 작성되었습니다. 기존 지침들이 갖는 주된 단점은, 지침들이 너무 일반적이다보니 보다 구체적이고 상세한 규칙들(예를 들면, 명명 규칙:naming rule)이 확립되어야 할 필요가 있다는 것입니이다. 따라서, 본 지침은 여타의 지침들에 비하여 프로젝트의 코드 검토 단계에 사용하기 용이하도록 각 항목마다 주석과 예제를 두었습니다. 추가적으로, 일반적으로 프로그래밍 권고안들은 코딩 스타일 이슈와 언어 고유한 기술적 이슈들을 혼합하여 기술함으로써 혼란을 초래하는 경향이 있기 때문에, 본 문서에서는 Java 언어의 기술적인 권고안에 대해서 일절 언급하지 않고 오로지 프로그래밍 스타일에 대해서만 다루고자 합니다. IDE 도구를 사용하는 개발 환경에서는 접근제한자, 키워드/문법 하일라이팅, 자동 포맷팅 등을 제공하여 가독성을 향상시킬 수 있을 것입니다. 하지만 프로그래머라면 절대로 그러한 기능에 종속되어서는 안됩니다. 소스 코드를 단순히 IDE 도구 내에서 개발되는 코드뿐 아니라 더 큰/다양한 범위로 확대하여야 하며, 어떠한 IDE 도구를 사용하는지와 상관없이 가독성을 극대화할 수 있도록 소스 코드를 작성하여야만 합니다.

1.1 권고안 레이아웃

권고안들은 주제별로 그룹지어져 있으며, 각각의 권고안들은 코드 검토 시 손쉽게 참조할 수 있도록 숫자를 부여하였습니다. 본 문서에서 사용할 권고안 레이아웃은 다음과 같습니다:

지침에 대한 간략한 설명
적용이 가능한 경우, 적용사례
동기(motivation), 배경 및 추가적인 정보

동기 섹션은 중요합니다. 코딩 표준과 지침들은 일종의 "성전(聖戰)" 과 같은 성격을 띄기 마련입니다. 따라서 각 권고안의 배경을 언급하는 것은 중요합니다.

1.2 권고안의 중요도

지침 섹션에서 사용되는 반드시 한다(must), 한다(should), 할 수 있다(can) 와 같은 용어들은 특별한 의미를 가집니다. 반드시 한다는 필히 준수해야 한다는 것을, 한다는 강한 권고를, 할 수 있다는 일반적인 지침을 의미합니다.

2 일반적인 지침들

1. 가독성을 증진시킬 수 있는 타당한 이유가 있다면 본 지침을 어길 수도 있다.
 
본 지침의 궁극적인 목표는 가독성을 향상시키는 것입니다. 가독성이 향상되면 이해가 용이해지고 유지보수가 수월해지며 일반적으로 코드의 품질도 좋아집니다. 일반적인 지침을 거론하는 본 지침서에서 모든 상황들을 감안한 지침을 제공해 드릴 수 없기 때문에, 프로그래머의 판단에 의하여 가변적으로 활용하실 수 있습니다.

3 명명 관례(Naming Conventions)

3.1 일반적인 명명 관례

2. 패키지를 표현하는 이름은 모두 소문자를 사용한다.
mypackage, com.company.application.ui
이 패키지 명명 관례는 Java 핵심 패키지들의 명명에 Sun 社 가 사용하고 있는 것입니다. 패키지 이름의 시작부는 반드시 도메인 이름으로 소문자를 사용해야만 합니다.
3. 타입을 표현하는 이름은 대소문자를 혼용할 수 있지만, 반드시 명사를 사용하고 시작 글자를 대문자로 지정한다.
Account, EventHandler
Java 개발자 커뮤니티에서 사용하는 일반적인 관습이며, Sun 社 가 Java 핵심 패키지들의 타입 명명에 사용하고 있는 것입니다.
4. 변수의 이름은 대소문자를 혼용할 수 있지만 반드시 소문자로 시작한다.
account, eventHandler
Java 개발자 커뮤니티에서 사용하는 일반적인 관습이며, Sun 社 가 Java 핵심 패키지들의 변수이름 명명에 사용하고 있는 것입니다. 변수와 타입을 손쉽게 구별할 수 있도록 하면, 이름의 충돌이 발생하는 것을 효과적으로 해결할 수 있게 됩니다. 예) Account account; // 선언문
5. 상수(final 변수)를 표현하는 이름은 반드시 모두 대문자로 지정하되 '_' 를 사용하여 단어들을 구분한다.
MAX_ITERATIONS, COLOR_RED
Java 개발자 커뮤니티에서 사용하는 일반적인 관습이며, Sun 社 가 Java 핵심 패키지에 사용하고 있는 것입니다. 일반적으로, 이러한 상수의 사용은 최소화해야만 합니다. 대다수의 경우 상수 변수를 메소드로 구현하는 것이 더 낫습니다:
int getMaxIterations()     // NOT: MAX_ITERATIONS = 25
{
  return 25;
}

이러한 양식이 보다 읽기에 편하며, 클래스의 값을 참조하는 일관된 인터페이스를 제공할 수 있다는 장점을 가집니다.
 
6. 메소드의 이름은 대소문자를 혼용할 수 있지만 반드시 동사를 사용하며 소문자로 시작한다.
getName(), computeTotalWidth()
Java 개발자 커뮤니티에서 사용하는 일반적인 관습이며, Sun 社 가 Java 핵심 패키지에 사용하고 있는 것입니다. 이 방식은 변수의 이름을 지을 때 사용하는 관례와 동일합니다. 하지만, Java 에서는 이미 특별한 양식(getter/setter, 동사로 시작하는 이름, JVM Spec, 등)에 의거하여 메소드는 변수를 구분합니다.
7. 축약형(Abbreviation) 과 두문자어형(頭文字語: Acronym) 을 이름에 사용할 경우에는 전부 대문자로 지정하지 않는다.
exportHtmlSource();    // exportHTMLSource(); 가 아님
openDvdPlayer();       // openDVDPlayer(); 가 아님
축약형 혹은 두문자어형 이름을 모두 대문자로 지정하게 되면 앞서 기술한 명명 지침들과 충돌이 발생하게 됩니다 (대표적으로 상수에 대한 명명 지침과 혼동될 수 있습니다). 그렇다고 이 유형의 이름을 dVD, hTML 등 과 같이 다양한 형태로 지정할 경우에는 가독성이 떨어집니다. 또 다른 문제점으로는 위의 예제에서 살펴볼 수 있는 바와 같이, 이 유형의 이름이 다른 이름과 결합되는 경우 가독성이 극도로 나빠진다는 것입니다. 후속하는 단어가 있을 경우는 더욱 각별히 주의해야 합니다.
8. private 접근 제한자를 갖는 클래스 변수에 '_' 접미사를 사용한다.
class Well
{
  private int  depth_;
  ...
}
변수의 이름이나 타입과는 별개로, 변수의 범위(scope)는 매우 중요한 특성입니다. 접미사 '_' 를 사용함으로써 클래스 범위의 변수(로컬 변수가 아닌)임을 쉽게 구별할 수 있게 됩니다. 클래스 변수는 메소드 내에서 선언되는 로컬 변수에 비해 중요도가 높기 때문에 프로그래머가 각별히 주의해야 합니다. '_' 를 사용하는 명명 규칙은 부가적으로 setter 메소드에서의 이름 충돌문제를 깔끔하게 해결해 줍니다: void setDepth (int depth)
{
  depth_ = depth;
}
제기될 수 있는 이슈거리는 '_' 를 변수의 접두사로 쓸 것인가 접미사로 쓸 것인가에 대한 것입니다. 두 가지 모두 일반적으로 널리 사용되는 방법이기는 합니다만, 이름을 읽기 편하다는 측면에서 후자의 것을 권고합니다. 변수의 이름에 볌위를 식별할 수 있도록 하자는 제안은 한 동안 많은 논쟁을 불러일으켰습니다. 그런데 현재에는 이러한 방법이 수용되어 전문 개발자 커뮤니티에서도 일반적인 관례로 점차 정착이 되고 있는 것 같습니다.
 
9. 일반적인 변수의 이름은 타입의 이름과 동일하게 지정한다.
void setTopic (Topic topic)      // void setTopic (Topic value) 이 아님
                                 // void setTopic (Topic aTopic) 이 아님
                                 // void setTopic (Topic x) 이 아님

void connect (Database database) // void connect (Database db) 가 아님
                                 // void connect (Database oracleDB) 가 아님
용어나 이름의 수를 줄이는 것이 코드의 복잡도를 줄여줍니다. 또한 변수의 이름만으로도 그 타입을 손쉽게 유추할 수 있게 해준다는 장점도 있습니다. 만약 어떠한 이유에선가 이러한 관례가 맞지 않는 것처럼 느끼신다면, 이는 분명 타입이름 자체를 잘못 지정한 것입니다. 일반적이지 않은 변수들은 각기 나름의 역할(role)을 가지고 있습니다. 이러한 변수들은 역할과 변수의 타입을 결함하여 이름을 짓곤 합니다. Point startingPoint, centerPoint;
Name  loginName;

 
10. 모든 이름은 영어로 작성한다.
fileName;    // filNavn 나 파일이름 이 아님
국제적인 개발에 있어서 영어가 선호되기 때문입니다.
11. 넓은 범위에 영향을 미치는 변수는 긴 이름을 부여하고, 좁은 범위의 변수는 짧은 이름을 부여한다 [1].
 
임시 저장공간이나 인덱스로 사용되는 Scratch variable (주: 의미있는 값을 갖지 않고 그때그때 상황에 따라 값들을 잠시 보관해 두기 위한 변수로, 대개 보유한 값이 얼마 후에 의미가 없어지거나 삭제됨)들은 매우 짧은 이름을 부여하십시요. 프로그래머가 그러한 변수들을 읽음과 동시에, 이 변수는 몇 라인 뒤에 그 값이 유효하지 않을 것임을 짐장할 수 있게 해야 합니다. 보편적인 scratch variable 로는 정수를 저장하는 i, j, k, m, n 가 있고 문자를 저장하는 c, d 가 있습니다.
12. 호출하려는 객체의 이름을 통해 의미를 짐작할 수 있다면, 메소드의 이름을 간략화할 수 있다.
line.getLength();    // line.getLineLength(); 가 아님
클래스 선언 시에는 후자의 것이 자연스럽지만, 사용할 때에는 위 예에서 볼 수 있듯이 중언부언하는 느낌을 줄 수 있습니다.

3.2 특수한 명명 관례

13. get/set 이라는 용어는 반드시 애트리뷰트에 직접 접근하는 메소드에 사용한다.
employee.getName();
matrix.getElement (2, 4);
employee.setName (name);
matrix.setElement (2, 4, value);
이 접근 메소드 명명 관례는 Java 핵심 패키지들의 명명에 Sun 社 가 사용하고 있는 것입니다. 실제 자바빈즈를 작성할 때에는 이 명명규칙을 준수해야 합니다.
14. is 접두사를 불리언 변수와 메소드에 사용한다.
isSet, isVisible, isFinished, isFound, isOpen
이 불리언 메소드와 변수에 대한 명명 관례는 Java 핵심 패키지들의 명명에 Sun 社 가 사용하고 있는 것입니다. 실제 자바빈즈를 작성할 때에는 이 명명규칙을 준수해야 합니다. is 접두사를 사용함으로써 일반적으로 statusflag 와 같은 좋지 않은 불리언 이름을 선택하는 문제를 해결할 수 있습니다. isStatusisFlag 는 간결하지만 프로그래머에게 의미를 풍부하게 전달할 수 없다는 점에서 바람직하지 못합니다. 일부 상황에서는 is 접두사가 아닌 보다 더 적합한 접두사를 사용할 수도 있습니다. has, can, should 접두사들을 그런 대안으로 활용하실 수 있을 것입니다: boolean hasLicense();
boolean canEvaluate();
boolean shouldAbort = false;

 
15. compute 라는 용어는 무엇인가를 계산(시간이 소요되는)하는 메소드에 사용할 수 있다.
valueSet.computeAverage();  matrix.computeInverse()
프로그래머로 하여금 보는 즉시 이 메소드는 잠재적으로 시간이 소요되는 작업을 수행하고 있다는 것을 주지심으로써, 이 메소드의 결과를 반복해서 사용하고자 할 경우에 프로그래머는 계산된 값을 캐시해 둘 것을 고려하게 만들 수 있습니다. 용어를 일관성있게 사용하는 것은 가독성을 높이는 지름길입니다.
16. find 라는 용어는 무엇인가를 찾는 메소드에 사용할 수 있다.
vertex.findNearestVertex();   matrix.findMinElement(); 
프로그래머로 하여금 보는 즉시 이 메소드는 최소한의 계산을 통해 요청하는 결과를 찾을 수 있는 메소드라는 것을 알려주십시오. 용어를 일관성있게 사용하는 것은 가독성을 높이는 지름길입니다.
17. initialize 라는 용어는 객체나 개념이 확립되어지는 곳에 사용할 수 있다.
printer.initializeFontSet();
미국식 initialize 가 영국식 initialise 보다 바람직합니다. init 라는 축약형 이름은 절대로 사용하지 마십시오.
18. JFC (Java Swing) 변수들은 각 컴포넌트의 타입을 접두사로 사용한다.
widthScale, nameTextField, leftScrollbar, mainPanel, fileToggle, minLabel, printerDialog
변수의 이름 자체가 자신이 어떤 타입의 변수인지 알려주기 때문에 객체가 어떤 자원인지 쉽게 알 수 있습니다.
19. 컬렉션의 이름은 반드시 복수형으로 사용한다.
vertex (one vertex),   vertices(a collection of vertices)
account (one account),    accounts(a collection of accounts)
 
여기서의 컬렉션은 java.util.Collection 변수와 단순 배열과 같은 Collection 의 자손들을 의미합니다.
20. n 접두사는 객체의 개수를 나타내는 변수에 사용한다.
nPoints, nLines
이 표기법은 개체의 개수를 나타내는 수식의 표기법에서 차용한 것입니다. Sun 社 는 Java 핵심 패키지에서 이런 용도로 num 접두사를 사용한다는 것에 주목해 보겠습니다. 이는 필경 number of 에 대한 축약어를 의미할 것입니다만, 그 보다는 number 를 연상시킴으로써 변수 이름을 이상하게 만들거나 혼동을 불러일으킬 수 있습니다. 만약 "number of" 를 더 선호하신다면, n 대신에 numberOf 접두사를 사용하실 수도 있을겁니다. num 접두사는 사용하시지 않기를 강력하게 권합니다.
 
21. No 접미사는 엔터티 번호를 나타내는 변수에 사용한다.
tableNo, employeeNo
이 표기법은 엔터티의 번호를 나타내는 수식의 표기법에서 차용한 것입니다. 또 다른 우아한 표기 방법으로는 i 을 접두사로 사용하는 것입니다: iTable, iEmployee. 이 방법은 효과적으로 변수에 iterator 로의 역할을 부여하게 됩니다.
 
22. Iterator 변수들은 i, j, k 등 과 같은 이름을 사용한다.
while (Iterator i = pointList.iterator(); i.hasNext(); ) {
  :
}

for (int i = 0; i < nTables; i++) {
  :
}
 
이 표기법은 iterator 를 나타내는 수식의 표기법에서 차용한 것입니다. j, k 등과 같은 이름의 변수들은 중첩된 반복문 내에서만 사용합니다.
 
23. 대응하는 단어가 있는 이름은 반드시 함께 사용한다 [1].
get/set, add/remove, create/destroy, start/stop, insert/delete, increment/decrement, old/new, begin/end, first/last, up/down, min/max, next/previous, old/new, open/close, show/hide
대칭을 이루도록 함으로써 복잡도를 줄일 수 있습니다.
24. 축약형 이름의 사용은 피한다.
computeAverage();     // compAvg(); 가 아님
고려해 볼 두 종류의 단어들이 있습니다. 먼저 프로그래밍 언어를 구사하는 데에 있어 빈번하게 사용되는 일반적인 단어들이 있습니다. 이들 단어는 절대로 축약형을 사용하지 말아야 합니다: command    대신 cmd
copy      
대신
cp
point     
대신
pt
compute   
대신
comp
initialize
대신
init
등등.
그 다음, 도메인에서 사용하는 특수한 두문자어나 축약어들은 축약형을 그대로 사용합니다. 이들 구문은 굳이 풀어 나열하지 않고 축약형을 사용하십시오. 다음과 같이 사용하시면 안됩니다: html 대신
HypertextMarkupLanguage
cpu 
대신
CentralProcessingUnit
pe  
대신
PriceEarningRatio
등등.
 
25. 불리언 변수 이름은 절대로 부정적인(거짓인) 이름을 사용하지 않는다.
boolean isError;    // isNotError 가 아님
boolean isFound;    // isNotFound 가 아님
문제는 불리언 변수에 부정적인 이름을 사용할 경우, not 연산자를 사용할 경우 부정의 부정을 계산해야 하는 혼동을 초래한다는 것입니다. 예를 들어, !isNotError 에서 처럼, 신속하게 이것이 무엇을 의미하는지 인지할 수 없게 됩니다.
26. 관련있는 상수(final 변수)들은 공통 타입의 이름을 접두사로 사용하여 그룹핑한다.
final int COLOR_RED   = 1;
final int COLOR_GREEN = 2;
final int COLOR_BLUE  = 3;

final int MOOD_HAPPY  = 1;
final int MOOD_BLUE   = 2;
 
이 표기방법은 상수들이 어디에 속해있는지 상수가 무엇을 나타내고 있는지 식별하는데 도움이 됩니다.
27. 예외(Exception) 클래스들은 Exception 이라는 접미사를 사용한다.
class AccessException
{
  :
}
 
사실 예외 클래스들은 프로그램의 핵심 디자인에 해당되지 않기 때문에, 이와 같은 방식으로 이름을 지정함으로써 상대적으로 클래스들 중에서 눈에 띄게(구분을 용이하게) 해두는 것이 좋습니다. 이 명명 관례는 Java 기본 라이브러리들에 Sun 社 가 사용하고 있는 표준입니다.
28. 디폴트 인터페이스 구현은 Default 라는 접두사를 사용할 수 있다.
class DefaultTableCellRenderer
implements TableCellRenderer
{
  :
}
 
이 방법은 인터페이스 메소드들에 대한 디폴트 처리작업을 제공하는 구현물에, 간단하게 이름을 부여하는 방법으로 널리 사용되고 있는 방법입니다. Default 접두사를 클래스의 이름에 부여하는 이 명명 관례는, Java 기본 라이브러리들에 Sun 社 가 채택한 방식입니다.
29. 함수(객체/결과를 리턴하는 메소드)의 이름은 '처리 후 무엇을 리턴하는지'를 의미하고, 프로시저(void 메소드)의 이름은 '무엇을 처리하는지'를 의미한다.
 
메소드가 무엇을 하는지. 의도하지 않는 것들이 무엇인지를 명확하게 해주기 때문에, 가독성을 높여줍니다. 또한 이 방법은 예기치 못한 부작용(side effect)들로부터 코드를 명쾌하게 유지시켜 줄 수 있습니다.

4 파일

30. Java 소스 파일의 확장자는 .java 이다.
Point.java
Java 개발툴에 의해 강제적으로 준수해야 하는 규칙입니다.
31. 클래스는 각각의 파일에 선언하며, 클래스의 이름과 파일의 이름이 동일해야 한다. 이너(inner) 클래스나 private 으로 선언된 secondary 클래스들은 굳이 별도의 파일로 구분하지 않고도 primary 클래스와 같은 파일 내에서 선언할 수 있다.
 
Java 개발툴에 의해 강제적으로 준수해야 하는 규칙입니다.
32. 파일의 내용물은 반드시 80 컬럼을 벗어나지 않는다.
 
80 컬럼은 다양한 편집기, 프린터, 터미널 에뮬레이터, 디버거에서도 일반적인 길이로, 각 라인이 80 컬럼을 넘지 않도록 소스코드를 작성한다면 다양한 환경의 여러 개발자들과 파일을 공유해서 사용할 수 있습니다. 이는 프로그래머들 간에 파일을 전달하였을 때 의도하지 않은 들여쓰기나 개행문자가 포함되어 가독성이 떨어지는 것을 예방합니다.
33. 탭(TAB) 문자나 페이지 구분(page break) 문자와 같은 특수한 문자들은 절대로 사용하지 않는다.
 
이러한 문자들은 프로그래머가 여럿이거나 다수의 플랫폼에서 개발하는 환경에서, 편집기 별, 프린터 별, 터미널 에뮬레이터 별, 디버거 별로 지정된 설정에 따라 소스코드를 들쭉날쭉하게 만들어 가독성을 떨어뜨리게 됩니다.
34. 여러 라인으로 분리한 문장들은 반드시 명확하게 만든다 [1].
totalSum = a + b + c +
           d + e);
function (param1, param2,
          param3);
setText ("Long line split" +
         "into two parts.");
for (tableNo = 0; tableNo < nTables;  
     tableNo += tableStep)
한 문장이 80 컬럼을 벗어날 때 라인을 분리해서 작성하게 됩니다. 어떻게 라인을 분리해야 하는지에 대한 엄격한 규칙을 제시하기는 어렵습니다만, 위 예제들은 일반적인 힌트를 제공해줄 것입니다: 일반적으로:
  • 콤마(,) 뒤에서 분리한다.
  • 연산자 뒤에서 분리한다.
  • 이전 라인에서의 표현식 시작 부분에 맞추어 정렬한다.

5 문장

5.1 package 와 import

35. package 문은 반드시 파일의 첫번째 라인에 나타나야 하며, 모든 파일은 특정 패키지에 소속된다.
 
package 문의 위치는 Java 언어 코딩 표준에서 권고하고 있는 것입니다. 모든 파일들을 실제 패키지(디폴트 패키지보다는 이름이 있는 패키지)에 두는 것은 Java 객체 지향 프로그래밍 기법에 도움을 줍니다.
36. import 문은 반드시 package 문 뒤에 나와야 한다. import 문은 가장 기본이 되는 패키지들 부터 순차적으로 정렬하며, 관련있는 패키지들은 함께 묶어 두고 빈 라인을 삽입하여 일목요연하게 정리한다.
import java.io.*;
import java.net.*;

import java.rmi.*
import java.rmi.server.*;

import javax.swing.*;
import javax.swing.event.*;

import org.linux.apache.server.*;
 
import 문의 위치는 Java 언어 코딩 표준에서 권고하고 있는 것입니다. 많은 import 문들을 정렬해두면 편리하게 import 문들을 검토할 수 있고, 이를 통하여 현재 이 패키지가 어떤 용도로 설계되었는지를 쉽게 파악할 수 있습니다. 또한 import 문을 그룹핑하면 관련된 정보들을 공통의 유닛으로 관리할 수 있기 때문에 복잡도를 줄일 수 있습니다.
37. import 문을 사용할 때에는 와일드 카드 문자(*)를 사용하지 않는다.
import java.io.*;

대신:

import java.io.File;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
 
사실 #36 의 예제와 같이 import 문에 와일드 카드 문자인 * 를 사용하는 것은, 프로그래머에게는 편리할지 모르지만 성능에 얼마간 영향을 미치게 됩니다. 더구나 import 문만 보고도 정확하게 현재 클래스/인터페이스가 어떤 작업을 할 것인지 예측할 수 있도록 하려면, 명시적으로 사용하는 클래스와 인터페이스들에 대해서만 import 하시는 것이 필요합니다.

5.2 클래스와 인터페이스

38. Class 와 Interface 의 선언은 다음과 같은 방식으로 조직화하여 사용한다:
  1. Class/Interface 문서(javadoc 주석)
  2. classinterface 선언문
  3. 클래스 변수(static으로 선언된) 들을 public, protected, package (접근제한자가 없는), private 순서대로 나열한다.
  4. 인스턴스 변수들을 public, protected, package (접근제한자가 없는), private 순서대로 나열한다.
  5. 생성자.
  6. 메소드 (메소드에는 특별한 순서가 없음).
 
각각의 클래스/인터페이스 구성요소들의 등장 위치를 지키게되면, 현재 코드 상에 어떤 요소들이 다음에 등장할 것인지 예측할 수 있게되어 복잡도를 낮추게 됩니다.

5.3 메소드

39. 메소드 지시자는 다음의 순서대로 사용한다:
<access> static abstract synchronized <unusual> final native
만약 <access> 지시자가 존재한다면 반드시 맨 처음에 나타나야 한다.
 
<access> 지시자는 public, protected, private 중 하나이고, <unusual> 부분은 volatiletransient 중 하나가 지정됩니다. 여기서 가장 중요한 점은 접근(access) 지시자가 맨 처음에 나타나야 한다는 것입니다. 사용할 수 있는 다양한 지시자들이 있겠지만, 이는 매우 중요한 사항이기 때문에 반드시 메소드 선언문에 반영되어야 합니다. 기타 지시자들의 순서는 덜 중요하지만 일관된 관례를 따르는 것이 바람직합니다. 여기서 제안한 지시자 나열 순서는 Teach Yourself Java in 21 Days 의 저자인 Charles L. Perkins 씨가 자신의 책에서 제시한 방식을 차용한 것입니다.

5.4 타입

40. 타입 컨버전(변환)은 반드시 명시적으로 한다. 묵시적인 타입 컨버전(변환)은 절대로 사용하지 않는다.
floatValue = (float) intValue;     // floatValue = intValue; 가 아님
위 예제의 경우, 프로그래머가 서로 다른 두 타입을 사용하였으며 그가 의도적으로 두 타입을 혼합해서 사용하고 있음을 알려줍니다. 만약 묵시적으로 floatValue = intValue 라고 하였다면 의도적으로 그러한 것인지, 타입 컨버전을 깜빡 한 것인지 혼동할 수 있습니다.
41. 배열 지시자([])는 변수의 이름 뒤가 아니라 타입의 이름 뒤에 나온다.
int[] daysOfMonth;      // int daysOfMonth[]; 가 아님
배열은 타입의 한 속성이지 변수의 속성이 아니기 때문입니다. 어떤 이유에서인지 Java 에서는 두 가지 모두 문법적으로 허용하고 있습니다만, 하나로 통일하는 것이 좋겠습니다.

5.5 변수

42. 변수는 선언된 지점에서 초기화하며, 가능한 사용범위를 최소화하여 선언한다.
 
이 규칙은 어느 시점에서든 변수가 유효한 값을 가진다는 것을 보장해줍니다. 종종 선언하는 시점에 변수에 유효한 값을 초기화하는 것이 불가능한 경우가 있습니다만, 그러한 경우에도 초기화하지 않은 상태로 내버려두는 것보다는 임의의 값이라도 사용하여 초기화 해두는 것이 좋습니다.
43. 변수는 절대로 하나 이상의 의미를 가져서는 안된다.
 
무의미한 이름을 부여한 변수(scratch 변수)를 가지고 이값 저값을 할당하여 사용하게 되면, 어느 순간 이 변수가 현재 어떤 의미의 값을 가지고 있는지 모호해지는 경우가 발생합니다. 일관되고 유일한 의미를 부여함으로써 가독성을 향상시키고 더불어 부작용까지 예방할 수 있습니다.
44. static 으로 선언된 클래스 변수들은 절대로 public 으로 선언하지 않는다.
 
public 변수들은 Java 의 정보은닉과 캡슐화 컨셉에 위배됩니다. 대신 변수를 private 으로 선언하시고 이 변수를 접근할 수 있는 메소드를 사용하게 하십시오. 한 가지 예외적인 상황은 클래스가 데이터 구조로만 사용될 때입니다. 이 경우 클래스는 어떠한 행위(메소드)도 갖지 않고 오로지 데이터를 보관하는, 즉 C++ 에서의 struct 와 동일한 형태로 사용됩니다. 이 경우에는 클래스의 인스턴스 변수들을 public 으로 선언할 수도 있습니다 [2].
45. 동일한 타입의 변수 중 관련있는 변수들은 하나의 구문에서 선언할 수 있다.
즉, 관련이 없는 변수들을 같은 라인에서 선언하지 않는다.
float  x, y, z;
float  revenueJanuary, revenueFebrury, revenueMarch;
위의 예제를 여러 라인에 나누어 선언하는 것은 바람직하지 않습니다. 변수들을 그룹핑함으로써 가독성을 높일 수 있기 때문입니다. 그러나 여기서 주의할 점은, 대다수의 경우에서는 이 규칙보다 각각의 변수는 선언 시 초기화 한다는 규칙이 우선적으로 적용되어야 한다는 것입니다.
46. 변수의 생존기간을 가능한 짧게 유지한다.
 
변수에 대한 조작을 작은 범위 내에 국한시킴으로써, 영향과 부작용을 통제하는 것이 용이해집니다.

5.6 반복문

47. 반드시 반복을 제어하는데 사용되는 문장들만 for() 구문 내에 포함시킨다.
sum = 0;                   // NOT:     for (i=0, sum=0; i<100; i++)
for (i=0; i<100; i++)      //            sum += value[i];
  sum += value[i];
관리의 용이성과 가독성을 향상시킬 수 있습니다. 무엇이 반복문을 제어하고 무엇이 반복문 내에서 사용되는지 명쾌하게 하십시오.
48. 반복문에 사용하는 변수는 반복문 직전에 초기화한다.
boolean isDone = false;  // NOT:   boolean  isDone = false;
while (!isDone) {        //         :
  :                      //        while (!isDone) {
}                        //          :
                                   }
 
49. do .... while 문의 사용을 피한다.
 
여기에는 두 가지 이유가 있습니다. 첫번째, 제어문에 사용되는 구문 요소(키워드)들이 분산되어 있어 난잡합니다. do .... while 문을 사용한 모든 문장은 while 문이나 for 문을 사용하여 동일하게 바꾸어 작성할 수 있습니다. 사용되는 구문 요소들을 최소화함으로써 복잡도를 줄일 수 있습니다. 두번째 이유는 가독성과 관련되어 있습니다. 반복의 조건을 체크하는 부분이 하단에 위치하는 것은, 상단에서 조건을 체크하는 반복문보다 읽기가 더욱 어렵습니다.
 
40. 반복문 내에서 breakcontinue 의 사용을 자제한다.
 
이 두 문장은 구조화된 반복문보다 훨씬 가독성이 높을 때에만 사용하십시오. 일반적으로 break 문은 case 문 내에서만 사용하시고, continue 문은 반복문이든 case 문이든 어떤 경우라도 사용을 피해주시기 바랍니다.
 

5.7 조건문

51. 복잡한 조건식은 반드시 피한다. 그 대신 임시 불리언 변수를 활용하라 [1].
if ((elementNo < 0) || (elementNo > maxElement)||
    elementNo == lastElement) {
  :
}
다음과 같이 변경한다:
boolean isFinished      = (elementNo < 0) || (elementNo > maxElement);
boolean isRepeatedEntry = elementNo == lastElement;
if (isFinished || isRepeatedEntry) {
  :
}

 
조건식을 불리언 변수에 할당함으로써, 프로그램 그 자체로 의미를 명확하게 전달하고 있습니다. 조건문을 평가하는 구문은 보다 쉽게 해석할 수 있으며, 더불어 디버깅할 때에도 편리해집니다.
52. if 문에서, 일반적인 상황은 if 블록에 위치시키고 예외 상황은 else 블록에 위치시킨다 [1].
boolean isError = readFile (fileName);
if (!isError) {
  :
}
else {
  :
}
일반적인 처리 흐름과 예외상황 처리 흐름을 불명확하지 않게 하십시오. 이 지침은 가독성과 성능 모두에 영향을 미치는 중요한 사항입니다.
53. 조건을 평가하는 문장은 별도의 라인으로 분리한다.
if (isDone)              // NOT:  if (isDone) doCleanup();
  doCleanup();
이는 디버깅을 위한 목적으로 한 것입니다. 한 라인에 이것저것 기술하게 되면, 조건식 테스트가 참인지 거짓인지를 확인하기가 어려워집니다.
54. 절대로 조건식에 실행문을 사용하지 않는다.
file = openFile (fileName, "w");  // NOT:   if ((file = openFile (fileName, "w")) != null) {
if (file != null) {               //         :
  :                               //        }
}
조건식에 실행문을 사용하는 것은 간편하지만 읽기가 매우 어려워집니다. 이 지침은 Java 에 발을 처음으로 들여놓는 개발자들에게 특히 강조하고 싶은 지침입니다.

5.8 기타

55. 코드 상에서 매직 넘버(magic number: constants, array size, character positions, conversion factors와 같이 프로그램내에 등장하는 숫자/문자값)의 사용을 자제한다. 01 이외의 숫자는 차라리 상수로 정의하여 사용하도록 한다.
 
명확한 의미를 갖지 않는 숫자를 사용할 경우, 가독성 향상을 위하여 상수로 정의하여 사용하도록 합니다.
56. 실수값 상수는 항상 소수점과 최소한 소숫점 이하 한 자리 숫자를 사용하여 지정한다.
double total = 0.0;   // double total = 0; 가 아님
double speed = 3.0e8; // double speed = 3e8; 가 아님

double sum;
:
sum = (a + b) * 10.0;
특별한 경우에 정수와 실수가 동일한 값을 갖는다 하더라도 기본적으로 특성이 다르기 때문에 구별하는 것이 좋습니다. 또한 위 마지막 라인의 예제에서 살펴볼 수 있듯이, 값을 할당받은 변수(sum)는 다른 변수의 타입을 알 수 없다고 하더라도 명백하게 실수값을 계산해 낸다는 것을 보장할 수 있습니다 (* 10.0 을 통해서)
 
57. 실수값 상수는 항상 정수부에 숫자를 사용하여 지정한다.
double total = 0.5;   // double total = .5; 가 아님
Java 에서 사용하는 숫자와 표현식은 수학식 표기법에서 차용하였으므로, 프로그래머는 가능한 수학적 표기법을 준수하는 것이 바람직합니다. 실제로 .5 (간편한 표기) 보다 0.5 (수학적 표기) 가 더 읽기에 쉽습니다. 이 수식에서 정수 5 가 함께 사용되는 경우에는, .5 와 정수 5 를 혼동하여 잘못된 연산을 초래할 가능성이 높아지게 됩니다.

6 레이아웃과 주석

6.1 레이아웃

58. 기본 들여쓰기(indentation)는 4 자로 한다.
for (i = 0; i < nElements; i++)
  a[i] = 0;
1 자짜리 들여쓰기는 너무 작아서 논리적인 코드의 레이아웃에 사용합니다. 한편 4 자 이상 들여쓰기를 할 경우 중첩 들여쓰기한 코드를 읽기가 어려워지며, 한 문장을 여러 라인으로 쪼개야하는 상황이 자주 발생하게 됩니다. 2, 3, 4 글자 중에서 선택하시는 것이 바람직합니다만, 2 자와 4자가 가장 보편적입니다. 2 자로 하였을 경우에는 한 문장을 여러 라인으로 쪼개야할 상황을 최소화할 수 있습니다. Sun 社 에서는 4 자 들여쓰기를 권고하고 있습니다. 이 지침은 본래 2 자였던 것을 Sun 표준인 4 자로 변경한 것입니다.
59. 블록 레이아웃은 아래 예제 1 (권고안) 나 예제 2 를 따르되, 예제 3 의 형태는 결코 취해서는 안된다. 클래스, 인터페이스, 메소드 블록은 예제 2 레이아웃을 따른다.
while (!isDone) {
  doSomething();
  isDone = moreToDo();
}
 
while (!isDone)
{
  doSomething();
  isDone = moreToDo();
}
 
while (!isDone)
  {
    doSomething();
    isDone = moreToDo();
  }
 
예제 3은 추가적인 들여쓰기를 사용하고 있으나 예제 1 와 예제 2 를 사용한 것보다 나을 것이 없습니다.
60. classinterface 선언문은 다음과 같은 형태를 따른다:
class SomeClass extends AnotherClass
  implements SomeInterface, AnotherInterface
{
  ...
}
 
이 지침은 위에서 언급한 #59 의 일반적인 블록 규칙에 의거한 것입니다. Java 개발자 커뮤니티에서는 클래스를 선언하는 문장의 끝에서 중괄호를 여는 것이 일반적입니다. 실제로 이 괄호 스타일은 모든 종류의 블록에 대하여 사용할 수 있는 방식입니다. 개인적인 선호의 차이가 있겠지만, 이 방식은 C/C++ 에서 클래스와 메소드 블록은 다른 블록들과 구분할 수 있도록 하는 것을 차용한 것입니다.
61. 메소드 선언문은 다음과 같은 형태를 따른다:
public void someMethod()
  throws SomeException
{
  ...
}
 
class 문장에 대한 설명을 참고하십시오 (#59).
62. if-else 문장은 다음과 같은 형태를 따른다:
if (condition) {
  statements;
}

if (condition) {
  statements;
}
else {
  statements;
}

if (condition) {
  statements;
}
else if (condition) {
  statements;
}
else {
  statements;
}
 
이 지침은 위에서 언급한 #59 일반적인 블록 규칙에 의거한 것입니다. 하지만, else 절이 직전의 ifelse 절의 닫히는 중괄호와 동일한 라인에 있어야 한다고 한다면 논의를 해 볼 수도 있을 것입니다:

if (condition) {
  statements;
} else {
  statements;
}

이 방식은 Sun 社의 코딩 표준 권고안에서 제시한 것과 동일한 것입니다. 여기서 제시한 방법은 if-else 문장을 별도의 행에 분리되어 있기 때문에, else 절을 쉽게 식별할 수 있고 (직전 ifelse 절의 닫히는 중괄호 때문에 else 절이 잘 드러나지 않는 경우도 있습니다) 심지어 else 절을 이동한다거나 하는 경우에 손쉽게 if-else 문장을 조작할 수 있다는 점에서 조금 더 낫다고 할 수 있겠습니다.
63. A for 문장은 다음과 같은 형태를 따른다:
for (initialization; condition; update) {
  statements;
}
 
이 지침은 위에서 언급한 #59 일반적인 블록 규칙에 의거한 것입니다.
64. 비어있는 for 문장은 다음과 같은 형태를 따른다:
for (initialization; condition; update)
  ;
이 방식은 프로그래머가 의도적으로 for 문장을 비워두었음을 분명히할 수 있습니다.
65. while 문장은 다음과 같은 형태를 따른다:
while (condition) {
  statements;
}
 
이 지침은 위에서 언급한 #59 일반적인 블록 규칙에 의거한 것입니다.
66. do-while 문장은 다음과 같은 형태를 따른다:
do {
  statements;
} while (condition);
 
이 지침은 위에서 언급한 #59 일반적인 블록 규칙에 의거한 것입니다.
67. switch 문장은 다음과 같은 형태를 따른다:
switch (condition) {
  case ABC :
    statements;
    // Fallthrough 혹은 '계속'
  case DEF :
    statements;
    break;
  case XYZ :
    statements;
    break;
  default :
    statements;
    break;
}
 
이 방식은 Sun 社의 코딩 표준 권고안과는 들여쓰기와 공백문자 처리에 있어서 약간 다릅니다. 특히, 각각의 case 키워드들은 모두 switch 문에 소속되어 있음을 부각시키기 위하여 switch 키워드를 기점으로 들여쓰기를 수행하였습니다. 이로써 switch 문이 강조되었습니다. 한 가지 더 주목해서 보셔야 할 것은 casedefault 키워드들과 : 문자 사이에 추가 공백이 들어있다는 점입니다. break 문을 사용하지 않는 case 문에는 반드시 명시적으로 Fallthrough계속 이라는 주석을 달아주십시오. break 문을 빠뜨리는 것은 일반적인 실수이기 때문에, 이와 같은 주석을 명시함으로써 실수가 아니라 의도적으로 break 문을 생략했다는 것을 분명히 할 수 있습니다.
2004-04-14 08:43:56.0 (wgshim 222.108.45.193) D
68. try-catch 문장은 다음과 같은 형태를 따른다:
try {
  statements;
}
catch (Exception exception) {
  statements;
}

try {
  statements;
}
catch (Exception exception) {
  statements;
}
finally {
  statements;
}
 
이 지침은 위에서 언급한 #59 일반적인 블록 규칙에 의거한 것입니다. 이 형태 역시 #61 의 if-else 문이 그랬던 것처럼, Sun 社의 코딩 표준 권고안에서 제시한 것과는 다릅니다. #61 을 참고하시기 바랍니다.
69. 단일 문장의 if-else, for, while 문은 중괄호 없이 작성할 수도 있다.
if (condition)
  statement;

while (condition)
  statement;

for (initialization; condition; update)
  statement;

 
일반적인 코딩 권고안은 Sun 社의 Java 코딩 표준 권고안에도 포함되어 있는 것과 같이, 모든 경우에 항상 중괄호를 사용하여 블록화 하라는 것입니다. 하지만 블록은 여러 문장을 그룹핑하기 위한 용도로 사용되기 때문에, 단일 문장을 묶는 것은 오히려 번거로울 수 있습니다. #52 와 같이 조건을 평가하는 부분과 실행문을 분리해서 기록하며 들여쓰기를 제대로 한다면 크게 문제되지는 않습니다.

6.2 공백문자

70.
- . 를 제외한 모든 binary 연산자(conventional operator)는 피연산자들 사이에 스페이스로 분리한다.
   예외적으로 Unary operator(++, --) 와 피연산자 사이에는 공백을 두지 않는다.
- Java 예약어/키워드 뒤에 공백문자 하나를 추가한다.
- 콤마(,) 뒤에 공백문자 하나를 추가한다.
- 콜론(:) 의 앞뒤에는 공백문자를 추가한다.
- for 문 내의 세미콜론(;) 문자 뒤에 공백문자 하나를 추가한다.
a = (b + c) * d;            // NOT:   a=(b+c)*d
while (true) {              // NOT:   while(true) ...
doSomething (a, b, c, d);   // NOT:   doSomething (a,b,c,d);
case 100 :                  // NOT:   case 100:
for (i = 0; i < 10; i++) {  // NOT:   for (i=0;i<10;i++){
이 방법은 문장의 각 구성요소들을 부각시켜 가독성을 높여줍니다. 여기서 제안하는 Java 코드 상에서의 공백문자 사용에 관한 모든 예제를 다 나열하기는 어렵겠습니다만, 위에 제시한 예제로도 충분히 그 의도를 제시해주고 있습니다.
71. 메소드의 이름과 메소드의 여는 괄호 사이에 공백문자를 사용하지 않는다.
(참고: 본래 이 문서의 원본에는 Sun 社의 권고안과는 달리 '메소드의 이름과 여는 괄호 사이에도 공백문자를 넣어 모든 이름을 부각시키자' 라고 언급하고 있었으나 변경함)
doSomething(currentFile);    // doSomething (currentFile); 가 아님
#69 지침에 의해 Java 의 예약어/키워드 뒤에 공백문자를 추가하기 때문에, 메소드의 이름과 여는 괄호 사이에 공백을 없앰으로써 메소드 호출과 키워드를 구별하는데 도움을 줍니다.
72. 블록 내의 논리적인 유닛들은 빈 라인을 하나 삽입하여 구분한다.
 
블록 내 논리적 유닛들 사이에 공백을 삽입함으로써 가독성을 향상시키게 됩니다.
73. 메소드 선언들 간에는 3-5 개의 빈 라인을 삽입하여 구분한다.
 
메소드 내에서 사용하는 빈 라인보다 많은 라인을 삽입함으로써 클래스 내 각각의 메소드들을 부각시키게 됩니다.
74. 선언문에서의 변수는 타입과 구분하여 변수끼리 좌측정렬 한다.
AsciiFile  file;
int        nPoints;
float      x, y;
타입과 변수를 구분하여 정렬함으로써 변수를 부각시켜 가독성을 높이게 됩니다.
75. 문장은 가독성을 높이기 위하여 정렬한다
if      (a == lowValue)    compueSomething();
else if (a == mediumValue) computeSomethingElse();
else if (a == highValue)   computeSomethingElseYet();


value = (potential        * oilDensity)   / constant1 +
        (depth            * waterDensity) / constant2 +
        (zCoordinateValue * gasDensity)   / constant3;


minPosition     = computeDistance (min,     x, y, z);
averagePosition = computeDistance (average, x, y, z);


switch (value) {
  case PHASE_OIL   : phaseString = "Oil";   break;
  case PHASE_WATER : phaseString = "Water"; break;
  case PHASE_GAS   : phaseString = "Gas";   break;
}
일반적인 지침에 위배될 수도 있겠지만 위 예제에서는 가독성을 높이기 위하여 코드 사이에 공백문자를 넣었습니다. 공백문자를 넣을 때에는 코드의 정렬방식을 준수합니다. 번거로울 수 있겠지만 코드를 정렬함으로써 코드를 한 눈에 들어오게 만들 수 있습니다. 이렇게 공백문자를 넣어 정렬하는 코드정렬에 대해 일반적인 지침을 제시하기는 어렵겠습니다만, 위에 제시한 예제로도 충분히 그 의도를 제시해주고 있습니다.

6.3 주석

76. 난잡한 코드에는 주석을 다는 것보다는, 코드를 구조화하여 재작성하고 명료한 코드에 주석을 다는 것이 낫다 [1] .
 
일반적으로 적절한 이름 선정과 명쾌한 논리 구조를 바탕으로, 코드 자체만으로도 충분히 이해가 되도록 작성하는 것이 우선이고 그 후 주석을 다는 것이 바람직합니다. 주석을 달지 않는 프로그래머를 나쁜 습관을 가졌다고 하지만, 역설적으로 코딩을 정말 잘하는 프로그래머는 주석을 많이 달 필요가 없는 것입니다.
77. 모든 주석은 영어로 작성한다.
 
국제적인 제품을 개발하고자 할 때에는, 주석도 자국어를 사용하는 것 보다는 영어를 사용하는 것이 바람직합니다.
78. JavaDoc 주석이 아닌 모든 주석과 여러 줄을 사용하는 주석에 // 를 사용한다.
// 한 줄 이상의
// 주석이랍니다

// /*
   여러 라인의 주석을 해제합니다.
// */
Java 에서 멀티 레벨 주석을 지원하지 않기 때문에, 디버깅이나 기타 목적으로 사용한 /* */ 블럭의 주석을 해제하는데 // 를 사용하기도 합니다.
79. 주석은 설명하려는 코드와 같은 위치에서 들여쓰기하여 작성한다 [1].
while (true) {          // NOT:    while (true) {
  // Do something       //         // Do something
  something();          //             something();
}                       //         }
이 방법은 주석이 프로그램의 논리적인 구조를 깨뜨리지 않게 해줍니다.
80. collection 변수를 선언할 때에는, 컬렉션에 담겨질 요소들의 공통 타입에 대한 주석을 작성한다.
private Vector  pointList_;  // Point 객체에 대한 Vector
private Set     shapeSet_;   // Shape 객체에 대한 Set
 
이러한 추가적인 주석이 없다면 컬렉션이 어떤 요소들로 구성되어 있는지 파악하기가 어려워지기 때문에, 컬렉션의 요소들을 어떻게 다뤄야 하는지 혼동이 되는 경우가 발생합니다. 컬렉션 변수를 입력 인자로 받아들이는 메소드에서는, JavaDoc 주석을 사용하여 컬렉션 입력 인자의 요소들의 공통 타입을 기술하십시요.
81. 모든 public 클래스와 public 클래스의 public, protected 로 선언된 메소드들에 JavaDoc 방식의 주석을 작성한다.
 
이 방식은 간편하게 온라인 코드 API 문서를 항상 최신내용으로 유지시킬 수 있도록 합니다.
82. 각 파일에는 package 선언문 상단에 다음과 같은 헤더를 삽입한다:
/*
 * (@)# <<파일의 이름>>.java
 *
 * $Header$
 * $Revision$
 * $Date$
 *
 * ====================================================================
 *
 * <<회사 이름>>., Software License, Version 1.0
 *
 * Copyright (c) 2002-2004 <<회사 이름>>.,
 * <<회사 주소>>  * All rights reserved.
 *
 * DON'T COPY OR REDISTRIBUTE THIS SOURCE CODE WITHOUT PERMISSION.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <<회사 이름>> OR ITS
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * For more information on this product, please see
 * <<회사 웹 사이트 URL 주소>>
 *
 */
각 파일의 상단에 코드의 소유자(혹은 조직)와 라이센스 및 책임의 한계에 대한 정보를 기술합니다.
83. class, interface 및 메소드 선언문 위에는 다음과 같은 JavaDoc 주석을 삽입한다:
/**
 * 클래스, 인터페이스 메소드에 대한 설명을 기술합니다.
 *
 *   메소드의 경우는 다음 항목들을 기록하십시오:
 *      - 메소드의 작성의도
 *      - 메소드를 사용하기 위한 사전조건(pre condition) 과 사후조건(post condition)
 *      - 부작용
 *      - 종속성 (종속되는 라이브러리, 클래스, 메소드 등)
 *      - 사용시 주의해야 할 점
 *      - 누가 이 메소드를 호출하는가
 *      - 언제 이 메소드를 재정의해야 하는가
 *      - 메소드 재정의 시 어디서 부모 메소드를 호출해야 하는가(super 키워드를 사용하여)
 *      - 제어 흐름 및 상태 전이에 관련된 내용들
 *
 * @author (클래스와 인터페이스에서만 사용합니다)
 * @version (클래스와 인터페이스에서만 사용합니다)
 *
 * @param (메소드와 생성자에서만 사용합니다)
 * @return (메소드에서만 사용합니다)
 * @exception (Javadoc 1.2 의 @throws 와 같은 표현입니다)
 * @see
 * @since
 * @serial (또는 @serialField 나 @serialData)
 * @deprecated (deprecated 된 클래스, 인터페이스, 메소드에 대해 어떻게 대응해야 하는지 기록합니다)
 */

public class Example { ...
 
JavaDoc에 대한 자세한 최신 정보는 이곳을 참고하시기 바랍니다.

7 참고문헌

[1] Steve McConnel, "Code Complete," Microsoft Press. [2] Sun, "Java Code Conventions," http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html [3] Netscape, "Software Coding Standards for Java," http://developer.netscape.com/docs/technote/java/codestyle.html [4] NASA, "C / C++ / Java Coding Standards," http://v2ma09.gsfc.nasa.gov/coding_standards.html [5] AmbySoft, "Coding Standards for Java," http://www.ambysoft.com/javaCodingStandards.html

'java core' 카테고리의 다른 글

Threads from aritma  (0) 2005.02.12
Reference object model from java world  (0) 2005.01.28
Garbage collection from javaworld  (0) 2005.01.28
자바 코드 컨벤션  (0) 2005.01.24
J2ME쪽 JSR모음  (0) 2005.01.24
Posted by '김용환'
,
제 목 : 인터럽트에 대해서
작성자: 캠퍼스 C
출 처 : 나우누리
U R L : http://explore.kwangwoon.ac.kr/~k98el560
기 타 : 여기에 게재되는 모든 글들은 이미 작성자의 동의를 얻은 것이기
        때문에 상업적 목적이 없는 한 출처(이 홈페이지)를 밝히고 다른
        곳에 게재할 수 있습니다.
======================================================================
*******************************************************************
<중급>                  < 캠퍼스 C >                            4회
*************************<  목 차  >*******************************
<1> 인터럽트(interrupt)의 개념
<2> 인터럽트(interrupt)와 폴링(polling)
<3> 인터럽트 벡터 테이블(vector table)을 확인하자
<4> 인터럽트의 종류
<5> 인터럽트를 위한 하드웨어의 구현(IBM-PC 에서)
<6> 하드웨어 인터럽트의 순서.
<7> C 에서 제공하는 인터럽트 함수 (turbo C 에서)
<8> 인터럽트의 작동을 눈으로 확인해 보자.
<9> 인터럽트를 이용하여 시계를 만들어 보자
************************< 내용 시작 >******************************
<1> 인터럽트(interrupt)의 개념
-------------------------------------------------------------------
        영어로 "inter" 라는 의미는 "중간에, 사이에서" 라는 뜻이다.
그래서 잘아시다시피, 농구에서 패스하는 공을  가로채는 것을 "인터셉트
(intercept)" 라고 한다.
        마찬가지로 지금 우리가 공부하려는 "인터럽트(interrupt)"도
"중간(inter)에서 탁 깨뜨려서(rupt) 흐름을 바꿔 놓는다"는 뜻이다.
        지금 이 강좌를  듣는 분 중에는 나름대로 C의  기초를 공부하고
온 분들이겠지만 컴퓨터안에 "흐름"이 있다는 것을 모두  알고 있는지
궁금하다.
        그 흐름이란 80x86  CPU내부에 있는 "IP" 라는  레지스터의 값의
변화를 말한다.
        IP 하니까 생각나는게  있다. 천리안,하이텔  같은  회사에 근무
하는 분들은 이 IP란 용어를 참 많이 사용한다.
        "저 사람 IP 야"
글쎄 "JP" 라면 누군지 금새 알 것도 같은데 "IP"는 누군지 잘모르겠다.
          여기서 얘기하는 "IP"란  (Information Provider)란 뜻으로 "
정보를 제공하는 사람"이라는 뜻이다. 이를테면  사주팔자 같은 데이타베
이스를 천리안,나우콤같은 업체에 제공하는 사람들이 "IP"인 것이다.
        그러나 지금  우리가 얘기하는, (똑같은 이름의)  "레지스터 IP"
는 (내가 보기엔) 그것보다 훨씬 더 중요한 의미를 가지고 있다. 여러분이
소위 "프로그램을 배우겠다"는 사람이면 이 IP의 흐름을 손바닥 보듯이
훤하게 보고 있어야만 한다. 그것은 마치 "혈액 순환계"를 공부하는 의사
들이, "심장에서 나온 피가 어디로 돌고 있는지"를 훤하게 알고 있어야 하는
것과 마찬가지이다.
        IP 는 (Instruction Pointer)의  준말이다. C 기초 강좌에서
"포인터"를 공부한  사람이라면 이 레지스터의 내부에 들어갈  값 (예를
들면 0x1234 따위)가 무엇을 의미하는지 짐작이 가실 것이다.
        이 IP의 역할은,  "다음번에 수행해야 할 명령어의  번지수를 가
리키는것"이다. 이 강좌는 그래도 "중급강좌"인데  이런 자질구레한 얘기
를 쓸 필요가 있는지 잘 모르겠지만, 그래도 혹시나 하는 마음에 적어본다
        이  IP의 기능을 생생하게 느끼실려면 "국민은행"에 가보시면 잘
알 수 있다.  지방 국민은행에도 이런 시스템이  되있는지 잘  모르겠지만
국민은행에서 일처리를 하려면  들어가자마자 무조건 "대기번호" 표를 뽑고
전광판에 내 번호가 나타나기를 "멍하니" 서서(혹은 앉아서) 기다려야 된다.
        수시로  "띵동" 하는  소리와  함께  전광판의 숫자는  39,  40,
41,42, 하는 식으로  증가한다. 두말할 것도 없이 "39번  손님 앞으로.."
하는 안내이다.
        IP의 역할도 전광판과 똑같다. IP가  현재 "0x0039"를 가지고 있
으면 그 주소에 있는 코드를 읽어다가 수행을  한다는 뜻이다. 그리고 이
연산이  끝나면 IP의  값은 역시  "자동적"으로 증가  된다. 즉  0x0039,
0x0041 하는식이다.(여기서는 꼭 1씩 증가 하지는 않음).
        인터럽트의 개념은  이렇다. 지금 전광판이 38번을  가리키고 있
다. 그리고 다음이 내 번호인 39가  될 차례이다. 그런데 갑자기  번호가
999번으로 바뀐다. 그러더니  뒤에 앉은 더 높은 은행원이  "999번" 표를
흔들며 나타나서 먼저 돈을 찾아간다.  "아니 뭐  저런 x가 다있어 ? "하
고 항의를 하려는 순간, 이제서야 전광판에 내 번호인 39번이 나타난다.
        아시다시피 이것은  일종의 새치기에  해당한다. 그러나  이것이
실제로 컴퓨터  내부에서 일어나고 있는  인터럽트의 기본 개념이다.  왜
정직한 컴퓨터가 이런 새치기를 허용하는지,  의문을  갖는 분도 있을 것
이다.
      그러나 알고 봤더니 999번의 은행원이  찾아간 돈은 급한 응급환자
의 수술비 라고 한다...
        이런 기본적인  인터럽트의 개념 외에  반드시 알아야 할  것은,
"인터럽트는  nesting(중첩)도 허용된다"는 사실이다.  이런 설명을 위해
서 아래에 (중급 독자를 실망시킬 지 모르는) 유치한 예를 들었다.
        예를 들면, 지금  "이 팔육" 이라는 학생이 고등학교 2  학년 이
라고 치고, 같은  반 친구와 "야구 얘기"를 나누고 있다고  하자. 그런데
갑자기 3 학년 학생이 말을 걸어오면 "이  팔육"은 일단 친구와의 얘기를
잠시 중단하고 선배인 3학년하고 얘기를 시작 해야 한다.
        그러는 도중에 갑자기  선생님이 말을 걸어 온다면  여러분은 어
떻게 할 것인가  ? 정신 나간 학생이 아닌 다음에야  당연히 하던 얘기를
멈추고 선생님과 얘기를 시작 할 것이다.
<문제>  그러다 이번엔 교장 선생님이 말을 걸어오면 ?
        위의 문제는  "완전히" 정신 나간  문제인것 같다. 이런  당연한
문제는 낼 필요가 없는 것 같은데, 나온김에 하나만 더 내보자.
<문제> 교장 선생님과  하던 얘기가 끝이났다. 이번엔 누구와  다시 얘기
를 나누어야 하나 ?
        역시 이 문제도 정신이 나간  문제인데, 당연히 선생님과 얘기를
한다. 그러다 또 선생님과 얘기가 끝나면 다시  3 학년 학생과 얘기를 한
다. 그리고 또  3학년 학생과 얘기가 끝나면 이제 비로소  2 학년 친구와
하던 "야구 얘기"를 계속 할 수 있다.
        하두 인터럽트가 많이  걸려서 "이 팔육"은 잠시  생각을 해봐야
할 것이다. "몇회전 까지 공을 던졌던가 ?"를...
        나중에도 자세히  나오겠지만, 이런 "문맥(context) 전환"을  위한
노력은 실제로 컴퓨터 안에서도 똑같이 일어나고 있다.
        그런데 이 순간, 갑자기 1 학년 후배가  "잠깐만 !"을 외치며 말
을 걸어 온다면 여러분은 어떻게 할 것인가 ?
        이런 때 그  사람의 인간성이 드러날 것 같은데,  나같으면 대꾸
없이 주먹을 한방 날릴 것 같다. "조용히 해, 너마저 인터럽트냐 ? "
        그러나 컴퓨터의  CPU "이 팔육(80286)"은  (착하게도) 때리지는
않지만 아무런 대꾸를 하지 않은 채 , 친구와 하던 얘기를 계속한다.
        이런 예가 "인터럽트의 nesting(중첩)"에  대한 실제적인 개념이
다.   여기서, 위 등장  인물들의 "인터럽트 우선순위"를 높은  순서대로
적어보면 다음과 같다.
   교장 선생님 --> 선생님--> 3학년   --> 2학년 친구  --> 1학년
        컴퓨터 내부에서도 이런 우선 순위를  가지고 있는 것은 똑같다.
그럼 이제 문제를 하나 더 내보자.
<문제>  "이 팔육" 학생이 "하드 디스크 C"와  얘기를 나누고 있다. 그런
데 갑자기  "프린터" 가 얘기를 걸어  온다면, "이 팔육"은  주먹을 날릴
것인가 ?  아니면 하던 얘기를 멈추고 프린터와 애기를 시작할 것인가 ?
        이 문제를 틀린 사람도 역시 정신 나간  사람에 해당 하는데, 여
러분 중에 과연 몇 명이나 정신이 멀쩡한지 모르겠다.
*******************************************************************
<2> 인터럽트(interrupt)와 폴링(polling)
*******************************************************************
        인터럽트의 나머지 내용을  더 공부하기 전에 먼저  상식으로 알
아 두어야 할 것이 있다.
        컴퓨터 용어로 "폴링(polling)" 이라는 용어가  있다. 이 단어는
굳이 프로그래머가 알아야  할 필요가 있는 것은 아니다.  주로 하드웨어
를 디자인 하는  사람들이 여러가지 칩들을 가지고 사용할 때  자주 등장
하는 용어이기 때문이다.
        그럼에도 불구하고 굳이 이 용어에  대해서 이야기를 하는 것은,
마치 "홀쭉이와 뚱뚱이"란 용어가 서로의 개념을  더욱 명확하게 보여 주
듯이, "인터럽트 와  폴링"이 서로의 개념의 차이를 더욱  분명히 보여주
기 때문이다.
        poll이란 용어는, 아시다시피 "투표,  투표하다"라는 뜻이다. 그
러나 전산 용어가  많이 그렇듯이 이런 용어로는 정확한 뜻을  알기 어렵
다. 내가 가지고  있는 영어사전은 오래되서 그런지 [전산]에  관한 의미
는 아예 없는데, 다행히 아래한글 2.5에  속한 영어사전에서는 그 의미가
실려있다. 그런데...
        적어도 유명한 사전에  실린 해설이니까  엉터리  일리는 없는데
나로서는 무슨 의도로 이렇게 적어놨는지 도저히 알기가 어렵다.
poll : (신호, 스위치) 장치로 단말기기에 송신하도록 작용하다.
polling :  특정 단말을 지정하고  그 국(한자로 방송국 할때의  "국")이
          송신하도록 권유하는 과정
        컴퓨터 내부에서는  CPU가 "인터럽트 방식"으로  일을 한다.  즉
CPU의 역할은, 어느  한가지의 주변 기기만 상대하는 것이  아니다. 마치
대통령의 임무와 비슷하게,  일이 없다면 그냥 놀고 있다가 갑자기   "누
가 키보드를 눌렀습니다"(하드웨어 인터럽트에  해당함)라고 인터럽트 전
령이 연락을 하면, "음 읽어봐라" 하고 처리해준다.
        또 놀다가 "프린터가 데이타  보내랍니다"(역시 하드웨어 인터럽
트에 해당) 하면 역시 "음 보내줘라" 하고 처리를 하는 식이다.
        이에 비해 "폴링"이란  것은 마치 대통령이 길거리를  걸어갈 때
호위하는 경호원들의  역할과 비슷하다. 즉  한시도 감시를 늦추지  않고
주위를 두리번 거리며 살핀다(이것이 polling(폴링)임).  따라서 혹시 괴
한이 총을 뽑는 경우가 있으면, 경호원은 누구의  연락도 받지 않고 즉각
자기가 알 수 있다.
        하나 더 예를  들면, 영화에서 흔히 보는 것 같이,  교도소 담벽
에 누가  붙은 놈이 없나하고 왔다갔다  하는  "서치 라이트"  의 불빛과
같다. 즉  한시도 쉬지 않고 "한  가지 임무"만을 위해서 일을  하는 것,
이것이 폴링이라는 개념이다.
        이미 여러분이  짐작하시다시피 폴링  기능을 하는 것은  컴퓨터
중에서도 "변방"의 단순 기능을 하는 장치들에 흔히 있다.
        그중에서도 가장 대표적인  것이 키보드 내부에 있는 8048 이라는
 "원 칩 (one chip) 마이크로 프로세서"이다.  원 칩 마이크로 프로세서는
간단히 얘기해서, "CPU +  RAM + ROM"을 하나의 칩 안에  전부 갖고 있는
것을 얘기한다.
        아마 세월이 좀 지나면 지금  우리가 쓰는 386컴퓨터, 486컴퓨터
정도의 기능을 하는 one chip 마이크로프로세서가  나올 것이다. 그 정도
쯤 되면  아마 "터미네이터(T2)"의 몸속에  넣어주고 쓸 만할 정도가  될
지도 모른다.  하지만 현재는 그렇게 막강한  기능을 갖는 것은  없는 것
같고 거의 장난감 수준이다. 하지만,  그래도  냉장고, 세탁기 정도의 자
동화를 위해서는 충분히 쓰일 수 있는 정도이다.
        이런 원칩  마이크로 프로세서가  우리의 키보드 안쪽에  장착이
되있는 것이다.(앞으로 기회가 되면 그림 파일로  보여드리겠고) 그리고
그 칩은 항상  폴링을 하고 있다. "인간이 키 자판을  누르나 안누르나를
항상 살피면서..."
        ---------------------------------------------------------
<참조>  (앞으로 이런 곳에서 같이 보내는 "그림 파일"을 참조하세요)
        ----------------------------------------------------------
        이와같이 "인터럽트 와 폴링"이라는 개념을  비교하면서 이해 하
시기를 바란다.
<숙제> 자신 있는 사람은 키보드를 뜯어보고  눈으로 직접 8042라는 칩을
        확인하세요 (반드시 전원을 내리고)
<숙제> 컴퓨터를 켠 상태에서 여러분 눈앞에  있는 키보드를 보고 8042가
        "폴링"하고 있는 것을 느껴 보세요.
        (서치 라이트 불빛이 왔다갔다 하듯이...)
*******************************************************************
<3> 인터럽트 벡터 테이블(vector table)을 알자
*******************************************************************
        현재 IBM-PC 에서는 256개의 인터럽트를  허용하고 있다. 그리고
각각의 인터럽트가 걸리면, 그에 해당하는 일을  하는 루틴이 있는데, 우
리는 그것을 "인터럽트 핸들러(interrupt handler)"라고 부르고 있다.
즉, 인터럽트가  걸리면 그  일을 처리(handle)하는 프로그램을  말한다.
이 인터럽트 핸들러라는  프로그램은 ROM BIOS 안에 어셈블러로  짜여 있
기도하고, DOS 안에도 있고, 우리가 직접 짤 수도 있다.
        이 각각의 인터럽트 핸들러의 시작 번지를  모아 놓은 것을 우리
는 "인터럽트  벡터 테이블(interrupt  vector table)"이라고 부르고  있
다.
        이 인터럽트 벡터  테이블을 직접 살펴보기 전에  상식으로 알아
야 할 것은 다음과 같다.
        1. 각 핸들러의 주소는 총 4바이트로 이루어져 있다.
            -> 세그먼트(2바이트) + 오프셋(2바이트) = 4 바이트
                예) 0x1234 : 0x5678
        2. IBM-PC 에서는, 메모리에 각 주소가 뒤집어져서 들어간다
             -> 이걸 "역 word" 방식이라고 부르며,  x1234  : 0x5678인
               값이  0번지부터 메모리에 들어가는 모습은 다음과 같다.
                78     56     34     12
                --     --     --     --
                0번지  1번지  2번지  3 번지
        3. "인터럽트 벡터 테이블"은 메모리의 절대번지
                --------------------------------
                0x0000 : 0x0000부터 할당되 있다.
                --------------------------------
        4. 벡터 테이블의 총 크기는 1K의 메모리 size이다.
                총 인터럽트 벡터 수 :   256개
                크기                :     4 바이트
                ---------------------------------------
                                        1024 바이트
<숙제> 디버거(debugger)의  덤프 명령(d)를 이용하여 인터럽트  벡터 테
        이블을 프린트하고 책상앞에 붙여 놓으세요.(총 1K 만큼)
<숙제> 디버거(debugger)를  이용하여 실제  메모리 00번지 부터  dump로
살펴보세요. 이 때  [525쪽] 에서 인터럽트 번호 9h의 실제  인터럽트 서
비스 루틴"의 주소를 "세그먼트 : 오프셋" 형태로 적어보세요.
*******************************************************************
<4> 인터럽트의 종류
*******************************************************************
        인터럽트의 갯수는 총 256개 (한바이트  크기분 )가 있다고 했지
만, 이것도 크게 다음과 같이 나누어 볼 수가 있다.
        1. 소프트웨어 인터럽트
        2. 하드웨어 인터럽트
        먼저 교재를 가지신  분은 [524쪽]에 나와 있는 표를  지금 펴보
자.(교재가 없는 분들은 각자 가지고 있는  인터럽트 벡터 표를 참조해주
세요)  이 표를 보는 방법은 다음과 같다.
<첫째>
        제일 왼쪽  칸이 "인터럽트 번호"  인데, 이게 아파트  당첨순서
처럼 "0 순위"에 가까울수록 우선순위가 높은  것이다. 따라서 제일 처음
에 나오는 "0" 번 인 "devide by zero  error"가 교장 선생님 처럼  컴퓨
터 내부에서는 가장 우선순위가 높은것이다. 숫자  뒤에 붙은 h는 16진법
을 의미한다. 즉  1h --> 0x01 과 같은 의미이다.
<둘째>
        가운데 "Address"  칸이 있는데, 이  칸은 전부 4바이트  크기의
주소이다. 주소가 4바이트인 이유는 "세그먼트  : 오프셋" 형식으로 먼거
리 포인터(far pointer)를 이용하기 때문이다.
1> 하드웨어 인터럽트
----------------------
        이 중에서도  일단 하드웨어 인터럽트를 구분해보자.  각기 색이
다른 형광펜으로 다음의 번호에 표시를 해두자.
   * 인터럽트 번호 : 8h 부터  fh 까지
       <메모>   - 하드웨어 인터럽트
                - 8259 인터럽트 콘트롤러 1번에서 발생한다.
   * 인터럽트 번호 : 70h 부터 77h 까지
        <메모>  - 하드웨어 인터럽트
                - 8259 인터럽트 콘트롤러 2번에서 발생한다.
   * 인터럽트 번호 : 0h  부터 04h 까지
        <메모> - CPU 에서 발생하는 인터럽트
2> 소프트웨어  인터럽트
------------------------
        위에서 표시한 하드웨어 인터럽트를 제외한  모든 것이 소프트웨
어 인터럽트라고 생각하면 된다. 이것도 크게  BIOS 인터럽트와 DOS 인터
럽트로 구별할  수 있다. 먼저   DOS 인터럽트의 구별을  위해서, 표에서
다음과 같은 줄에 "확실히"표시를 해두기로 하자.
        * 인터럽트 번호 -->  21h    84-87    (Dos function call)
        이 DOS function  call을 호출하면 (메모리에 올라와  있는) DOS
의 일부분인 command.com 안의 루틴을 호출하게 된다.
        BIOS function  call을 호출하면  ROM-BIOS 안의 루틴을  호출한
다.
*******************************************************************
<5> 인터럽트를 위한 하드웨어의 구현(IBM-PC 에서)
*******************************************************************
        인터럽트를 발생시키는 기능은 8259라는  콘트롤러(칩) 2개가 이
용된다. 더 자세한 개념도는 나중에 그림 파일로 보여드리기로 하겠다.
*******************************************************************
<6> 하드웨어 인터럽트(8259에서 발생하는))의 순서.
*******************************************************************
        하드웨어 인터럽트에 대해서  생각해야 할 것은 다음과  같은 두
가지이다.
        -----------------------------------------------------------
        1. 인터럽트를 걸 수 있는 디바이스(장치)의 종류는 무엇인가 ?
        2. 그 우선순위는 어떻게 결정되어 있는가 ?
        -----------------------------------------------------------
        이런 문제는 컴퓨터를  만드는 회사에서 이미 결정이  된 것이기
때문에 , 일반 사용자들은 [525쪽] 표를 참조하기만 하면 된다.
        표에서 "하드웨어  인터럽트"라고 표시한 부분을  참조하고 다음
의 문제를 풀어 보기로 하자.
<문제> 키보드와  하드디스크 인터럽트가  동시에 걸렸다고 하자.  CPU는
어느 인터럽트를 먼저 실행하겠는가 ?
*******************************************************************
<7> C 에서 제공하는 인터럽트 함수  (Turbo C 에서)
*******************************************************************
        C에서 인터럽트를  사용하는 방법은 지극히 간단하다.  이미 C에
서 준비되  있는 함수를 불러다 쓰면  되기 때문이다. 그  종류는 다음과
같다.
int86()
int86x()
intdos()
intdosx()
        이 내용은 교재의 [440쪽] (라이브러리  함수)편에 잘나와 있다.
(교재가 없는  분은 각자 가지고  계신 "라이브러리 레퍼런스"를  참조해
주세요.) 이 강좌를 읽는 분들은 "함수읽는  방법"에 대해 잘 아시리라고
생각하지만, 혹시나 하는 마음에 하나만 설명해 보기로 한다.
        먼저  [440쪽]의 int86()  함수를  살펴보면, 반드시  "dos.h"를
포함하라고 되어있다. 이유는,  union REGS의 정의가 이 곳에  되있기 때
문이다. 인터럽트를 사용하기 위해서는 CPU의  레지스터를 직접적으로 이
용해야 하는데, 그 변수의 정의가 dos.h 안에 이미 되있는 것이다.
        그리고,  int86()함수의 파라메타로  사용되는 변수는  3개인데,
교재에 보다시피. 첫번째 값은 "인터럽트의 번호"이다.  이 번호가 이 강
좌의 첫부분에서 얘기했던 "인터럽트 번호"를 의미한다.
        그리고 두번째,  세번째의 파라메타는 아래와 같이  똑같은 형태
이다.
                union REGS *inregs
                union REGS *outregs
스트락춰 와 유니온의  표현 방법에 대해서 익숙치 않은 분들은  각자 연
습하기로 하고 ,  앞으로는 아래에 보이는 상투적인 표현을  그대로 따라
쓰도록 하자.
#include <dos.h>        <-- 반드시 포함
main()
{
 union REGS r;          <-- 변수 r을 임의로 지정.
 r.h.ah = 0x02;      <-- 인터럽트  call 하기전에 필요한 값 대입
 int86(0x1a,&r,&r);  <-- 인터럽트 호출 (현재는 0x1a번)
                         &r의 형태로 쓴 걸 주의할 것
                        (함수에서 주소를 쓰라고 정의되 있기때문)
 hour = r.h.ch;      <-- 레지스터에 저장된 결과를 이용
 min  = r.h.cl;
 sec  = r.h.dh;
}
        int86x() 함수는 똑같은 내용이지만,  특별히 세그먼트 레지스터
를 더 지정 할 수 있는 형태이고,  intdos() 형태는 "DOS 인터럽트"를 호
출하는 함수이므로 굳이 인터럽트 번호 0x21을  안써도 되는 형태일 뿐이
다.
*******************************************************************
<8> 인터럽트의 작동을 눈으로 확인해 보자.
*******************************************************************
        다음에 인터럽트가 직접 작동되는 모습을 살펴보기로 하자.
먼저 [524쪽] 인터럽트 번호표를 보면, 인터럽트  0번은 "divide by zero
error"이다. 이말은 짐작하시다시피, 프로그램 실행중  "0으로 나누는 경
우"가 있으면  발생되는 인터럽트이다. 0으로  나누면 안되는 이유야  잘
아실 것이고, 이 인터럽트는 성격상 CPU  내부에서 발생하는 것이고 우리
가 임의로 호출할 수 있는 것은 아니다.
        다음을 직접  실행시키고 인터럽트 0번이 실행되는  모습을 살펴
보기로 하자.
main()
{
        int i;
        i = 0;
        i = 100/i;
}
<문제> 인터럽트 0번의 인터럽트 핸들러  (인터럽트 서비스 루틴)의 실제
주소는 얼마인지 디버거를 이용하여 찾아보세요.  (00 - 03까지에 들어가
있는 주소)
        하나 더  예를 들어,  인터럽트 번호 1c  를 살펴보자. 이  것은
"사용자 정의 timer tick" 이라고 설명되 있다.  이 내용을 이미 알고 계
신 분도 많겠지만, 지금 우리가 쓰고  있는 IBM-PC에서는 1초에 18.2번의
인터럽트가 걸리고 있다. 더 근본적인  일련의 이야기는 다음번에 하나의
강좌로 다시 쓰기로  하고 지금은 이런 사실을 그대로 확인해  보기로 하
자.
<문제>  먼저 도스 상태에서 모니터를 쳐다보세요.  즉 다음과 같은 상태
입니다. 여기서는  지금 안보이지만 모니터상에서는 커서가  깜박이고 있
을 것입니다.
           c:\tc>
지금 컴퓨터는 무슨 일을 하고 있습니까 ?
        요즘 아주 인기있는  "문화 유산 답사기"에 관한  책을 읽어보면
"사람은 아는 만큼  느낀다"는 아주 근사한 말이 나온다.  우리가 지금하
고 있는  기계적인 컴퓨터 공부에서도  이런 말을 쓰는 것이  어울리지는
잘 모르겠지만,  여러분이 바로  위의 문제를 풀면서(모니터를  쳐다보고
있으면서) 무엇을 느끼실 지 궁금하다.
        평상시에 커서는 (DOS 상태에서), 사람이  키보드를 치기를 기다
리며 한가롭게  껌벅이고 있는 것  같지만, 사실은 이 상태에서도  1초에
18.2번씩 인터럽트가 걸리고 있다는 걸 알아야 한다.
        이 인터럽트가 걸리면 ( 인터럽트 1c 번이므로)  70 - 73 번지에
적혀 있는  주소로 가서 일을 하고  온다. 그러나 이 곳에  가보면 (보통
상태에서는) 아무 일도  안시키고 "그냥 돌아가" 하는 쓸쓸한  대답만 듣
고 돌아온다. 따라서  외관상으로는 마치 아무것도 안하는 것  같이 보인
다.
        따라서 우리는 이제 아주 간단항 일을  하나 시킴으로서 정말 인
터럽트가 1초에 18.2번씩 걸리는 지 확인해 보기로 하자.
        시키는 일은 간단하다.  그냥 기념으로 '0' 이라는  숫자를 하나
찍고 돌아가라는  것이다. 먼저 프로그램을 보기로 하자
#include <dos.h>
interrupt intr_exam();
main()
{
        unsigned segment, offset;
        segment = FP_SEG(intr_exam);
        offset  = FP_OFF(intr_exam);
        poke( 0x0000, 0x0070, offset);
        poke( 0x0000, 0x0072, segment);
}
interrupt intr_exam()
{
        putch('0');
}
        위  프로그램은  보시다시피   두개의  함수로  이루어져  있다.
main() 함수에서  하는 일은 intr_exam()  이라는 함수의 주소를  읽어서
0000 : 0070, 번지와 0000 : 0072 번지에 넣어 주는 일만 한다.
        현재 변수로 쓰인 segment, offset 두개는 int 타입(2 바이트)
에 해당하는 것을 기억하자. 따라서 이 값들은  70 - 73까지의( 인터럽트
1c의 서비스 루틴 주소) 값을 변경하고 있는 것이다.
        이 작업은  짐작하시다시피, "일 안시키는 현재의  서비스 루틴"
으로 가지 말고 intr_exam() 이라는 함수로 오라는 뜻이다.
        현재 intr_exam() 함수는 '0' 을  찍으라는 일을 시키고 있다.그
리고 이 함수는 보통 프로그램의 서브  루틴이 아니고, 특별히 "인터럽트
서비스 루틴" 이라는 의미로 함수명 앞에  "interrupt" 라는 휘장을 달아
준 걸 눈여겨 보자.
        이제 이 프로그램을 그대로 잘라내서  실행시켜 보기로 하자. 이
프로그램은 원래의 서비스 루틴으로 되돌리는  프로그램이 없으므로 평상
시와 같이 DOS를 쓰고 싶으면 커퓨터를 껐다가  켜야 한다는 것을 기억하
자.  그리고 아래에 적혀 있는 숙제를 메모해 두고 직접해 보기로 하자.
Posted by '김용환'
,
질문: 싸이월드, 다음 싸이트가 뜨지 안아요 0just_one0 / 2004-05-28 02:07
싸이월드는 홈피 창이 뜨질안고요

다음은 배너광고도 뜨지않고, 메일 클릭을 해봐도 하얀 창만 뜨구,

이게 어떻게 된 일인지

이 지식인에 질문하는 것두요,

피씨방에서 하고 잇어요

다른 싸이트도 마찬가지구요

내공 35에요,

도와주세요

컴퓨터 키면 버디도 못하고,

이게 무슨일인지

이렇게 된지 일주일 좀 넘었어요 좀 도와주세요
답변: re: 싸이월드, 다음 싸이트가 뜨지 안아요 kimjy810 / 2004-05-15 22:13
혹시 인터넷을 연결했는데 연결표시는 나도 인터넷이 안되는것을 말씀하시는것이 아닌지 모르겠습니다. 그경우는 현재 많은 문제를 일으킨 웜바이러스가 문제이고요.
웜바이러스는...

Posted by '김용환'
,