Java와 C#의 전반적인 관점에서 비교해보도록 하겠습니다! 
사실 금번 학기에는 C#과 Java 두가지 언어를 사용해 프로젝트를 수행해보았는데요.
아무래도 지금 쓰는 이 “VS” 는 약간 저의 주관적인 의견이 많이 들어가게 될 것 같습니다.

사실 Java와 .NET의 플랫폼적인 관점에서 비교를 하려고도 생각해보았지만, 너무나도 범위가 광범위해질 듯 하여 좀 줄여본 게 Java나 C#의 순수한 언어론적인 비교에서부터 사소하다면 사소하다고 할 수 있는 IDE 비교까지 적다면 적고, 많다면 많은 내용을 비교할 예정입니다.

 일단은 Java와 C# 두가지의 언어론적인 관점보다는 비언어론적인 부분부터 비교해보도록 할까요?

 

 

Java와 C#의 전반적인 배경 – Java 어원 VS C# 어원


 일단은 자바부터 전반적인 배경을 살펴보겠다.

자바는 1991년 Green project 라는 이름으로 제임스 고슬린이 수행했던 프로젝트이다.

일단 이 “자바”라는 이름이 참으로 특이한데, 선택된 과정은 무작위로 선택되었다고 하지만, 그 당시 Java Coffee가 매우 유명했다고 한다. 개인적인 생각으론 그 Java Coffee 메이커의 명성을 얻어보고자 한 것이 아닐까? 라고 조심스럽게 추측해본다 :) 

 



 위가 Java의 로고이다. 커피가 그려져 있지 않은가? ㅎㅎ지금은 Java Coffee 보다도 Java가 더 유명해진 듯 하다..

 한편 Java는 “Write Once, Run Anywhere”라는 문구를 통해 많이 알려져 있다.

이 문구는 한번 작성한 프로그램이 어떤 운영체제에서라도 돌아간다는 의미인데, 정말 참신하고, 멋진 생각이었던 것 같다. 지금이야 임베디드 기기면 임베디드 기기, PC라면 PC, 어디서든 자바가 빠지는 곳은 없어 보이는 듯 하다. ^^ (플랫폼적인 관점이므로, 비교에서 제외하겠습니다.)

 요즘 자바에서 많이 사용되고 있는 것들을 살펴보자면, 서버 사이드 프로그래밍으로는 JSP(Java Server Page)가 쓰이고, 웹페이지 내에서 멀티미디어 효과를 내는 데에는 자바 애플릿, 그리고 대부분 Local에서 응용 프로그램으로 쓰이는 Java SE 버전 등 여러가지가 있다.

 자바의 전반적인 배경을 살펴보았다.

“자바”라는 이름과 자바의 철학을 살펴보았는데, 점수를 주자면 10점 만점에 8점을 주고 싶다. 개인적인 생각이지만, 프로그래밍 언어에 Java Coffee라는 그다지 관련 없는 이름을 지었다는 점에서 마이너스 감점 요인이 있었던 듯 하다. ^^; (프로그래머는 매일 커피를 마시며 밤을 새야한다는 느낌을 받게 되는 점에서 감점 요인이 되었다.)

 다음으론 C#의 전반적인 배경을 살펴보겠다.

C# (“See Sharp”라고 발음)은 1998년에 시작된 프로젝트로 목표 자체가 Simple, modern, object-oriented, 그리고 타입 안전 프로그래밍 언어로 닷넷 플랫폼이라는 이름 하에 진행되었다. C#이라는 이름을 보면 사람들은 보통  “C와 C++과 같은 프로그래밍 언어에 종속되어지겠구나. “ 라고 생각하게 된다. 그리고 C++ 의미가 C with Class 라는 뜻과 “++”이라는 증가 연산자의 의미를 덧붙여서 만들어 졌듯이(C의 향상된 버전), C#도 어떠한 의미가 담겨 있지 않을까? 라고 생각이 들 수 있다.

 일단 C#은 C언어군에 뿌리를 두고 있다. 물론 Java도 C언어군에 뿌리를 두고 있지만, C#은 Java이후에 나온 언어이므로, 대략적으로 살펴보면, 거의 Java와 문법이 비슷하므로, Java의 뿌리라고 보아도 무색하지 않다고 생각한다.

 C#은 닷넷 플랫폼 내에 최적화된 언어이다. 위에서 Java가 JVM(java Virtual Machine) 상에서 돌아가듯이, C#도 닷넷 플랫폼 내의 CLR(Common Language Runtime) 상에서 돌아간다. C#도 닷넷기반의 이용을 하게 되면 Java 처럼 서버 사이드 프로그래밍 뿐만 아니라, 멀티미디어 처리까지 가능하다. ASP.NET이라고, C#을 이용하여, 서버 사이드 처리를 가능하게 하고, 실버라이트라는 이번에 나온 신기술을 통해 Flash와 같은 미려한 멀티미디어 처리가 웹상에서 가능하다. :)

 이제 C#도 점수를 매길 때가 온 듯 하다. 이번 편은 Java와 C#의 어원에 대해서 비교해보았는데, C#은 아무래도 C 계열 언어라는 계통이 확연히 드러나며, 또 그렇게 묻어났다. 물론 Java의 영향도 매우 많이 받았지만 말이다. 내 개인적인 판단과 생각으로 C#이라는 이름도 매우 참신하다고 생각한다. 악보에서 #(Sharp)의 의미는 반음 올린다는 의미이다. 이건 내 개인적인 생각이지만, 이렇게 #이라는 의미가 한단계 올린다는 의미로서, C++의 객체지향적 특성보다는 C언어에서 C++과는 다른 객체지향적 특성을 한단계 올린다는 의미에서 C#이라고 명명하지 않았을까? 하는 생각이다.
따라서 점수를 주자면, 9점 정도가 적당한 듯하다.


Java VS C# ! 8:9 C# 승 !!

 

 두 언어간의 IDE 비교 !

 이번 편은 자바와 C#의 대표적으로 유명한 IDE를 비교하도록 하겠다.
자바의 대표적인 IDE로써, Netbeans 6.0를 선택했고, C#은 Microsoft Visual Studio 2008로 선택했다.
이 둘은 내가 금번 실제 프로젝트 시에 사용한 IDE이다.
 이 두 IDE를 사용하며, 가장 놀랬던 건 기대하지 않았던 Netbeans의 편리성이었다.
내가 주로 작업하는 Visual Studio에 필적하는 편리성을 지녔고, Visual Programming 즉, Swing Programming 시에도 전혀 Visual Studio에 떨어지지 않는다고 판단했다.
거기다 2008년 Jolt Award Result도 가히 놀라운 결과를 보였다.




개발환경이라든지, 모바일 개발 툴, 웹 개발에서 무려 세부문에서 수상했다.
 Netbeans의 UML지원이라던지, 디버깅 시간 절약, 기본적인 Windows 환경에서의 GUI 프로그래밍 조차 Visual Studio에 비해 떨어지지 않는다고 판단이 되었다.

 사실 Visual Studio야 대중들이 즐겨 쓰는 IDE라 최신버전이라고 해도 이전 버전에 비해 그다지 혁신적으로 바뀐 점은 찾아 보지 못했다.

(저번 TR1 boost 세미나에 참석했을 때에, Visual C++에서 TR1을 사용할 수 있다는 점과 Microsoft .NET Framework 3.5이므로, REST나 AJAX, LINQ가 추가된 점은 꽤나 놀라웠다.)

이 두 IDE를 비교하기는 정말로 힘들다. 둘 다 너무 뛰어나고 유명한 IDE이기 때문이다.
Visual Studio는 매우 유명하고 편리한 IDE라, 점수를 측정하기 어렵고, Netbeans 또한 전혀 불편함이 느껴지지 않았고, 초보자도 쉽게 사용할 수 있는 인터페이스, 그리고 2008 Jolt Award Result에서의 수상 경력을 지니고 있어 둘 중 어떤 특정한 IDE에 점수를 더 부가하기가 어렵다.

 아쉽지만 이번 편의 승부는 무승부로 결정하게 되었다.

 

Java language vs C# language 언어론적 관점

 가장 민감하고 어려운 부분이지만, 내 주관적인 생각이기에 부담 없이 쓰련다.
두 언어다 타입 안전 객체 지향(Object Oriented) 언어로 겉으로 보기엔 너무 비슷해서, 얼핏 보면 구분하기 어렵지만 생각보다 다른 점이 많다.
첫째, 우선 Keywords부터 살펴보자.

Java

assert      

boolean   

extends     

final       

implements

instanceof  

native    

package     

strictfp    

super

synchronized           

throws      

trainsient

C#

as           base       bool         checked      decimal

delegate     enum       event        explicit     extern

fixed        foreach    implicit     int          internal

is           lock       namespace    object       operator

out          override   params       readonly     ref

sbyte        sealed     sizeof       stackalloc   string

struct       typeof     uint         ulong        unchecked

unsafe       ushort     using        virtual

 

 위의 표는 상대가 가지지 않은 Keywords를 나타낸 것이다.

 상대적으로 C#이 월등히 많다. 기능은 똑같지만 이름이 다른 것도 존재하고, 아예 기능이 존재하지 않는 키워드들도 있다. 일단 키워드만 보면 기능면에서 C#이 더 많은 기능을 가진 것 같다. 맞다. 사실 C#이 Java에 비해 C나 C++에서 상속 받은 기능도 많고, 좀 다양한 듯 하다. 따라서 C#이 키워드면에서는 우세 ^^ (물론 키워드의 수가 많다고 해서 더 좋은 언어라고 판단할 수는 없다.)

 두번째로 객체지향 프로그래밍에서 핵심이라고 할 수 있는 Class를 직접 비교해보겠다.
일단 Class란, 필드와 메소드의 결합체로써, 하나의 청사진이라고 볼 수 있다. 청사진이 있으면 여러 객체를 생성해낼 수 있듯이, Class도 마찬가지다. Class 하나로 여러 객체를 생성할 수 있다. 그렇다. C#과 Java는 Class 기반 프로그래밍이라고 해도 과언이 아니다. 이제부터 비교를 통해 한번 Java와 C#의 차이를 분석해보고자 한다.
Java든, C#이든, Class의 선언은 똑같다.


class class_name{ }

대략 위와 같은 형식이다. 이런 클래스에는 여러 접근 수정자가 존재하는데, 여기서 C#과 Java의 차이가 또 드러난다.

C#

Java

Private

Internal

Protected

Protected internal

Public

Private

Package-private

Protected

public


 Public, private, protected 세가지가 우선 같다.

아마 이 세가지는 대부분의 프로그래머라면 알고 있는 내용이다.  

public :: access not limited

private :: access limited to the containing type

protected :: access limited to the containing class or types derived from the containing class

public이란 어떤 곳에서라도 접근이 허용된다는 뜻이다.

private는 자기 자신의 객체 내에서 어디서든, 접근이 허용된다.

어떻게 보면 private는 public과 가장 대조되는 접근 수정자이다. 그리고 protected는 자기 자신과 자신을 상속받은 클래스가 접근 가능한 수정자이다.

 자바나 C# 둘다 C++과 같은 public, private, protected 세가지의 의미는 똑같고, 차이는 지금부터다.

 우선 Java에는 없는 Internal와 protected internal를 살펴보면,

internal :: access limited to this program

protected internal :: access limited to this program or types derived from the containing class.

internal의 경우 현재 네임스페이스 내에서 자유롭게 접근 가능한 수정자라고 정의할 수 있다.  Protected internal는 protected와 internal의 결합으로 볼 수 있다. Protected와 internal두 가지 특성을 동시에 가지고 있다.

 이번에는 C#에는 없는 package-private를 보자. 

package-private ::accessible from any class in the package where it is declared.

Package-private는 package내의 어떤 클래스라도 접근이 가능하다는 접근 수정자이다. 이 접근 수정자가 Java의 기본 access로 정의되어 있다. C++에서는 private가 기본 access이다.
 C#의 namespace와 Java의 Package가 비슷한 의미이다. 따라서 java의 package-private와 C#의 internal은 서로 비슷한 역할을 한다고 볼 수 있다.

 java의 접근 수정자와 C#의 접근 수정자를 비교해보니 C#은 protected internal라는 하나의 접근 수정자를 더 가지고 있다. 한번도 써 본적은 없지만, 파생클래스가 다른 namespace에 있을 때에, 접근할 수 있도록 허용한 수정자이니 만큼, C#이 이번 접근 수정자에서도 추가된 기능으로 인해 앞섰다고 볼 수 있다.

 이번엔 클래스의 중요한 기능인 상속에 대해 비교해보자.

 

Java

C#

  1.  // Inheritance
    class A extends B {
      ...
    }
  2. // Interface definition
    interface IC {
      ...
    }
  3. // Extending an interface 
    interface IC extends ID {
      ...
    }
  4. // Interface implementation
    class IE implements IC, IT {
       ...
    }
  1. // Inheritance
    class A : B {
      ...
    }
  2. // Interface definition
    interface IC {
      ...
    }
  3. // Extending an interface 
    interface IC : ID {
      ...
    }
  4. // Interface implementation
    class IE : IC, IT {
       ...
    }

 

 클래스의 상속 받아 확장할 때에 java는 extends라는 키워드를 쓰고, C#은 “:” 를 쓰게 된다.

C++을 다뤄보신 분들은 알겠지만, C#은 C++의 클래스 상속 방식을 그대로 따라 가져왔다. 그리고 Java는 C++과의 차별화를 생각해서인지, extends라는 키워드를 쓰고 있다.

 이 두 방식은 초보자가 보기에는 java가 해석 측면에서 편할 수가 있고,(사람의 언어(영어)로 쓰였으므로, 언어를 잘 모르는 사람도 대략 추측을 할 수가 있다.) C#의 경우에는 객체지향적 개념에 익숙해진 프로그래머들에게 오히려 가독성이 증가할 수가 있다. 이 둘의 경우에도 서로간에 장점이 존재하고, 단점이 존재할 수 있다.

 그리고 인터페이스를 재구현할 때에 Java는 implements 키워드를 쓰고, C#은 확장과 똑같이 ":"를 쓴다. 초보자가 보기에는 C#은 헷갈릴 수가 있다. 물론 전문가라도 자신이 만들지 않은 코드를 보면 헷갈릴 염려가 있다.

 C#은 C++의 객체지향적 표현을 가져와 C++ 프로그래머의 유입을 기대하기 위해 표현 방식을 통일한 듯 하다. 하지만 이 경우에는 Java가 좀 더 우위에 있는 듯하다. 확실하게 확장과 재구현이 구분 가능하다.

 따라서 이 경우에는 Java에게 손을 들어주련다!
 
 

 이번에는 가상함수와 메소드 오버라이드를 비교해보겠다.

 대략 코드의 내용은 이렇다.

 부모 클래스가 있고, 아들 클래스가 있다. 아들은 부모에게 물려받은 메소드를 직접 수정하고 싶어한다.

이제 자바와 C#으로 메소드를 직접 수정해보자.

 

Java

C#

  1. class A
    {
        public void F() {
            System.out.println("A.F");
        }
    }
    class B extends A
    {
        public void F() {
            super.F();
            System.out.println("B.F");
        }
    }
    abstract class C
    {
        public abstract void F();
    }
    class D extends C
    {
        public void F() {
            System.out.println("B.F");
        }
    }

     

  1.  class A
    {
        public virtual void F() { 
            Console.WriteLine("A.F"); 
        }
    }
    class B: A
    {
        public override void F() { 
            base.F();
            Console.WriteLine("B.F"); 
        }
    }
  2. abstract class C
    {
        public abstract void F();
    }
    class D: C
    {
        public override void F() { 
            Console.WriteLine("B.F"); 
        }
    }

 

 자바에서는 부모 클래스의 메소드 이름을 아들 클래스가 한번 더 정의하여 쓰고 있다.

이에 반해 C#의 경우 virtual 키워드와 override 키워드를 각각 쓰고 있다.

내 개인적인 경험상 후자의 경우가 코드의 가독성을 증가시켜준다고 생각한다.

사실 자바의 경우 상속과 다형성의 개념을 클래스 내에 체득화시킨 경우이고, (따로 virtual나 override를 쓰지 않아도 된다.) C#의 경우는 정확히 명시를 하고 있는 경우인데, 정확히 명시를 할 경우 클래스 자체의 용도를 더 파악하고, 이해하기가 쉬워진다다고 생각한다.(순전히 저의 생각 ^^)

 이유는 프로젝트 하나에 여러 프로그래머가 작업할 수 있는 경우, A프로그래머는 B프로그래머가 만든 클래스를 사용하고 싶어한다. 이 클래스가 어떠한 용도로 사용될지는 모르나, 수정해서 사용하지 말기를 권고할 필요가 있을 수 있다.

 물론 Java에서도 'final' 키워드를 통해 수정을 막을 수는 있지만 C#과 같이 virtual와 override를 정확히 명시하는 것이 프로그래머 입장에서 더 좋은 것 같다. 이러한 경우를 따져, 이번엔 C#의 손을 들어주려 한다.

 

  그리고 이제부터 부록편!!

 

 자바에는 없지만, C#에는 있는 기능들로 비교해보려 한다.

응?! 어떻게 비교를 한다는거지 ? 자바에는 없다면 대결 자체가 성사할 수 없는 것 아닌가?

사실 이번에 C#과 Java의 기능을 살펴보면서, C#의 너무나도 방대한 기능들 때문에 대결 구도를 성사시키지 못한 경우가 좀 있었다.

 하지만 분석해보면서 이게 정말 필요한지, 쓸데 없는 것은 아닌지, 라고 한번 생각해볼 수 있었다.

따라서 효율성 측면이나 간결성 측면에서 비교할테니, 한번 나가보자!

 

 C#에는 있지만 Java에는 없는 것들 :: structs, ref(함수 인자 레퍼런스 참조), 상수 표현 방법, Unsafe code 등

 

구조체 먼저 생각해보자. 정말 필요한 기능인가?

C++ 프로그래머들은 알 것이다. struct와 class의 차이는 기본 접근 수정자가 private이냐? public이냐? 에 따라 구분된다는 것을 ^^

그 이상 그 이하도 아니다.

허면 C#도 똑같을까?

C#은 구조체와 클래스가 엄연히 구분될 수 있다.

C#의 구조체는 클래스와 같이 멤버 변수와 멤버 함수를 가지고 있다. 허나, 클래스와 달리 구조체 자체는 reference type이 아니라 value type이다. 그리고 상속개념을 가지고 있지 않다. 따라서 C#의 구조체는 C의 구조체와 아주 유사하다고 볼 수 있다.

그럼 클래스보다 구조체가 훨씬 가벼울 수 있으니 필요하지 않나? 자바에는 이런 기능이 없나?

자바는 클래스가 구조체의 역할까지 모두 해낸다.

바로 Degenerate class 라고 불리는데 예로 들자면 다음과 같다.

  1. class Point{ 
  2. public float x; 
  3. public float y;
  4. }

 위의 Degenerate class는 C#의 구조체나 C의 구조체와 거의 비슷하다고 보면 된다.

따라서 나는 C#의 structs를 쓸데 없는 기능이라고 보겠다. Java의 승 !

 

다음으로 ref의 기능을 보려 한다.

사실 Java에서는 함수의 인자로 값 타입(Value Type) 이외에는 정의할 수 없다.

C#에서는 함수의 인자로 ref을 씀으로써, Reference Type 을 함수의 인자로 받을 수 있다.

말할 것도 없이 C#의 승 !

 

이번에는 상수 표현의 방법이다.

Java에서의 상수 표현은  "final" 키워드이다. C#에서는 상수를 const와 readonly 두가지 방법으로 표현할 수 있다.

어라 ? ! C#에는 상수표현법이 두개나 있네?

const :: compile-time constants.

readonly :: runtime constants.

 둘의 차이는 유동성과 속도에 있다. const의 경우는 약간 빠르지만 유동적이지 않고 , readonly의 경우는 약간 느리지만 유동성 있는 상수를 만들 수 있다는 거다.

 그리고 const는 primitive types(int, float, enum, string)만이 상수로 선언이 가능하다.

예로 아래를 보자.

  1. //compile error 
  2. private const Test TestClass = new TesetClass(); 

 이 경우에 컴파일 에러가 뜬다. const 대신 readonly를 사용해야 한다. readonly는 클래스 타입의 상수까지 허용하기 때문이다.

거기다 readonly는 runtime contants라고 했다. 따라서 컴파일 때 값이 결정되는 것이 아니라 값이 실행시간에 결정된다는 거다. 그와 관련된 예는 아래와 같다.

  1.  public static readonly uint l1 = (uint)DateTime.Now.Ticks; 

 

따라서 정리해보면, readonly 키워드를 사용한 상수의 경우 유동성이 필요한 경우와 클래스 타입에 상수를 주어야 할 때 유용하고 const의 경우 정의하자면 정적인 상수 그대로 쓰고 싶을 때 쓸 수 있다.

 

이런 C#의 세세한 부분에 비해 Java의 상수표현법은 final 하나밖에 없다.

final은 readonly와 같이 클래스 타입의 상수도 허용한다. final로 선언한 상수는 딱 한번 값을 넣을 수 있다. final로 선언한 상수는 C#처럼 compile-time, runtime 으로 구분하지 않는다. 뭐 딱히 구분하자면 컴파일 시 값을 결정하니 compile-time이 옳다고 볼 수 있지만 말이다.

 

상수의 경우에는 아무래도 C#이 좀 더 세세하게 설정이 가능해서 더 점수를 주고 싶다.

따라서 C#의 승! 

 

 그리고 이번에는 C언어 팬이라면 잊을 수 없는 개념 하나 !

메모리 참조를 프로그래머가 직접 다룰 수 있어 때로는 매우 강력하면서도 때로는 매우 위험한 포인터를 사용할 수 있느냐, 없느냐에 관해 토론의 장을 열 수있는 Unsafe code를 "VS"의 장에 올려 보려 한다.

 사실 Java를 처음 접해보았을 때, "포인터는 어디 있지?" 라는 의문을 품어 본적이 있다. 하지만 어디에서도 포인터라는 개념을 찾아 볼 수 없었고, 어느 정도 비슷한 느낌을 받은 것이라고는 레퍼런스 참조 정도 ? 하지만 포인터의 개념이 없었기 때문에 자바를 쉽게 배울 수 있었고 고민할 거리도 줄여주었다.

 물론 C#도 마찬가지다. 사실 C#도 프로그래머의 위험한 메모리 접근을 달갑게 받아들이지는 않는 언어이다. 프로그래머가 C언어보다 C#을 먼저 접했다면 Unsafe code의 존재성 자체를 몰랐을 지도 모르기 때문이다.

 포인터에 관해선 말이 많다. 그만큼 프로그래머에게는 중요하면서도 위험한 기능인데, 이런 포인터를 C#에서는 사용할 수가 있다. 아래의 코드를 보자.

  1. public unsafe struct Node 
  2. public int Value; 
  3. public Node* Left; 
  4. public Node* Right;  

이런 식으로 unsafe 수정자를 추가하면 C언어에서처럼 포인터를 쓸 수 있다.

 그치만 unsafe가 무엇인가? 안전하지 않다는 뜻이다. unsafe 내의 코드는 메모리 접근에 관한 내용을 프로그래머가 모두 관리하고, 신경써야한다. 아무래도 CLR이나 VM이 직접 관리해주는 것보다 Error가 나타날 수 있는 가능성이 훨씬 늘어 난다.

 이렇게 Error가 날 수 있는 가능성이 높아지더라도 포인터를 직접 사용해야할 경우가 존재한다. Time critical한 알고리즘을 구현할 경우나 메모리 기반 device에 직접 접근하기 위해서 꼭 필요하다. 그리고 포인터의 사용은 프로그램의 창의성을 증대시켜 준다.

 개인적으로 나 자신은 코드도 하나의 문학으로 보고, 문학의 표현은 자유할수록 더 훌륭하고 멋진 글을 낳을 수 있다고 생각한다. 하지만 시대는 이런 나만의 이런 생각을 묻혀버린다. 시대가 미래를 향해 나아가면 갈 수록 코드의 아름다움보다는 더 빠른 개발 주기를 원하고 더 많은 생산을 원하기 때문이다. (바로 누구도 어찌 할 수 없는 프로그램의 상업성 때문이다.)

 자고로 이번 Unsafe code의 경우도 프로그래머마다 필요한 기능이 될 수도 있고, 필요 없는 기능이 될 수 있다. 자바의 경우는 아예 프로그래머가 메모리 접근 운용에 관여할 수 없도록 막아버린 케이스고 C#은 프로그래머에게 Unsafe code를 통해서 어느 정도 사용할 수 있도록 열어둔 케이스이다. (어떻게 보면 Unsafe code는 에덴 동산의 선악과 열매로 볼 수도 있다. 프로그래머의 호기심과 창의적 본능에 의해 접근을 허용하지만 자칫하면 큰 재앙으로 다가올 수 있고, 잘 된다면 프로그래머의 욕구 충족에 응할 수 있는 결과를 보이기 때문이다.)

 나는 아쉽지만 이번 승부를 무승부로 볼 수 밖에 없을 것 같다. 개인적으로는 위험하지만 강력한 포인터의 기능을 사용할 수 있는 C#의 승리로 보고 싶지만, 시대와 사회는 그렇지 않다. 사회는 점점 빠른 개발의 프로세스를 원하고, 또 그렇게 시대는 변화하기 때문이다.

 

 참으로 비교할 경우가 많았는데, 중요한 개념 몇가지만 비교해보았다.

나 자신의 관점에서는 여러가지 면모에서 C#이 좀 앞섰던 것 같다. 아무래도 나는 C언어 군을 어렸을 적부터 다뤄왔기 때문에, 그리고 더 애착이 가기때문에 이런 결정을 하게 되지 않았을까?

 이렇게 나는 어원, IDE, 언어특성 그리고 부록편을 통해 Java와 C#을 비교해보았다.  

이번 “VS”를 통해서 나는 Java와 C#에 대해 다시 한번 생각 하게 되었다.

 정말 비슷하지만 다른 언어라는 걸 알게 되었고, 내가 알고 있는 지식이 한낱 얕은 지식에 불과하구나 라는 걸 깨달았다. 더욱 더 정진해야겠다는 생각을 가지게 되었다!

 그리고 비교하면서 주관적인 내 판단이 많이 들어갔었는데, 가장 최고의 언어는 가려내기 어려운 것 같다. 컴퓨터 언어나 실제 우리가 쓰는 한글이나 영어, 일어와 같은 언어나 무엇 하나 최고의 언어라고 판단하기는 어렵 듯이 말이다.

 

 결국 내린 판단은 최고의 언어는 자기 자신이 만들어내는 것 같다.

자신에게 가장 편하고 가장 많은 시간을 투자한 언어가 진정 자신이 가장 애용하는 언어가 될 것이라는 말이다. C#이 Java보다 후에 나왔다고 해서, 더 좋은 언어라고 자부할 수 있을까? 그렇다고 Java가 C#보다 더 오래된 경험과 역사를 가지고 있다고 해서 좋은 언어라고 자부할 수 있을까. 정답은 자기 자신 즉, 프로그래머에게 있다.

 "언어의 좋고 나쁨", 이런 건 중요하지 않다. 좋고 나쁜 것은 프로그래머의 창의성과 논리력, 그리고 자기 자신이 사용하는 언어에 얼마나 깊은 통찰력을 가지고 있느냐에 따라 결정된다. 나는 "VS"를 통해 말하고 싶다. 세상에 최고의 언어는 없다. 최고의 언어는 나 자신이 만들어가는 것이라고 ...

* 공유 : http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040102&docId=72876773&qb=QyMgamF2YQ==&enc=utf8&section=kin&rank=3&search_sort=0&spq=1&pid=SnU7IdpySEhsssOkmzNsssssssC-243596&sid=QURtq5J1%2BYwlLqVIvIyoYA%3D%3D

(문제시 삭제하겠습니다.)


'Programming > java' 카테고리의 다른 글

Windows10 open JDK 설치하기  (1) 2018.11.06
SSL 적용하기  (0) 2018.07.25
SMTP 이메일 보내기  (0) 2018.03.23
[java] SSLHandshakeException  (0) 2017.06.16
트랜잭션 이란  (0) 2015.02.25
은행이나 금융권 개발 쪽 말을 들어보면 트랜잭션이란 말이 많이 나온다. 또 MySQL 이용자들이 InnoDB를 사용하는 가장 큰 이유도 트랜잭션을 지원하기 때문이라고도 한다. 굉장히 좋다는 건 뭔지 알겠는데 이름만 들어서는 도통 감이 안온다. 어느 정도냐면 필자가 트랜잭션이란 말을 처음 접했을 때는 트랜지스터처럼 뭔가를 쪼끄맣게 만드는 것이나 DB에서 상거래를 이용할 수 있게 하는 기술인 줄 알았다. 게다가 트랜잭션이란 코드에서 처리하는게 아니라 MySQL쿼리문만 처리가능한 기술이라고 말도 안되는 오해를 할 때도 있었다. 물론 모두 틀렸다. 트랜잭션에 대한 개념을 간략하게 설명하자면 다음과 같다.

트랜잭션은 현대의 웹 보안에 있어서 매우 중요한 역할을 차지하며 DB와 JAVA 언어가 데이터를 주고 받는 과정에 원자성을 부여하는 수단을 일컫는다. 

트랜잭션에 대해 잘 모르는 독자들은 이 말만 들어서는 트랜잭션이 뭔지 감이 안올 수도 있을 것이다. 필자도 트랜잭션이 뭔지 알고 나서야 이 말의 감을 잡았지 결코 위의 글을 읽고 "트랜잭션이란 정말 좋은 기술이구나. 나도 해봐야겠다!"라고 생각하진 않았으니 말이다.

과거에 트랜잭션이란 소수의 웹개발자들만이 공유하는 기술로 인식되곤 했다. 굉장히 고급기술이고 손이 많이 가는 작업인지라 트랜잭션이 일반화되지 않았을 때는 트랜잭션과 비슷한 기술인 프로시져를 더 선호할 때도 있었다. 물론 아직도 트랜잭션보다 프로시져를 선호하는 사람들이 존재한다. 하지만 이런 발달된 프레임워크 덕분에 트랜잭션을 이용하는 방법이 쉬워졌고 트랜잭션의 장점 또한 더욱 부각되면서 자바진영에서만큼은 프로시져보다 트랜잭션을 선호하는 추세이다.


그렇다면 트랜잭션과 프로시져란 무엇일까? 우리가 데이터베이스와 힘겹게 씨름하며 개발을 해가다보면 어느 순간 도저히 쿼리 한줄로는 끝낼 수 없는 상황에 부닥치게 되는데 이런 단일 쿼리로 해결할 수 없는 로직을 처리할 때 필요한 기술이 바로 트랜잭션이다. 먼저 트랜잭션을 설명하는데 있어서 가장 훌륭한 예제인 전자상거래를 살펴보도록 하자.


위의 예제는 우리가 한줄로 처리할 수 없는 쿼리의 가장 좋은 예이다. 먼저 쇼핑몰에서 상품을 구매할 때 회원의 잔여금액이 있는지확인하고 잔여금액이 상품가격보다 많을 때 선택한 상품을 구매하는 로직으로 넘어간다. 그리고 선택한 상품의 재고가 있는지 확인하여 재고가 있다면 회원의 잔여금액을 상품가격만큼 감소시키고 로직을 종료한다.

로직만 본다면 완벽한 것 같기도 하다. 근데 만약의 상황을 가정해보자. 예를 들어 선택상품구매 로직에서 Exception()이 발생하여 상품이 없음에도 있다고 된 것이다. 또는 잔여금액이 감소하는 찰나에 서버의 전원이 나가 상품을 구매해버렸는데 회원의 잔여금액은 감소하지 않는 상황 말이다. 이런 문제는 곧바로 엄청난 비용손실을 발생시킬 것이다. 예를 바꾸어 금융권 경우는 어떨까? 은행같은 곳에서 특정 입력 시에 발생하는 오류를 크래커가 알아내어 송금을 하여도 자신의 계좌에서 돈이 차감되지 않는 사실을 알게 됬다면? 그 누구도 이런 전자상거래는 이용하고 싶지 않을 것이다.

트랜잭션이란 바로 이런 문제를 해결하기 위해 탄생한 기술력이다. 2개 이상의 쿼리를 하나의 커넥션으로 묶어 DB에 전송하고 이 과정에서 어떠한 에러가 발생할 경우 자동으로 모든 과정을 원래 상태로 돌려놓는다. 그야 말로 All Or Nothing 전략이다. 프로시져도 같은 맥락이긴 하지만 차이점은 로직을 Java에서 처리하는게 아니라 DB상에서 처리한다. 과거 트랜잭션 구현이 어렵고 프로시져 구현이 더 간편했을 때만 하더라도 많은 웹어플리케이션이 비지니스 로직을 Java가 아니라 DB에서 처리하는게 유행했던 시절도 있었다.

좀 황당한 사실이긴 하지만 진짜다. 혹자는 이 때는 일컬어 자바의 암흑기라고도 한다. 자바 프로그래머들이 고작 하는 거라곤 DBA(DataBase Administrator)가 짜준 로직을 호출하고 결과값을 대충 조작해 리턴해주는게 대부분이었다. 이런 개발 방식에서는개발자가 DBA님을 상전 받들 듯이 모셔야 하며 모든 로직을 구현하는데 있어 DBA님이 선사하신 프로시져를 감사한 마음으로 사용하다가 만에 하나 오류가 발생하면 이게 프로시져의 문제인지 내 코드의 문제인지 밤잠설치며 고민하다가 은근슬쩍 DBA님에게 커피라도 한잔 마치면서 넌지시 물어봐야 했던 것이다.

심지어 현장에 투입된 신입프로그래머들은 웹어플리케이션마다 제각각으로 짜진 난해한 프로시져들을 완전히 습득하기 전엔 키보드에 손도 못올릴 때가 있었다. 그 뿐이던가. 초기에 가난한 벤쳐회사가 MySQL을 이용해 서비스를 하다가 어느 정도 성장해 Oracle 같은 유료 데이터베이스로 교체할 때, 또는 하나의 웹어플리케이션에 2개 이상의 데이터베이스를 사용할 때에는 그야말로 개발자와 DBA가 서로 멱살을 움켜지며 매일같이 댄싱파티를 열어대는 장관이 연출될 때도 있었다.

왜냐하면 자바는 mysql 커넥터에서 oracle 커넥터로 라이브러리만 교체해주면 그만이지만 DBA들은 기존의 DB에 있는 프로시져들을 몽땅 새로운 DB에 옮겨 주어야 했기 때문이다. 게다가 옮기는 과정에서 생기는 오타나 데이터베이스 제품마다 다른 성질로 발생하는 문제까지 테스트 하자면 개발자들은 연이어 발생하는 트러블 때문에 모든 다시 코드를 뜯어봐야 했고 수정해주어야만 했다.

그러나 이제 트랜잭션 기술의 발달로 이런 문제는 옛날 일이 되었다. 물론 프로시져가 트랜잭션보다 속도가 빠르다는 이유로 아직도 프로시져를 사용하는 그룹이 있긴 하다. 하지만 서버의 퍼포먼스 향상과 기술이 발달로 그런 속도차는 극단적인 상황이 아닌 이상 미미한게 사실이다.

다시 본론으로 돌아가자면 트랜잭션은 하나 이상의 쿼리에서 동일한 Connection 객체를 공유하는 것을 뜻한다. 이게 뭔말인가 하면 Java에서 DB로 연결할 때는 java.sql.Connection이란 객체를 이용하는데 이 Connection 객체에는 setAutoCommit(자동커밋)이라는 메서드가 존재한다. 이 메서드와 연결된 autoCommit 객체는 true란 기본값을 가지고 있으며 한번의 연결 이후 자동으로 커넥션을 커밋해 종료시켜준다. 근데 트랜잭션을 이용하려면 이 자동커밋을 false로 바꾸고 수동커밋으로 변경해야만 한다. 즉 이용자가 직접 커넥션에 대해 커밋과 롤백을 해준다는 뜻이다.

Commit(커밋) : 해당 Connection의 요청을 완료하고 특별한 에러가 없다면 결과를 DB에 반영한다. 
RollBack(롤백) : 해당 Connection 수행 중 예기치 않은 에러가 발생하였다면 모든 과정을 취소하고 DB를 Connection이 수행되기 이전상태로 변경한다.

물론 스프링의 트랜잭션 기술을 이용하면 이런 과정을 직접 해줄 필요는 없다. 스프링은 단 몇줄의 코드만으로 다이나믹 프록시와 AOP라는 기술을 통해 크게는 인터페이스 단위에서 클래스, 작게는 메서드까지 세분화하여 트랜잭션을 컨트롤할 수 있게 한다. 거기다 애노테이션 기술로 @Transactional을 설정하는 것만으로도 메서드 또는 클래스, 인터페이스까지 트랜잭션 설정이 가능하게 해준다.

우리는 여러 오픈소스 개발자들의 노력 덕분에 트랜잭션을 편리하게 이용할 수 있게 됬으며 금융권, 상거래에도 문제없이 비지니스 로직의 주도권을 찾아올 수 있게 되었다. 다음 장에서는 본격적으로 스프링의 트랜잭션에 대해 다뤄보도록 하겠다. 마지막으로 덧붙이자면 우리가 이처럼 트랜잭션 쉽게 구현할 수 있고 또 이용할 수 있다면 이젠 트랜잭션도 선택이 아닌 필수 사항이 되어야만 한다. 감당할 수 있는 에러라도 발생하지 않도록 하는 것이 가장 현명한 처사 아니겠는가!

* 공유 : http://springmvc.egloos.com/495798 (문제시 삭제하겠습니다.)

'Programming > java' 카테고리의 다른 글

Windows10 open JDK 설치하기  (1) 2018.11.06
SSL 적용하기  (0) 2018.07.25
SMTP 이메일 보내기  (0) 2018.03.23
[java] SSLHandshakeException  (0) 2017.06.16
c#과 java 차이  (4) 2015.03.04

mySQL 접속 & 재시작



  • 윈도우 

cmd 창에서 

net stop mysql;

재시작

net start mysql;

 

  • 리눅스

mysqladmin -u root -p shutdown || kill mysqld

재시작

mysqld_safe & safe_mysqld &

mysql.server 파일을  가지고 있다면

MySQL중지 : MySQL홈디렉토리/mysql.server stop 

MySQL시작 : MySQL홈디렉토리/mysql.server start

MySQL재시작 : MySQL홈디렉토리/mysql.server restart

 

패키지로 설치 했을시에 자동으로 /etc/rc.d/init.d에 등록되어진다.

MySQL중지 : service mysqld stop

MySQL시작 : service mysqld start

MySQL재시작 : service mysqld restart 



'DataBase > MySQL' 카테고리의 다른 글

[CentOS] mysql, maria DB sql 파일 import  (0) 2016.02.29
CentOS 7 mariaDB  (0) 2016.02.29
MySQL] dump / import  (0) 2016.01.24
[MySQL]DELETE Join delete  (0) 2015.09.21
[MySQL] Date 날짜 형식 바꾸기  (0) 2015.09.21

+ Recent posts