Wednesday, December 31, 2008

Java annotations revisit

As previously mentioned, annotation is not a "buzzword" when it is in the Tiger (Java SE 5) specs. But it turns out to be the most excellent feature of Tiger, and it saves Sun reputation from community's complaint about their howlers before (such as EJB1 and EJB2). Now that a little water has flowed under the bridge, I think it is time to revisit Java Annotations.



=== Java Annotations ===


Annotations are presented as metadata – that is data about data. In the case of Java this means that they provide information about various elements of a Java class. For example, they may annotate a method, class or instance variable. One example of an annotation is to note that a method has been deprecated, or that it overrides a method in the superclass. These annotations can then be used by an annotation processing tool (such as APT), or an IDE (such as Eclipse) or indeed a framework, to validate, configure or add to the original Java. For example, if you have annotated a method as overriding a parent class method, then the annotation processing can confirm that you are indeed overriding a method.


There are seven annotations provided in the J2SE 5.0 release (see the annotations guide here; these are provided in two packages, java.lang and java.lang.annotation:



In the package java.lang there is:

@Deprecated – indicates that the associated Java element has been deprecated. It is an alternative to using the Javadoc @deprecated element. A deprecated method or class is essentially one that should no longer be used and that is not guaranteed to be available in future versions of the software. It is thus often useful to know that you are using “old” versions of an API. Although the use of the Javadoc tag already allows many tools (such as Eclipse) to indicate that a language feature is deprecated, the use of the @Deprecated annotation makes this simpler and allows a wider range of tools to report on the use of deprecated features.


@Override - indicates that the method should override a method in the superclass.


@SuppressWarning – directs the compiler to suppress the specified warning.



In the package java.lang.annotaiton:


@Documented – directs tools to automatically generate Javadoc for the annotated element (e.g. a method or variable).


@Inherited – this indicates that the associated annotation is inherited by subclass of the current class.


@Retention – indicates how long annotations with the annotated type are to be retained. For example, a retention type of RUNTIME indicates…


@Target – This indicates the Java element to which associated annotations apply.

It is also possible to extend the set of annotations available by defining your own annotations. This enables project, task and company specific annotations to be created.




=== What are annotations for? ===


Annotations are intended to provide three basic facilities. These facilities are:


• The provision of additional semantics for various class elements. This additional semantic information can help developers to understand the intent behind some feature or implementation detail.


• The execution of additional compile time checks that ensure various constraints are met.


• The support of additional code analysis by annotation-aware tools.


None of these requirements are new and indeed many developers have found ways of overcoming the lack of any annotation-like feature in previous versions of Java.


For example, I have tended to make extensive use of Marker Interfaces over the last few years. These are interfaces that may not contain any methods, but are used to denote a particular concept or entity within an application. This is not a particularly radical idea and indeed there is an example of such an interface in the Java language itself - the java.io.Serializable interface. This interface is a marker interface in that it does not require any methods to be implemented but indicates that a class is capable of being serialized via the Java Serialization mechanism.


Such marker interface can now be replaced with annotations. We can define our own annotation that can be used to mark a class as being a particular concept or entity etc.




=== Using annotations ===


Annotations are straightforward to use; they merely require that an appropriate annotation type be placed directly before the Java language element being annotated. For example:


public class Person {

@Override
public String getName() {
return this.name;
}
}

This means that when this code is compiled, or when it is analysed by tools such as Eclipse, a check can be made to ensure that the method getName() does override a method in the class Person’s superclass. In this particular case, the class Person extends the class Object as a default. The class Object does not contain a method getName() and thus it does not override such a method. This therefore results in an error message being generated. For example, in figure 1 Eclipse has identified that the method getName() should override a method in the parent class and has provided a pop up to this effect.


Screenshot showing Eclipse analysing annotations


However, marking which methods you expect to override parent class methods is probably a step two far for many developers. A rather more useful annotation may be the @SuppressWarnings annotation.


The @SuppressWarnings annotation can be very useful if you have some code that uses a deprecated method or class (possibly because it has been in your system since before that method was deprecated) and you do not want the compiler to churn out lots of warnings about using deprecated APIs. By using the @SuppressWarning annotation and the parameter value “deprecation” it is possible to suppress (turn off) the production of the deprecated warning. For example:


@SuppressWarnings("deprecation")
public static void terminateProcess() {
Thread.currentThread().stop();
}


=== Defining your own annotations ===


You can easily create your own annotations by defining a new annotation type. This is done using a new piece of language syntax, the @interface key word. For example, to define a new annotation @Auditor we would define the following annotation type.


public @interface Auditor {

}

Note that although the syntax for this is almost exactly the same as for a standard interface, the “@” symbol at the start of the keyword changes this to be an annotation declaration. When you compile the resulting Auditor.java file this creates a standard Auditor.class file. If you place this class file on your class path, then you can use this new annotation type within your Java code. For example, if you place the @Auditor just before the class declaration, this marks the class as being of the entity type Auditor. This is illustrated in Figure 2.


A screenshot showing the use of the @Auditor annotation


You can also define parameters that can be used with annotations, and accessor methods for retrieving information about the options specified with an annotation.




=== Drawbacks of Annotations ===


Annotations are not without their drawbacks. Not least of which is that they are not really metadata – that is they are not data about data – they are data about classes, methods, instance and static variables etc.




=== Window dressing ===


As such annotations are syntactic sugar – they coat the elements of a class without actually telling you anything in detail about that class (you can use the reflection API for some of that). Thus they provide guidance to processors, tools and frameworks to help in the analysis, compilation or deployment of that software.

Inheritance


One of the major features of an object-oriented system is inheritance. You can subclass a class, and subclass an interfaces – but you can’t subclass annotations.




=== Null values ===


If a null value should be treated as an un-initialized value then annotations are somewhat awkward in the way they handle these – rely on the developer to provide a way of indicating un-initialised rather than initialised to null.




=== Values in General ===


These are somewhat limited in what you can use – although in the main this is fine.




=== Annotations hold constants ===


The values used with annotations are hard coded rather than variable. Thus if an annotation takes a literal value of 40 – then that value is now hard coded into your program.




=== Annotations and code synchronization ===


Just as with Javadoc comments themselves, annotations need to be maintained to reflect any code changes that may occur. However, as we all know, it is all too easy to change the source code and not to update the associated Javadoc (even when they are next to each other). Exactly the same is true for annotations. If the code relating to an annotation changes, then the associated annotation may also need modification. This may not be as straightforward as it seems. For example, if I rename a method in a class I am working on, then this may impact on another class, that I may know nothing about; if that class requires that one of its methods overrides mine (due to the use the @Override annotation). Of course this may be what is desired or it may not! As you can define your own annotations this situation may become much worse, with significant repercussions for on-going maintenance, clarity and general stability of the code.




=== Summary ===


So where does that leave the question “To Annotate or not to Annotate?”. In essence, as with many things in life, annotations can be very useful but should not be over used or abused. They can add extremely useful additional information to Java code that can be analysed by tools, frameworks, analysers as well as developers themselves – but they should not be used without due consideration.




(main reference: TheRegister)
See also :
http://javabeat.net/articles/30-annotations-in-java-50-1.html
http://www.developer.com/java/other/article.php/10936_3556176_1
http://www.oracle.com/technology/pub/articles/hunter_meta.html
...

Monday, December 29, 2008

JavaCard quick notes [2]

Tiếp tục JavaCard nào


=== Các lỗi thường gặp với JCOP ===

Sau một hai buổi mày mò lăn xả với JCOP, mình trở về với thân thể trầy xước tả tơi, dưới đấy là vài kinh nhiệm mình gặp phải và cách xử lý


1 - Lỗi upload ".cap" file không thành công.
Lý do:
- Build file cap không thành công, không có file .cap để upload.
Xử lý:
- Từ menu Window->Preferences..-> Java->Compiler
- Hiệu chỉnh "Compiler Complance level" -> 1.5
- Build lại project của bạn và Run.


2 - Lỗi không thể send các command.
Thông báo lỗi:
- "CLA value not supported"
- "INS value not supported"
Lý do:
- process() của bạn hiện tại không bắt, xử lý được với các mã CLA/INS lệnh theo yêu cầu.
Thông báo lỗi:
- "Conditions of use not satisfied"
Lý do: bạn phải /select applet mới có thể bắt đầu truyền các command hoặc applet chưa được xác thực (nếu có)


3 - Lỗi "No precise diagnosis"
Đây là lỗi làm "điên người" nhất mà mình tạm cho 1 lý do tạm là .. trình biên dịch JC còn củ chuối. Khi gặp lỗi này, bạn nên xóa mọi hành động vừa mới làm và bắt đầu cẩn thận lại từ bản backup gần nhất :D, nôm na ra là .. bó hand

Vài lỗi nhỏ trên là cơ bản, sẽ còn lỗi nhiều nữa, mình sẽ liệt kê thêm nếu gặp phải



=== Vòng đời của 1 "cardlet" ===

Trước tiên lưu ý: "Cardlet" là cách gọi của mình về applet của JavaCard, chưa phải thuật ngữ chính thức.

Theo đặc điểm kỹ thuật, vòng đời của một JavaCard Applet bắt đầu từ khi "em" được đăng ký vào card với phương thức Applet.register() . JCRE (JavaCard Runtime Environment) sẽ tương tác với applet thông qua các phương thức tĩnh của applet là: install, select, deselect process.


Phương thức install():
Khai báo:
public static void install(
byte[] bArray, short bOffset
, byte bLength )
throws ISOException;
- Khi applet được cài đặt vào JC, phương thức install được thực thi một lần duy nhất cho mỗi thể hiện của applet. Các phương thức khởi dựng không nên được truy cập một cách trực tiếp mà phải thông qua phương thức install. Nhiệm vụ chính của phương thức install là tạo thể hiện của applet thông qua các constructor và đăng ký applet với JCRE thông qua phương thức register(). Chỉ khi được đăng ký thành công, JCRE mới có thể cho phép thao tác lệnh APDU với applet.


Phương thức register(..):
Khai báo:
protected final void register()throws SystemException;
protected final void register(
byte[] bArray,short bOffset
,byte bLength)throws SystemException;
- Phương thức này được dùng để đăng ký một thể hiện của ứng dụng "cardlet" với JCRE với một mã (AID) xác định. Mã AID xác định bởi một chuỗi Hexadecimal, có độ dài trong khoảng 5-11 bytes (1byte = 8bits). Mã AID này là tham số đầu vào cho lệnh Select applet. Thông thường, phương thức register() được gọi từ thân của phương thức install() để applet được đăng ký với JCRE 1 lần cho mỗi card.


Phương thức select():
Khai báo:
public boolean select();
- Phương thức select() cho phép chuyển quyền nhận lệnh cho một thể hiện của Applet. Phương thức select applet được JCRE thực thi khi JCRE nhận được lệnh SELECT FILE APDU cùng một mã Applet từ thiết bị. Việc select Applet sẽ chuyển trạng thái applet từ deselect -> select và cho phép applet nhận các lệnh từ bên ngoài thông qua phương thức process() do JCRE chuyển giao. Tuy nhiên, trước khi select Applet, JCRE sẽ tự động thực hiện hành động deselect() một (hoặc các) applet đã được select trước đó.


Phương thức process():
Khai báo:
public void process(APDU apdu) throws ISOException;
- Sau khi được select(), tất cả các lệnh APDU sẽ được JCRE chuyển cho Applet thông qua phương thước process(). Các nhân xử lý của applet sẽ được thể hiện (hoặc phân hướng xử lý) ở phương thức này. Từ đây, các thao tác dữ liệu, nhận và trả lệnh APDU được thực hiện trên vùng buffer có giới hạn đã được applet đăng ký trong hàm register().


Phương thức deselect():
Khai báo:
public void deselect();
- Phương thức được gọi thực thi bởi JCRE khi có yêu cầu hoặc khi có hành động select một Applet khác. JCRE sẽ tự động thực hiện deselect() Applet hiện tại.
- Khi có lỗi khi thực hiện deselect, JCRE sẽ tiếp nhận lỗi, và tại thời điểm đó, applet đã được deselect.

GoF Design Patterns [5]

Adapter


Decorator


Visitor




(will be updated on demand)

Sunday, December 28, 2008

PureMVC framework notes

PureMVC is a lightweight framework for creating applications based upon the classic Model, View and Controller concept; based upon proven design patterns



This free, open source framework which was originally implemented in the ActionScript 3 language for use with Adobe Flex, Flash and AIR, has now been ported to nearly all major development platforms. It seems PureMVC is more popular in other languages (Java, C#, Ruby, ... ) than its competitor (Cairgorm) .





(to be updated)

Wednesday, December 24, 2008

GoF Design Patterns [4]

Abstract Factory

Proxy

Mediator





(will be updated on demand)

Tuesday, December 23, 2008

JavaCard quick notes

Những ai đã biết đến Java thì chắc hẳn cũng biết Sun đã phân Java ra làm 3 nền (platform) chính: Standard (Java SE), Enterprise (Java EE) và Micro (Java ME) . Tuy nhiên hiện nay có 2 hướng phát triển của Java có thể vươn ra thành 1 platform mới, đó là JavaCard và JavaFX .

Về JavaFX thì đã có giới thiệu sơ trong bài RIA , tuy nhiên triển vọng của JavaFX không khả quan lắm, khi 2 đối thủ cạnh tranh là Silverlight và Flex/OpenLaszlo đã vượt lên hẳn.

Còn JavaCard vẫn là 1 lĩnh vực mới mẻ ở VN , tuy nhiên tiềm năng rất lớn, vì có thể xây dựng hệ thống bán lẻ, hệ thống máy tự động (kiểu ATM cho ngân hàng), cũng như chính phủ điện tử. FYI, công ty lợi nhuận lớn nhất ở Hoa Kỳ năm ngoái là, không phải Microsoft vì MS chỉ đứng khoảng hạng 10, chính là WalMart , hệ thống bán lẻ giá rẻ toàn nước Mỹ. Bây giờ một số công ty VN bắt đầu tính đến thị trường này, và nước ngoài cũng có công ty ngấp nghé nhảy vào làm, vì thế JavaCard có tiềm năng khó lường.


Xin đưa lên vài bài dịch của bạn Trịnh Quốc Hùng để các bạn hiểu hơn về JavaCard .



=== Cài đặt plugin JCOP (3.1) cho Eclipse ===

Xin đặt vài dòng giới thiệu ngắn ngủi, JCOP - JavaCard OpenPlatform - khởi nguồn do IBM nghiên cứu - với tên gốc là JavaCard - là một bộ khung lập trình để phát triển cho công nghệ các loại thẻ thông minh (smart card), cho phép lập trình trên các loại thẻ có chip xử lý nhỏ mà ta đã thấy ứng dụng của chúng trong thực tế ngày nay: sim điện thoại, thẻ ngân hàng, thẻ nhân viên thông minh...
Nhưng sau năm 2007, IBM ngừng đầu tư và chuyển giao công nghệ cho hãng NXP Semiconductors - một trong những tập đoàn hàng đầu thế giới về công nghệ thẻ bao gồm cả thẻ "không tiếp xúc" (contactless). Từ đó, công cụ này có tên mới là JCOP với các version phát triển 1.0, 2.1 , 3.1, 4.1... Ngày nay, công cụ này không còn được tìm thấy trên mạng, mà nó chỉ được chuyền tay qua các thành viên hoặc được cấp từ chính hãng NXP với điền kiện có đăng ký hợp đồng. Dưới đây mình sẽ liệt kê từng bước cài đặt JCOP 3.1 thành công:


Điều kiện :
- Eclipse IDE từ version 3.2 đến 3.3.1, dùng khác các version này không đảm bảo build CAP file thành công.
- JCOP plugin for Eclipse version 3.1.2 , tool này bạn phải tự tìm hoặc đăng ký với NXP Semiconductors.


Thực hiện:
- Sau khi giải nén và khởi động IDE Eclipse.
  1. Chọn menu Help > Software Updates > Find and Install
  2. Trong hộp thoại Install/Update, chọn Search for new features to install và chọn Next
  3. Chọn nút nhấn New Archived Site . . . và chỉ đường dẫn đến file n
  4. Chọn liên tiếp Open -> OK -> Finish
  5. IDE Eclipse sẽ đòi hỏi khởi động lại.
Sau khi khởi động thành công, trong mục New Project sẽ có thêm cấp project "JavaCard Project". Nếu thấy mục này, coi như bạn đã cài đặt thành công plugin JCOP for Eclipse.


=== Tạo một JavaCard Project ===

theo các bước sau
  1. Trong menu New -> Project...
  2. Tại hộp thoại New Project, chọn mục JavaCard Project và chọn Next.
  3. Tại hộp thoại Java Card Project, điền thông tin Project Name và chọn Next.
  4. Tại đây bạn đã có thể chọn Finish. Nhưng mình thì thích đi từng bước hơn.
  5. Nếu chọn Next, bạn sẽ có thể chọn các chuẩn configuration card xác định cho loại project của mình (Java Card 2.2.1, JavaCard 2.1.1, Global Platform, ...)
  6. Chọn Next, chọn mục "Create a JavaCard Application using ...", chọn item "Basic JavaCard applet".
  7. Điền thông tin Package và Applet ClassName. Package là gói chứa đựng các Applet. Applet là gói ứng dụng sẽ được cài lên các chip xử lý.
  8. Chọn Next, điền thông tin PackageAID và AppletAID. Đây là mã xử lý của Package và Applet trên chip. Lưu ý: PackageAID và AppletAID được đặt tên dưới dạng chữ số hexadecimal. Chiều dài cho cả Package AID và AppletAID là 5 bytes. (bạn có thể đọc thêm thông tin trong tài liệu "Smart Card Handbook" để nắm vững hơn)
  9. Chọn Finish.
  10. Tới đây là bước kiểm tra bản quyền của NXP, cử sổ activate code sẽ hiện cho bạn 3 action activate: Đăng ký 1 activate code mới, sử dụng thẻ được cung cấp bới NXP để activate hoặc nhập lại 1 activate code đã được cung cấp bới NXP. Nếu không qua được bước này thì coi như quá trình tìm hiểu JavaCard, cardlet buộc phải chấm dứt.

Xong 9 bước trên vẫn chưa xong, mục đích là phải build được file có đuôi là .cap mới có thể upload vào thẻ. Dưới đây là các bước để Run/Debug project, trong quá trình Run/Debug thành công, file .cap sẽ được build và đặt ở thư mục "../bin" của project.
  1. Trong menu Run -> Open Run/Debug Dialog..
  2. Tạo mới một "JavaCard Application" và đặt các cấu hình phù hợp cho project.
  3. Chọn Run/Debug.

Kết quả trong cửa sổ JCOP Shell:


chú ý dòng : "cm> upload -b 250 .... .cap" là đường dẫn đến file cap đã được build thành công.
"cm> install -i abababab01 -q C9#() abababab00 abababab01"
-
abababab00 là tên packageAID
-
abababab01 là tên appletAID

"cm> card-info" cho thông tin card sau khi upload applet thành công.

Đến đây xem như bạn đã có thể tạo được một card applet (.cap) . Công việc kế tiếp sẽ còn nhiều cam go, nhưng đến đây mình cần phải dừng lại để suy ngẫm, đúc kết lại những gì mình đã làm được. Làm ly cafe nào.

Saturday, December 20, 2008

GoF Design Patterns [3]

Tiếp tục với những design patterns dễ gặp:


Factory Method (creational)

Facade (structural)

Observer (behavioural)





(will be updated on demand)

Friday, December 19, 2008

ActionScript 3 notes

=== Data types ===

Top level types:

- void, int, uint,
- Object, Number, String, Boolean, Null


Complex types:

- Date, Array, ByteArray, Vector, Dictionary, RegExp, Function, Error
- XML, XMLList, BitMap, Shape, MovieClip, Video, SimpleButton, TextField



=== Declaration ===:

Package, import, class:

package com.example {
import flash.net.URLLoader;
import flash.net.URLRequest;
public class Example {
// Class code goes here.
}
}


Access modifiers:

public : accessible outside the class (e.g., from an instance of the class).
private : accessible only within the class.
protected : accessible only within the class and its subclasses.
internal : accessible only within the package.


Variable/constant, field/property:

var myObject: Object = {Param1:"Hi!", Param2:76};
public var myString: String = "ABC";
protected var myNumber: Number = 5;
private var myInt: int = 12;
var myBoolean: Boolean = true;
var myArray: Array = [5,"Hello!",{a:5, b:7}]
private var myDate: Date = new Date();
var myButton: mx.controls.Button = new mx.controls.Button();
static public const MY_TEST: String = "test constant";

var authorsByBook:Object = new Object( );
authorsByBook["Flex"] = "Mediocre, Ninja";
authorsByBook["ActionScript 3"] = "bibo, ninja, mediocre";



Function/method/constructor:

function test( ):void {
var message:String = "function message";
trace(message);
}




=== Formal syntax ===

Expression/Statement/FlowControl

while(total < int =" 0;"> maxTotal + 20) {
total -= 10;
}
else {
total -= 5;
}



Inheritance

package com.example {
import com.example.A;
public class B extends A {
override public function run( ):void {
trace("B");
}
}
}


Interface

package com.example {
public interface IExample {
function a( ):String;
function b(one:String, two:uint):void;
}
}

package com.example {
import com.example.IExample;
public class Example implements IExample {
public function Example( ) {
}
public function a( ):String {
return "a";
}
public function b(one:String, two:uint):void {
trace(one + " " + two);
}
}
}


Handling Event

;lt&mx:Script;gt&
;lt&![CDATA[
import flash.net.FileReference;
private function initializeHandler(event:Event):void {
var file:FileReference = new FileReference( );
file.browse( );
file.browse( );
}
]];gt&
;lt&/mx:Script;gt&


Handling Error

try {
// Code that might throw errors
}
catch (error:IOError) {
// Code in case the specific error occurs
}
catch (error:Error) {
// Code in case a non-specific error occurs
}
finally {
// Code to run in any case
}




(to be updated)

Wednesday, December 17, 2008

GoF Design Patterns [2]

Hãy bắt đầu bằng những Design Pattern đơn giản và dễ gặp nhất :-) .




Singleton (creational)

Bridge (structural)

Command (behavioural)



(will be updated on demand)

Monday, December 15, 2008

Rich Internet Application

Nói đơn giản, Rich Internet applications là những ứng dụng (application) chạy trên mạng máy tính (cụ thể là Internet) mà có nhiều tính năng (rich features) như là ứng dụng chạy stand-alone trên máy không nối mạng (thường gọi là desktop application) .


=== Sự ra đời của RIA ===

Từ những ngày khởi thủy của những ứng dụng trên máy tính đều được thực hiện trên các máy tính lớn (mainframe). Các máy trạm chỉ làm nhiệm vụ hiển thị thông tin được xử lý từ các mainframe. Sau đó, tốc độ phát triển phần cứng cho các máy trạm (terminals - từ đây ta sẽ gọi chung là clients , mặc dù không đúng lắm ) nhanh như vũ bão. Từ tốc độ xử lý, hệ thống lưu trữ, bộ nhớ đến các thành phần khác dành cho clients đều phát triển rất nhanh.Như vậy, nếu chỉ dành toàn bộ việc tính tóan cho mainframe, và các clients chỉ để hiển thị thông tin sẽ vô cùng lãng phí tài nguyên.

Sau đó đến giai đoạn phát triển của các ứng dụng dạng client/server. Lại có vấn đề về hệ thống phân tán. Sẽ mất nhiều công sức cho việc cài đặt, bảo dưỡng các ứng dụng trên clients. Rồi việc đảm bảo các ứng dụng trên clients phải tương thích với các platforms khác nhau.

Vào những năm 90, internet ra đời. Việc sử dụng các web browsers cho các thin clients được áp dụng rất mạnh mẽ và hiệu quả. Nhưng (lại nhưng) kiểu lập trình page-to-page, khiến các nhà phát triển ứng dụng rất khó khăn, mệt mỏi và có rất nhiều hạn chế. Rồi các giao diện người dùng đơn điệu, không hiệu quả. Để cố gắng khắc phục những nhược điểm này, RIA đã ra đời. Vậy RIA có những khả năng gì?
(Về định nghĩa, xin xem lại ở đầu bài này)


=== Khả năng của RIA ===

Có khả năng tương tác với DOM (Document Object Model), xây dựng những ứng dụng chạy trên nhiều loại browsers và platforms.

Có khả năng sử dụng được các đối tượng trên server như web services hay những công nghệ tương tự khác, làm cho các ứng dụng trên clients có thể kết nối với server minh bạch hơn, dễ dung hơn.

Có khả năng làm việc “offline”. Dữ liệu được đưa về clients, xử lý tại clients, sau đó trả lạ cho server, tránh việc quá tải đường truyền cũng như hệ thống xử lý của server.


=== Các khuynh hướng xây dựng RIAs ===

Hiện nay có 4 trường phái xây dựng RIAs : đầu tiên là Ajax (Asynchronous Javascript and XML) : sử các thư viện JavaScript như Dojo, OpenRico, Backbase và Yahoo ToolKit, etc . Tiếp theo là RIAs trên nền Flash Player với các công cụ như Flex, OpenLaszlo ( đây là công cụ Open source). Thứ 3 là Windows Presentation Foundation (WPF) sử dụng .NET framework 3, trong đó quan trọng là Silverlight. Cuối cùng là JavaFX, kết hợp với các công cụ GUI như : AWT/Swing, và Eclipse RCP (SWT/JFace). Trong đó, dường như WPF và JavaFX nhắm vào ứng dụng desktop hơn là RIAs, mặc dù chúng đều có thể phát triển cho RIAs.


Ajax : là 1 thuật ngữ. Nó được các nhà phát triển kết hợp từ nhiều công cụ (HTML,DHTML, Javascript), công nghệ, để chuyển dữ liệu từ server tới client mà không phải reload lại page. Thực ra, trước đây IFrames đã làm được những công việc này. Gần đây, Java script sử dụng XMLHttpRequest để thay thế applets, Iframe.


Flash : Là nền tảng để triển khai RIAs. Trước đây, flash được phát triển nhằm mục đích phục vụ xây dựng animations. Sau nhiều thập kỷ thành công, tới nay có tới 97% (theo Adobe Flex 3 : Training from the Source) các web browsers có cài đặt flash. Adobe nhận ra rằng, với flash có thể làm nhiều hơn việc chỉ phát triển animations. Vì thế Flex đã ra đời.

OpenLaszlo : là phần mềm open source với nền tảng phát triển là Javascript và XML và chạy trên nền flash. Các ứng dụng cũng được biên dịch thành các files SWF. Vì là công cụ open source nên Laszlo cũng gắn bó chặt chẽ với LAMP (Linux, Apache, MySQL và PHP).

Flex : (vì Flex là cái chúng ta đang quan tâm nên mình tách riêng ra 1 mục) được xây dựng với nền tảng là Eclipse. Flex 1 là phần mềm open source. Tuy nhiên, vào giữa năm 2006, Adobe đã thương mại hóa Flex 2, với những tính năng và ưu điểm vượt trội bản Flex 1. Gần đây, Adobe đã chính thức phát hành Flex 3 có những phần đáng chú ý như : Adobe AIR, cải thiện đáng kể hiệu năng của những files SWF. Có khả năng tích hợp các middle layers ngay trong ứng dụng như : PHP, ColdFusion, WebService, Flex Data Server (hay còn gọi là FDS). Từ phiên bản Flex 2 trở đi, các ứng dụng sử dụng ActionScript 3 và chạy trên nền Flash Player 9. Flex cho miễn phí Flex SDK, cũng như AIR SDK, chỉ thương mại Flex Builder (với giá bản full của Flex Builder 3 Pro là 699$). Thêm nữa, Flex là sự kết hợp không thể tách rời của ngôn MXML và ActionScript.


Windows Presentation Foundation (WPF) : là 1 tập hợp các công cụ để xây dựng các ứng dụng RIAs trên nền Windows.

WPF : nền tảng để xây dựng và chạy RIAs.
XAML : ngôn ngữ xây dựng nên RIAs.
Visual C# : IDE để viết ra RIAs


Java (JavaFX) : thật đáng tiếc , cho đến nay thì JavaFX vẫn chưa làm được gì nhiều và có vẻ đang tụt lại đáng kể trong cuộc đua này. Hy vọng Sun dẹp bớt những tham vọng ngu ngốc và hướng tới cộng đồng hơn, khi đó mới có thể hy vọng cạnh tranh thị phần RIA được.



(tạm thế đã , sẽ định dạng bài viết lại sau)

Sunday, December 14, 2008

GoF Design Patterns

Có lẽ không cần giới thiệu nhiều về Design Patterns (Mẫu Thiết kế), cũng như quyển sách kinh điển của Gang of Four (Bộ Tứ - a.k.a Bè lũ 4 tên) vì bây giờ đã quá nổi tiếng rồi.

Việc nắm được các Design Patterns ngoài việc cải thiện tư duy hướng đối tượng, nó giúp dự án nhanh chóng có được thiết kế tốt, vì thế reduce cost & development interval, đồng thời improve productivity & customer satisfaction. Đối với bản thân developer thì ít ra cũng hấp dẫn ở chỗ là có thể làm thay đổi đáng kể mức lương :D .
Do đó bạn nào muốn tìm hiểu kỹ hơn thì nên nghiền ngẫm sách và code nhiều vào, chứ các bài blog như bài này chỉ nêu như cưỡi ngựa xem hoa thôi :D


Trong sách DP của GoF, 23 mẫu được phân thành 3 categories là: Creational (khởi tạo) - 5 mẫu , Structural (cấu trúc) - 7 mẫu, và Behavioural (hành vi) - 11 mẫu còn lại .

Tuy nhiên theo tớ thì không nên tiếp cận các DP the thứ tự tên ABC, hoặc theo từng category như trên, mà nên tiếp cận theo 1 trong 2 hướng: hoặc là dễ hiểu nhất, hoặc là dễ gặp nhất.
Ngoài ra không nên chạy theo các "xxx Design Patterns" khác (VD: Enterprise), vì đa số các pattern dạng này thuộc loại bùng nổ, hầu như cái gì cũng quơ vào làm pattern, hiệu quả thực tế chẳng bao nhiêu mà còn dễ dẫn đến "tẩu hỏa nhập ma" :D .


=== Creational DP ===


C. Singleton

Ensure a class only has one instance, and provide a global point of access to it.



C. Factory Method

Define an interface for creating an object, but let the subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.



C. Abstract Factory

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.



C. Prototype

Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.



C. Builder

Separate the construction of a complex object from its representation so that the same construction processes can create different representations.



=== Structural DP ===


S. Bridge

Decouple an abstraction from its implementation so that the two can vary independently.



S. Facade

Provide a unified interface to a set of interfaces in a system. Façade defines a higher-level interface that makes the subsystem easier to use.



S. Adapter

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatibility interfaces.



S. Decorator:

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.



S. Proxy

Provide a surrogate or placeholder for another object to control access to it.



S. Composite

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.



S. Flyweight

Use sharing to support large numbers of fine-grained objects efficiently. A flyweight is a shared object that can be used in multiple contexts simultaneously. The flyweight acts as an independent object in each context; it’s indistinguishable from an instance of the object that’s not shared.



=== Behavioural DP ===


B. Strategy:

Defines a family of algorithms, encapsulates each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients who use it.



B. Chain of Responsibility

Avoid coupling the sender of a request to its receiver by giving more then one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.



B. Template Method

Define a skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure.



B. Iterator

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.



B. Command

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.



S. Observer

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.



B. Mediator

Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and lets you vary their interaction independently.



B. State

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.



B. Interpreter

Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.



B. Memento

Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.



B. Visitor

Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.



( từ từ tớ sẽ giới thiệu cụ thể từng cái pattern sau... nếu có thời gian :D )

Friday, December 12, 2008

Javascript Libraries Overview

Từ khi những thuật ngữ như AJAX hay RIA xuất hiện, Javascript đã được phát triển mạnh và hình thành các thư viện, hay cũng có thể gọi là các framework để hỗ trợ ứng dụng web.
Hiểu biết về JavaScript đã trở thành 1 skill không thể thiếu với những ai làm lập trình web, và cũng là 1 skill khá quan trọng của các hacker. Tuy nhiên với web-development hiện nay thì lời khuyên là bạn nên nắm vững 1 thư viện nào đó, hơn là đi tìm kiếm các đoạn script mẫu ngắn phục vụ cho 1 mục đích nào đó.

Các thư viện JS mã mở và hữu ích hiện nay có thể kể: jQuery, mooTools, Prototype + Scriptaculous, YUI + ExtJS , Dojo, ...

(ngoài ra còn 1 số công nghệ JS có cả phần server side như : qooxdoo, echo2, GWT, DWR, jMaki, Qcodo, AjaxCFC, ... )



Dưới đây là 1 slideshow so sánh cơ bản các thư viện JS trên để bạn có thể chọn cho mình 1 cái phù hợp :



Have fun :D !

Monday, December 08, 2008

Learning with YouTube

Well, maybe you already know flash-video sites such as MetaCafe , YouTube , Google Video, ... but have you ever used them for learning ?

My favourite lectures come from MIT and Standford :
MIT
Standford

IMHO , this method is quite good if you have enough time.
Try it yourself and see :-)

Sunday, December 07, 2008

VIM vs Notepad++

Ngoài 1 số điểm mà notepad-plus plus kết hợp plugins đuổi kịp VIM, vẫn còn một số ưu điểm không thể không nhắc đến của vim :


1/ Mở file lớn. (bạn thử mở 1 file > 100 MB bằng vim với Notepad++ coi sao)


2/ Xử lý nhiều cụm từ trong 1 file lớn (VD: thay thế vài ngàn từ bằng vim và Notepad++)


3/ Hỗ trợ highlight nhiều hơn (syntax on hoặc syntax enable), hiện nay Notepad++ đã được tăng nhiều nhưng vẫn chưa bằng vim (thử mở các file text như .conf, .cnf, .lst , .cnt , .*rc , ... )


4/ Customize màu sắc dễ hơn, adapt không chỉ 1 ngôn ngữ lập trình (colorscheme, set background, set foreground, set guifont, tự chỉnh các file .vim , ... )


5/ Customized macro: recording các thao tác , chẳng hạn bạn đang viết blog đến từ "CSS", muốn link Wiki chỉ bấm 1, hoặc 2 phím đã recorded thành macro thì chữ CSS đó đã trở thành <a href="http://en.wikipedia.org/wiki/CSS">CSS</a> ,


6/ Customized hotkey: nếu macro không quá phức tạp mà lại hay dùng thì thường người ta ánh xạ hotkey, hầu như không có giới hạn nào cả. Chẳng hạn nếu muốn thì Ctrl+B có thể là cặp thẻ (cho HTML) , Ctrl+W rồi phím b là cặp thẻ [b] (cho forum BBcode) .


7/ Thao tác trên từng word, dòng, ..., di chuyển... bằng các phím cực nhanh. Chẳng hạn file có 1234 dòng, bạn muốn cut 543 dòng đầu tiên đem xuống cuối file rồi paste lại thì chỉ cần chuyển qua Normal mode rồi bấm (nhắm mắt luôn) :
gg543ddGp
hoặc gõ tương ứng các lệnh đó rồi Enter cũng được


8/ Viết script: vim có hỗ trợ cả các cú pháp if, else, func... Chẳng hạn có thể viết 1 function rồi map cho "Ctrl+/" : khi gặp file java, C, C++,... thì comment out cả đoạn bằng " // " , khi gặp file Perl, Shell,... thì comment out bằng " # " , gặp hợp ngữ thì comment bằng " ; " khi gặp file VIM thì comment out bằng " " " , ...


9/ Kích hoạt shell command: bằng dấu "!" ngay sau dấu ":" , chẳng hạn
:!ps
Một ví dụ tổng hợp: chẳng hạn dùng để map hotkey (kết hợp shellscript & perl) để mở Xterm tra dữ liệu từ điển Hồ Ngọc Đức trong vim console bằng phím F9 (gần giống kiểu click & see)


10/ "DIFF" 2 hoặc 3 file cùng lúc bằng lệnh
$ vimdiff copyBTL1.txt copyBTL2.txt
hoặc
$ vim -d copyBTL2.txt copyBTL1.txt copyBTL3.txt


... more to come (vimrc, multiple buffer, multiple session, multiple split, vimshell, external edit ... ), làm biếng nghĩ tiếp quá



have fun geeks !

Saturday, November 29, 2008

BIOS access keys

Most OEM PC or custom-built clone PC using third-party motherboard (MoBo) allows user to configure various settings in BIOS (CMOS setup) to enter BIOS Setup or Configuration Utility in order to enable or disable devices or ports available, and more commonly, boot device priority or sequence. Some advanced settings also allow user to tweak computer performance, such as CPU clock speed multiplier and CPU front side bus (FSB) rate for overclocking, chipset features, DRAM parity, speed and timing, etc.

To access BIOS configuration screen, user need to press and invoke a specific hotkey or keys combination during the initial BIOS load screen (usually right after the computer is powered on). Here’s a list of the ways and access keys to press to access BIOS Setup Utility on variety of popular OEM computer systems, motherboard makers and major BIOS brands. Note that some BIOS or computer systems may have more than one method of accessing BIOS depending on when the BIOS is released.


Acer (Aspire, Power, Veriton, Extensa, Ferrari, TravelMate, Altos): Press [F2] or [Del] Immediately After Power Up
Acer (Altos 600 Server): Press [Ctrl]+[Alt]+[Esc] or [F1] During Boot (for Advanced Options)
Acer (Older PC): Press [F1] or [Ctrl]+[Alt]+[Esc] to Access BIOS

AMI (American Megatrends AMIBIOS, AMI BIOS): Press [Delete] During Boot
AMI
AMI (American Megatrends AMIBIOS, AMI BIOS) - Old Version: Press [F1] or [F2] During Boot

Award BIOS (AwardBIOS): Press [Del] After Powering Up Computer
Award BIOS (AwardBIOS) - Old Version : Press [Ctrl]+[Alt]+[Esc] During Boot

ALR: Press [Ctrl]+[Alt]+[Esc] or [Ctrl]+[Alt]+[Del] During Boot

ARI: Press [Ctrl]+[Alt]+[Esc] or [Ctrl]+[Alt]+[Del] During Boot

AST Advantage: Press [Ctrl]+[Alt]+[Esc] During Boot

Compaq (Presario, Prolinea, Deskpro, Systempro, Portable): Press [F10] When Blinking Cursor Jumps To Top Right Corner of Screen
Compaq (Presario, Prolinea, Deskpro, Systempro, Portable): Press [F10] When Logo Screen Is Displayed
Compaq (Older Computers): Press [F1], [F2], [F10], or [Del] Key

Cybermax: Press [Esc] Key

Dell (XPS, Dimension, Inspiron, Latitude. OptiPlex, Precision, Vostro): Press F2 When Dell Logo Is Displayed Until “Entering Setup” Appears
Dell (Older 486 Models): Press [Ctrl]+[Alt]+[Enter] During Boot
Dell (Some Models): Press Reset Button Twice (i.e. Power Reset Button)
Dell Dimension L566cx System: Press [Del]
Dell (Older Laptop Models) : Press [Fn]+[Esc] or [Fn]+[F1]

DTK (Datatech Enterprises): Press [Esc] Key Right After Powering On the PC.

EISA Computer: Press the Reset button on the Front of the Computer, then Press [Ctrl]+[Alt]+[Esc] immediately when the memory count begins or Press [Crtl]+[Alt]+[S].

eMachines (eMonster, eTower, eOne, S-Series, T-Series): Press [Tab] or [Del] During Boot
eMachine (Some Older Computers): Press [F2]

Fujitsu (LifeBook, Esprimo, Amilo, Tablet, DeskPower): Press [F2] When Fujitsu Logo Is Appearing.

Gateway Using Phoenix BIOS (DX, FX, One, GM, GT, GX, Profile, Astro): Press [F1]
Gateway (Some Older PCs): Press [F2]

Hewlett-Parkard (HP Pavilion, TouchSmart, Vectra, OmniBook, Tablet): Press [F1] Upon Startup or Bootup
Hewlett-Parkard (HP Alternative): Press [F2] or [Esc]
Hewlett-Parkard (HP) Tablet PC: Press [F10] or [F12]

IBM ThinkPad using IBM BIOS (Early Models): Press [Ctrl]+[Alt]+[Ins] When Cursor Is At Upper-Right Corner of Screen
IBM ThinkPad using IBM BIOS (Later Models): Press and Hold [F1] When Powering Up Laptop
IBM ThinkPad using Phoenix BIOS: Press [Ctrl]+[Alt]+[F11] from DOS Prompt

IBM PS/1 (Late Models), PS/ValuePoint and 330s: Press [Ctrl]+[Alt]+[?]
IBM PS/2 with Reference Partition: Press [Insert] During Boot
IBM PS/2: Press [Ctrl]+[Ins] When Pointer Is At Top Right of Screen
IBM PS/2: Need Reference Disk and ADF Disk for Setup
IBM PS/2 75 and 90: Press [Ctrl]+[Alt]+[?]

IBM (PC, XT, AT): Press [F1] Immediately On Powering On the Computer
IBM (Older Computers or Notebooks): Press [F2]

Lenovo (ThinkPad, IdeaPad, 3000 Series, ThinkCentre, ThinkStation): Press [F1] or [F2] on Boot Up
Lenovo (Older Products): Press [Ctrl]+[Alt]+[F3], [Ctrl]+[Alt]+[Ins] or [Fn]+[F1].

Microid Research MR BIOS: Press [F1]

Micron (MPC Computers ClientPro, TransPort): Press [F1], [F2] or [Del] On Startup

NEC (PowerMate, Versa, W-Series): Press [F2] During Boot
NEC Versa Notebook: Press and Hold Down [F1] Upon Startup or Bootup

Olivetti PC Pro: Press [Ctrl]+[Alt]+[Shift]+[Del](in Num Pad) During Boot
Packard Bell (8900 Series, 9000 Series, Pulsar, Platinum, EasyNote, imedia, iextreme): Press [F1], [F2], or [Del].
Packard Bell (Early 386 and 486 Dodels): Press [Ctrl]+[Alt]+[S] Sequence

Phoenix BIOS (Phoenix-Award BIOS): Press [Del] During Power On Self-Test
Phoenix BIOS (Phoenix-Award BIOS) - Old Version: Press [Ctrl]+[Alt]+[S], [Ctrl]+[Alt]+[Esc], [Ctrl]+[Alt]+[Ins] or [Ctrl]+[S] During Power On Boot Self-Test Right After Startup

Sharp (Notebook Laptops, Actius UltraLite): Press [F2] On Computer Starts
Sharp (Old PCs): Require Setup Diagnostics Disk to Access BIOS

Shuttle (Glamor G-Series, D’vo, Prima P2-Series, Workstation, X Mini XPC, Surveillance): Press [F2] or [Del] on System Startup

Sony (VAIO, PCG-Series, VGN-Series): Press [F1], [F2] or [F3] After Turning On the Computer
Sony Vaio 320 Series: Press [F2] During Boot

Tandon 386: press [Ctrl]+[Shift]+[Esc]
Tandon: press [Ctrl]+[Shift]+[Esc]

Toshiba (Portégé, Satellite, Tecra): Press [Esc] During Boot
Toshiba (Portégé, Satellite, Tecra with Phoenix BIOS): Press [F1] during Boot

Zenith, Phoenix: Press [Ctrl]+[Alt]+[Ins] During Boot


Miscellaneous and Other Common BIOS Key Sequences

[Ctrl]+[Esc]
[Ctrl]+[Ins]
[Ctrl]+[Alt]
[Ctrl]+[Alt]+[+]
[Ctrl]+[Alt]+[F3]
[Ctrl]+[Alt]+[Del]
[Ctrl]+[Alt]+[S]
[Ctrl]+[Alt]+[Enter]
[Ctrl]+[Alt]+[Ins]
[Ctrl]+[Alt]+[Esc]
[Ctrl]+[Shift]+[Esc]
[Tab]
[F1]
[F3]
[F4]
[F10]
[F12]
[Fn]+[Function Key]


Note that for some older system with Phoenix BIOS, the following steps are required to get to BIOS setup screen:

  1. Exit or boot up to DOS.
  2. Press [Ctrl]+[Alt]+[Esc] to enter setup screen.
  3. If hot key sequence above doesn’t work due to changes or problems been made on the system, then try to use the key to lock the keyboard while leaving computer switched on.
  4. Press the Reset button on the front of the computer. A message will appear asking user to unlock the keyboard.
  5. Unlock the keyboard and press [F2] to run the CMOS setup.
  6. Press [Del] to bring up the CMOS setup program.




( From myDigitalLife )


BONUS: CMOS PASSWORD TOOL http://www.cgsecurity.org/wiki/CmosPwd

Hopefully this list might help some laptops :-) ,

Wednesday, November 26, 2008

J2EE with NetBeans

You can download the following simple demo presentation:
(the presenter's pronounciation is very clear, feel free to practice your listening skill :D ):

http://mediacast.sun.com/users/ArunGupta/media/v3prelude-nb65-webapp.flv

IMHO GlassFish is a fairly good Application Server, compared to JBoss, although the core servlet containers of both are derived from the same (Tomcat).

Tuesday, November 25, 2008

Technical forum structure

Nhân thấy các bạn bên forum của CLB tin học khoa CSE của trường ĐHBK HCM tranh luận về việc định hướng và tái cấu trúc forum, tớ thử nghĩ ra cấu trúc cho 1 forum định hướng kỹ thuật để thu hút được nhiều người giỏi tham gia.


Tuy nhiên chưa kịp post lên forum đó thì tớ đã bị "ban" nick vì "có quá nhiều sense of humour", đến nỗi vài anh bạn không-có-óc-hài-hước cảm thấy tủi thân.
(nghĩ kỹ thì nhờ bị "banned" mà tiết kiệm được mấy $ mỗi giờ, hehe )



Thôi thì cứ để các bạn ấy trưởng thành vậy, mình lo kiếm cơm qua ngày là đủ mệt rồi, gánh chi chuyện thiên hạ.

Monday, November 24, 2008

VIM for dummies [2]

Sau khi biết được cơ bản về VIM thì các bạn đã bắt đầu có thể dùng vim để soạn thảo (edit) rồi, nhưng để hiệu quả hơn thì cần biết thêm một số thiết lập, phím tắt và lệnh.

Bài này sẽ ôn lại một số điểm trong post trước và giới thiệu thêm một số thao tác thường gặp của vim . Hy vọng sau bài này thì các bạn yêu thích máy tính sẽ cảm thấy hứng thú với việc dùng vim trên Linux/BSD.



=== Khởi động vim ===

Ôn lại bài trước:
$ vim myfile.txt

Bài này thì ta khởi động cách khác:
$ vim

Khởi động kiểu này sẽ thấy hiện giữa màn hình các thông tin về tác giả (Bram Moolenaar - hiện đang làm cho Google), phiên bản (7.x.yz) , cách quit bằng :q , cách xem trợ giúp bằng :h , ...
Bây giờ để bắt đầu soạn thảo 1 file (giả sử tên myfile.txt) , ta gõ lệnh
:edit myfile.txt
hoặc đơn giản hơn chỉ cần :e myfile.txt .

Trong trường hợp bạn muốn mở nhiều file cùng lúc (ví dụ: file1.js , file2.cpp, file3.java, ...), thì vim cũng hỗ trợ nhiều cách. Nếu phiên bản vim của bạn hỗ trợ tab các file, thì nên mở bằng cách sau:
$ vim -p file1.js file2.cpp

Hoặc khi đang ở trong chế độ normal của vim, bạn dùng lệnh:
:tabedit file3.java
thì vim sẽ mở cho bạn file3.java trong 1 tab mới :) .
(Để ngắn gọn hơn có thể gõ :tabe file3.java )



=== Di chuyển / Cuộn màn hình ===

Ôn lại bài trước:
* trái và phải : là "h" và tương ứng "l"
* còn xuống , lên : là "j" , "k"


Di chuyển bằng các phím (ở normal mode):
+ Đến tab kế tiếp: gt , tab trước đó: gT
+ Đến file mà tên nằm ở dấu nháy: gf (để trở lại, dùng Ctrl+o hoặc Ctrl+6 )

+ Đến đầu file: gg
+ Đến (đầu) dòng cuối file: G (tức là Shift+g )
+ Đến dòng thứ 17: 17G

+ Đến cuối dòng: $
+ Đến đầu dòng (ký tự đầu): ^
+ Đến đầu dòng (cột 0): 0


Cuộn màn hình :
+ Cả trang : Ctrl+f (forward), Ctrl+b (backward)
+ Nửa trang : Ctrl+d (down), Ctrl+u (up)
+ Từng dòng : Ctrl+n (next), Ctrl+p (previous) . Hoặc phím cũ là Ctrl+e và Ctrl+y

Lưu ý: các tổ hợp phím scroll màn hình này cũng giống như khi dùng lệnh man, more hoặc less , nên khi xem manpage hay file nào các bạn cũng có thể scroll bằng các tổ hợp phím kể trên.



=== Tìm kiếm / Thay thế ===

Ôn lại bài trước:
phím / : tìm từ trên xuống
phím ?: tìm từ dưới lên (thường dùng để tìm cụm từ có chứa / )
Khi đã tìm thấy thì có thể bấm tiếp phím n hoặc N để tìm đến từ kế tiếp (next) .

Tìm ngay các từ giống từ đang ở dấu nháy (cursor) : phím * , hoặc #


Thay thế (substitute) thì dùng cú pháp mới gần giống sed: ( s/OLD/NEW/option )
+ thay toàn bộ chuỗi "OLD" bằng chuỗi "NEW" trong cả file:
:%s/OLD/NEW/g

+ thay toàn bộ chuỗi "OLD" bằng chuỗi "NEW" trong đoạn từ dòng 5 đến dòng 17 :
:5,17s/OLD/NEW/g

+ thay toàn bộ chuỗi "OLD" bằng chuỗi "NEW" trong 1 dòng (đang chứa cursor) :
:s/OLD/NEW/g

+ chỉ thay chuỗi "OLD" đầu tiên trong dòng bằng chuỗi "NEW" thì ko cần "g" :
:s/OLD/NEW

+ nếu muốn có xác nhận (confirm) trước khi thay thì ta thêm option là "c" :
:%s/OLD/NEW/gc


Các thao tác tìm kiếm và thay thế trên VIM cũng hỗ trợ biểu thức chính quy (Regular Expression) khá tốt. Các Regex được hỗ trợ trên vim hiện nay giống như của egrep, khá giống của perl . Nhưng để tránh phức tạp cho người mới dùng thì tớ chưa nêu ví dụ ở đây :D .



=== Sao chép / Xóa / Dán ===

Đơn giản:
- chép (copy/yank) : phím y
- xóa : phím d (hoặc phím x)
- dán : phím p

btw, trong VIM thì xóa (delete) luôn có nghĩa là cắt (cut), tức là mất đi trên màn hình hiển thị , nhưng ngay lúc đó đã lưu lại trong vùng nhớ nào đó (gọi là vùng register hoặc còn gọi là vùng buffer). Khi đó có thể dán (paste) lại màn hình soạn thảo của vim bằng phím p .


Để xóa 1 đoạn thì ta có thể làm các cánh sau:

1/ chuyển qua chế độ visual rồi chọn vùng cần xóa và bấm phím xóa

2/ dùng chức năng đánh dấu (mark) bằng phím m , đánh dấu 2 điểm rồi xóa từ điểm đầu đến điểm cuối

3/ chuyển sang chế độ chuột
set mouse=a
hoặc
set mouse=i
rồi dùng chuột để chọn vùng cần xóa, rồi bấm phím xóa.

4/ Ánh xạ các thao tác xóa thành tổ hợp phím nào đó (VD: kiểu Ctrl+C của Windows) , để chọn và xóa dễ hơn.

5/ Chuyển sang chế độ soạn thảo giống các chương trình trên Windows , tức là dùng lệnh behave mswin để nó chuyển chế độ chuột và các phím tắt giống kiểu Notepad++ trên Windows.

Đại khái như vậy, nhưng phần này tớ khoan nói rõ, ai quan tâm sẽ tự tìm hiểu :D .




=== Thiết lập / vimrc ===

Ôn lại bài trước:
* Chuyển theme màu khác cho vim, chẳng hạn theme "murphy" :
:colorscheme murphy

* Bật syntax highlight màu cho các ngôn ngữ lập trình, script :
:syntax on

* Bật số dòng (line number) lên cho dễ theo dõi:
:set number

* Bật chức năng hiện các lệnh (show command) đã gõ :
:set showcmd

* Bật "cây thước" để hiện số dòng, số cột, số ký tự đã gõ:
:set ruler

* Bật chức năng highlight các từ được search :
:set hlsearch

* Bật chức năng ignore case của từ được search để tìm được nhiều hơn :
:set ignorecase




=== Ánh xạ phím tắt ===

Ôn lại bài trước:
Để undo, thì trước tiên chuyển về normal mode (nhấn ESC) , rồi bấm phím u , thế là undo 1 lần. Muốn undo nữa thì nhấn u nữa, cứ thế. Còn để redo thì ở Normal mode ta bấm Ctrl+r (trong VIM thường ký hiệu là C-R) . Nếu muốn redo nữa thì lại bấm Ctrl+r tiếp, bạn có thể redo đến hết lần undo liên tục gần nhất.



=== Một số tham khảo ===

Ôn lại bài trước:
:h word
(với "word" là từ mà mình muốn coi help)

vim cũng có built-in sẵn 1 cái tutor về cách dùng VIM:
$ vimtutor

Sunday, November 23, 2008

Object-oriented programming principles

Sau khi đã biết được các nguyên lý cơ bản để phát triển phần mềm, một lập trình viên nên biết qua về các nguyên lý lập trình hướng đối tượng.

Một số bạn thì gọi cái này là các nguyên tắc thiết kế hướng đối tượng (OOD principles) . Theo tôi thì gọi như vậy là không chính xác. Các nguyên tắc OO này áp dụng cho lập trình (programming), từ thiết kế (design) đến viết mã (coding) đến kiểm thử (testing) , đều cần biết các nguyên tắc này và nên áp dụng ở từng giai đoạn luôn chứ không chỉ ở giai đoạn design.

Nói một cách ví von, so với cờ thì: các nguyên lý KISS, DRY, YAGNI,... là các thế tàn cuộc cơ bản, các nguyên lý OOP là các cách chơi trung cuộc, còn như Design Patterns thì là các kiểu khai cuộc . Mặc dù ngày nay Design Patterns được nhắc đến nhiều nhưng thực sự thì để nâng cao nội lực thì nên nắm vững OOP principles , còn DP thì ban đầu chỉ cần biết một ít đủ để áp dụng OOP là được.


Trong vài bài post sau này chúng ta sẽ thảo luận về Design Patterns , còn bây giờ tôi sẽ nêu 4 nguyên lý OOP cơ bản :

1/ Nguyên lý đóng mở - OCP : (open close principle)
Open for extension, but closed for modification.

Tạm dịch: Dễ mở rộng các hành vi, mà không cần phải sửa lại (class/interface/method)


2/ Nguyên lý thay thế Liskov - LSP : (Liskov substitute principle)
Derived classes must be substitutable for their base classes.

Tạm dịch: Các lớp dẫn xuất phải có khả năng thay thế hẳn lớp cơ sở


3/ Nguyên lý nghịch đảo phụ thuộc - DIP : (dependency inversion principle)
Depend on abstractions, not on concretions.

Tạm dịch: Nên phụ thuộc ở mức trừu tượng, tránh phụ thuộc cụ thể


4/ Nguyên lý phân tách giao diện - ISP : (interface segregation principle)
Make fine grained interfaces that are client specific.

Tạm dịch: Tạo các interfaces đã lọc kỹ và hướng tới người dùng


4 revisited/ Nguyên lý trách nhiệm đơn định - SRP: (single responsibility principle)
(Cái này là 1 góc nhìn khác của ISP, nếu bạn thích gọi là nguyên lý 5 thì cũng không sai mấy)
A class should have one, and only one, reason to change.

Tạm dịch: Khi thay đổi, mỗi lớp chỉ nên có 1 và chỉ 1 lý do



Ngoài ra còn các nguyên lý về phân gói (package), chia làm 2 nhóm:
+ tăng độ kết dính (increase cohesion) : REP, CCP, CRP
+ giảm độ ghép cặp (decrease coupling) : ADP, SDP, SAP

Tuy nhiên nên nắm vững 4 nguyên lý cơ bản ở trên trước khi tìm hiểu các nguyên lý về package & granuality .

Saturday, November 22, 2008

Double-clicked Java

Nice article from Dmitry Leskov:
http://javalobby.org/articles/java2exe/




"How do I make an .EXE file from my Java application?",

"Need help converting jar to exe",

"Is it possible to create a Windows executable using Java?"

--- these and similar questions are among the most popular topics on Java developer forums. Should you start such a topic today, you are likely to encounter the following three types of replies:

1/ "You cannot"
2/ "You should not, because that would kill the very purpose of Java"
3/ "You can do that with third party software X and Y"


The truth is that there exist two completely different approaches to the creation of native executables from Java applications, addressing different sets of problems. Moreover, under certain conditions some of those problems may be solved without making an EXE. So the most correct way to reply to such a post would be a request for more information, namely what is the goal of conversion to EXE. And the most frequent answer would be



=== Simplify Java Application Deployment ===

Java compiles to platform-independent bytecode (.class files), which is not directly supported by PC hardware. So a Java program needs a Java Runtime Environment (JRE) to run, which would either interpret the bytecode instructions or compile them to native code on the fly. This in turn means that the author of that program has to ensure somehow that the proper version of the JRE is installed on an end user system.


In a general case you may not expect that your end users will know what a JRE is, how to check its version, and how to download and install it. This is especially true for consumer applications, such as games or multimedia. And those who already have a JRE installed may not like the idea about installing a different version, because it may break their existing Java applications and favorite applets.


Then, even if you can make sure the right version of the JRE is properly installed on enduser systems, which is quite possible in a classroom or enterprise environment, the command line required to launch your Java application can be quite long:

java -Xmx200m -cp whatever.jar -Dsome.property MyApp

Yes, you may put that line into a batch file and call it runme.bat, but it looks so much easier to give your program to a friend, teacher or colleague as a single file that can be run by a double-click. Or, even better, enable it to be installed and uninstalled in a native manner without affecting other applications.


So it comes as no surprise that the primary motivation for seeking a way to convert a Java application into an EXE file is to make its deployment and use simpler and safer for an average user, that is, a Windows user. What surprises newbie Java developers is that the JDK does not offer such functionality. Before J2SE 1.4, all you could make with JDK tools were



=== Executable Jars ===

You can make your Java application runnable via a double-click by packaging it into a so called executable jar. You do that by specifying the main class of your application, any extra jar files it may require and so on in the jar's manifest file

Main-Class: MyAppMain
Class-Path: mylib.jar

Then you use the jar utility from the Java SDK to package your classes and resource files, specifying the m option and the name of your manifest file:

jar cvfm MyApp.jar MyApp.mf *.class *.gif

This will result in the creation of MyApp.jar. Now, if you type

java -jar MyApp.jar

the Java launcher will read the manifest from MyApp.jar and invoke the main method from the class MyAppMain. Moreover, if you double-click that jar file on a system that has JRE installed, the java launcher will be invoked automatically.


Note: As of J2SE 5.0, jar files are associated with the javaw launcher on Windows, which does not open a console on startup. If your application needs a console, write a batch file which would start it using the java launcher.


If your application consists of more than one jar file, there is an open source tool called One-JAR that claims to correctly repackage multiple jars into one.


The major problem with executable jars is compatibility. The default JRE may be of an older version than is required by your application or may not have the necessary Java Optional Packages (previously known as Standard Extensions) installed. For instance, if your app uses the java.nio package introduced in Java 2 version 1.4, it will not work on JRE 1.3.x. Similarly, if it uses JavaMail 1.3, and the default JRE has JavaMail 1.2 or JavaMail is not present at all, the double-clicked jar will not run.


Fortunately, Sun has created a Java application deployment technology that eliminates this compatibility problem and adds some nice features. It is part of the Java 2 platform since version 1.4 and is called



=== Java Web Start ===

Java Web Start (JWS) and the underlying Java Network Launch Protocol (JNLP) enable Java application delivery from a standard Web server. The end user initiates application installation by clicking on an URL. If the Java Web Start engine is not present on the system, the user is prompted to download and install it. Once Java Web Start is in place, clicking on the same URL will initiate the application download and installation procedures. It may involve download and installation of the required version of the JRE and Optional Packages. Upon their successful completion, the application is launched. The application will be cached on the user's system so next time the user clicks on the same URL, the JWS engine will launch the local copy of the application from the cache, if it detects that the computer is offline or the application was not updated on the Web site.


Another important feature of JWS is its ability to run your application in a sandbox - a restricted container based on Java security architecture. But, unlike an applet, your application can gain access to local system resources like the filesystem, printer and system clipboard using the JNLP API even if it comes from an untrusted environment, after prompting the user for confirmation.


Java Web Start is available for Windows, Linux, and Solaris, and is part of MacOS X since v10.1. There are also third-party implementations of the JNLP protocol, some of them also include tools that assist you in the creation and maintenance of JNLP packages.


That was the bright side. Now, what is not so good about JNLP? First off, for seamless operation both the browser and the Web server that hosts the JNLP-enabled application must support application/x-java-jnlp-file MIME type. Some hosting providers do not support it. Moreover, versioning and incremental updates require additional support from the Web server, which has to be implemented using servlets, cgi-bin scripts, etc.


On the client side, a major browser would be configured to recognize the above MIME type during installation of the JWS engine, but users of less popular browsers, such as Opera, may have to do that manually.


JNLP-enabling an application may involve minor changes in its code and (re)packaging it into a set of jar files.


Before J2SE 5.0, JWS had very little to offer in terms of desktop integration - all it could do was create a desktop icon and/or a Start Menu entry for the application. On Windows, the application will not show up in Add/Remove Programs, so end users would have to run the Java Web Start application manager in order to remove your application.


Finally, JWS user interface needs much polishing. As of J2SE 5.0, users still complain about ugly windows with incomprehensible messages.


To sum it up, JWS can be a viable option in a controlled environment, such as corporate intranet, but it is not ready for the consumer market, where you may be better off using



=== Custom Java Launchers And Wrappers ===

When a Java program is invoked using one of the methods discussed above (batch file, executable jar, or Java Web Start/JNLP), the operating system runs a Java launcher from the JRE. The Windows version of the JRE has separate launchers for command-line and GUI apps, called java.exe and javaw.exe respectively.


As a result, all running Java applications have the same Taskbar/Alt-Tab icons and appear in the Windows Task Manager as either java.exe or javaw.exe. If you have two or more Java apps running, you have no means to distinguish between multiple instances of the standard Java launcher in the Task Manager.


In fact, those launchers are just small native programs that load the Java Virtual Machine from a DLL/shared library and then feed your program to that JVM using the Invocation API. That API is part of the Java Native Interface (JNI), so it is standardized, and it is also very simple. This makes it relatively easy to write your own launcher with a unique name and icon. What it has to do is find a suitable JRE on the end user's system (unless you bundle the JRE with your application), load and initialize the JVM, and run your application on it.


If you do not have the right tools, skills, or time to develop a custom launcher for your Java application, there are quite a few third-party Java launcher generators listed in the Tools section of the frame. Some of them provide additional features such as instant splash screen, stdout and stderr redirection, and so on, the most notable being wrapping.


A Java wrapper is essentially a custom Java launcher that is also a self-extracting archive containing all the application's classes, jars and auxiliary files. The wrapper unpacks those files on startup and removes on termination. This way, your application is distributed as a single executable.


A wrapper normally looks up the JRE upon startup. If the JRE is not present or its version does not match the application's compatibility requirements, some wrappers may install the JRE (if you have included it when wrapping your application) and/or download and install the required version of the JRE.


The most sophisticated wrappers may also setup file associations and create shortcuts on first run. But if you need something more complex, such as support for automatic updates or uniform cross-platform deployment, have a look at



=== Java-Aware Setup Authoring Tools ===

If all you need is install a private copy of the JRE alongside your application and create shortcuts that run your application on that JRE, you may use any setup generator. However, using a Java-aware tool may give you the following benefits:

* Install-time JRE detection and download
* Generation of native launchers
* User-editable JVM parameter files
* Redirection of stderr and stdout for saving logs and exception stack traces.
* Registration of Java applications as Windows services and Unix daemons

This category is the most diversified in terms of tool pricing and functionality. The differences are explained below by example.


Windows-centric tools, such as Advanced Installer for Java enable you to build MSI (Windows Installer) packages.


Multi-platform tools can generate native installers for multiple platforms - Windows, Linux, Mac OS X, as well as RPMs and tarballs. install4j is one such tool.


There exist also Java-based setup authoring tools enabling you to create cross-platform installations, Those installations are essentially executable jars with platform-specific logic selected at run time. InstallAnywhere is perhaps the most well known tool of this type, but if its pricing is beyond your budget, consider the cheaper JExpress or the open source IzPack.


Finally, there is One Tool to Rule Them All - InstallShield, which can create both Windows desktop (MSI) and cross-platform installations, plus server and mobile ones, for any type of application and for a multitude of platforms. And yes, it does support JRE lookup and bundling, native launchers, and so on.


For straightforward installations, however, InstallShield is an overkill. Also note that InstallAnywhere and InstallShield are aimed at the enterprise developer and are priced accordingly.


All the above solutions do not change the fundamental principle mentioned in the first section of this article. Whether you make an executable jar or create a sophisticated installer, your Java program is still deployed as platform-independent bytecode. In the early days of Java, the only way to execute a Java program on a common PC hardware was to interpret that bytecode. Today, any decent J2SE implementation contains a Just-In-Time (JIT) compiler that compiles frequently executed methods to native code. So it sounds quite natural to take one step further and compile the entire application down to native code before it is deployed. Such tools exist and they are called



=== Ahead-Of-Time Compilers ===

AOT compilers are known also as "static compilers" and "native code compilers". The latter term is the most used and, as it often happens, the least correct from the technical standpoint, because JIT compilers also produce native code.

An Ahead-Of-Time (AOT) compiler takes as input your jars and class files and produces a conventional native executable for the target platform, such as Windows EXE or Linux ELF binary. Just like any other technical solution, this has its advantages and drawbacks.


Advantages

* Performance. A JIT compiler works at application's runtime and shares CPU and memory resources with the application it compiles and possibly other applications. An AOT compiler runs on the developer's system with no resource or compilation time constraints. Therefore it can potentially use more powerful resource-intensive optimizations, yielding better code.

This advantage is amplified if you application will be deployed to embedded systems or low-end desktop PCs, where the JIT compilers simply may not have enough resources to work.

* Intellectual Property Protection. Java bytecode is very easy to decompile - just google for "download java decompiler" and you will get your source code back in 5 minutes. Yes, you may obfuscate names of public classes and methods not accessed via reflection, but control flow obfuscation can render your bytecode unverifiable on future JVMs and hinders optimizations implemented in JIT compilers. Finally, encrypting your Java bytecode does not protect it at all regardless of the encryption algorithm you use.

In contrast, native code produced by an optimizing AOT Java compiler is about as hard to reverse engineer as if you have coded the original program in C++. Needless to say, there is no performance loss. If you are concerned about protecting your intellectual property, have a closer look at native compilation.

* User Perception. Java client applications often suffer from the so called warm-up cycle syndrome. Starting up a Java application involves bytecode interpretation, profiling and JIT-compilation. So Java programs tend to start much longer than their native counterparts and the initial response time of a Java app GUI element is much worse than after it has been used several times, which are the two major reasons for Java still being perceived as slow by many users.

A native executable runs directly on hardware, without the interpret-profile-compile overhead, so it may start faster and immediately demonstrates the best response times.

* Native deployment. Even the most sophisticated Java-aware setup tools have to generate native launchers for better desktop integration, and may need to take care of the JRE download and installation.

Executables produced by an AOT Java compiler do not depend on the JRE and can be deployed using any setup authoring tool available for the target platform. Moreover, AOT compilers may come with specifically tailored setup generators that create compact, professional installers.


Drawbacks

* Dynamic applications. Classes that the application loads dynamically at runtime may be unavailable to the application developer. These can be third-party plug-ins, dynamic proxies and other classes generated at runtime and so on. So the runtime system has to include a Java bytecode interpreter and/or a JIT compiler.

Moreover, in the general case only classes that are loaded by either system or application classloader may be precompiled to native code. So applications that use custom classloaders extensively may only be partially precompiled.

* Hardware-specific optimizations. A JIT compiler has a potential advantage over AOT compilers in that it can select code generation patterns according to the actual hardware on which the application is executing. For instance, it may use Intel MMX/SSE/SSE2 extensions to speedup floating point calculations. An AOT compiler must either produce code for the lowest common denominator or apply versioning to the most CPU-intensive methods, which may result in code size increase.


FYI, there used to be half a dozen AOT Java compilers on the market in the year 2000, but the only two that have survived are Excelsior JET and GCJ (GNU Compiler for Java).



./.


To discuss about this article, please go to JavaLobby forum :-)

Thursday, November 20, 2008

Scrum software development

Việc phát triển phần mềm ngày nay càng lúc càng lưu ý hơn đến việc sử dụng lại (re-use) và đáp ứng (adapt) với thay đổi của yêu cầu khách hàng, bởi kinh nghiệm cho thấy đó là điều tất yếu không thể tránh khỏi.
Vì thế các quy trình phát triển phần mềm cổ điển như WaterFall, Spiral, RUP, ... càng lúc càng ít được dùng, mà thay vào đó là các phương pháp có tính reusable và flexible cao. Các quy trình tập trung vào 2 tính năng trên được gọi là quy trình linh hoạt (Agile process) .

WaterFall fails


Trong họ Agile software development process thì đến nay đã được khoảng năm bảy loại, nhưng nổi bật nhất là Extreme Programming (XP) và Scrum .

Agile Basis



Tuy nhiên đến bây giờ thì Scrum xem như đã vượt qua XP và FDD để trở thành mô hình Agile được công nhận rộng rãi nhất. Bởi Scrum vừa tập hợp các best practices từ các mô hình khác (daily meeting, test automation, iterations,... ), vừa khai thác triệt để các giá trị Agile (team interaction, run first, customer collaboration, embrace change) .


Các thuật ngữ và khái niệm trong quy trình Scrum mới nghe thì hơi khó hiểu hơn bên XP, chẳng hạn chia Roles thành PigChicken , rồi nào là Sprint, nào là BackLog, rồi BurnDownChart, etc... liệu có vi phạm KISS ? (trong Agile thường dùng thuật ngữ "Assume Simplicity" hơn là K.I.S.S)


Lúc đầu tôi cũng nghĩ là chia như vậy hơi rắc rối, làm sao mà lại tốt hơn quy trình XP được. Nhưng sau quá trình chấp nhận làm quen thuật ngữ và áp dụng triệt để Scrum tôi đã cảm thấy nó nhỉnh hơn XP (có lẽ nhờ kinh nghiệm XP đã làm trước đây chăng? ) . Dẫu sao đi nữa thì nó cũng là một quy trình đáng giá và sẽ rất tốt nếu áp dụng cho 1 team gồm những lập trình viên có kinh nghiệm.


Hẹn lại trong 1 bài khác tôi sẽ trình bày rõ hơn các khái niệm trong quy trình Scrum và vì sao nó lại được đánh giá cao trong giới Agile. Nếu có thời gian thì giới thiệu sơ luôn các quy trình Agile khác như: AUP, DSDM, FDD, Getting Real, ...

Tuesday, November 18, 2008

Some eponymous laws

which relates to software development or project management :D .



Brooks’ Law

Adding manpower to a late software project makes it later.



Parkinson’s Law

Work expands so as to fill the time available for its completion.



Hoare’s Law of Large Programs

Inside every large problem is a small problem struggling to get out.



Lister’s Law

People under time pressure don’t think faster.



Pareto Principle

For many phenomena, 80% of consequences stem from 20% of the causes.



The Peter Principle

In a hierarchy, every employee tends to rise to his level of incompetence.



Conway’s Law

Any piece of software reflects the organizational structure that produced it.



Fitts’ Law

The time to acquire a target is a function of the distance to and the size of the target.



Tesler’s Law of Conservation as Complexity

You cannot reduce the complexity of a given task beyond a certain point. Once you’ve reached that point, you can only shift the burden around.



Occam’s Razor

The explanation requiring the fewest assumptions is most likely to be correct.



Hofstadter’s Law

A task always takes longer than you expect, even when you take into account Hofstadter’s Law.



Ninety-ninety Law

The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.



Hartree’s Law

Whatever the state of a project, the time a project-leader will estimate for completion is constant.



Jakob’s Law of the Internet User Experience

Users spend most of their time on other sites. This means that users prefer your site to work the same way as all the other sites they already know.



Fisher’s Fundamental Theorem

The more highly adapted an organism becomes, the less adaptable it is to any new change.



Clarke’s Second Law

The only way of discovering the limits of the possible is to venture a little way past them into the impossible.




Have fun !

Sunday, November 16, 2008

Computer hackers exposed !

Alan Cox là lập trình viên máy tính và là người đóng góp chính vào sự phát triển của nhân Linux từ thuở sơ khai 1991.




John Gilmore là một trong những người sáng lập ra Electronic Frontier Foundation, Cypherpunks và Cygnus Solutions. Ông tạo ra thuyết phân cấp alt.* trong Usenet và là người đóng góp chính của dự án GNU.



Jon “maddog” Hall là Giám đốc điều hành của Linux International, một tổ chức phi quyền lợi lập nên từ những nhà cung cấp máy tính muốn hỗ trợ và đẩy mạnh hệ điều hành Linux.



Grace Murray Hopper là một nhà khoa học máy tính Mỹ và sĩ quan Hải quân Mỹ. Bà là một trong những lập trình viên kì cựu của Harvard Mark I, và phát triển trình biên dịch đầu tiên cho một ngôn ngữ lập trình. Do những thành tích đó mà người ta còn gọi bà là “Amazing Grace”.



David Korn, sáng lập ra Korn Shell, thường mặc áo thun in hình ban nhạc Korn. (Cool)!



Eric Steven Raymond là một lập trình viên, nhà văn và luật sư nổi tiếng trong cộng đồng mã nguồn mở. Ông nổi tiếng với câu nói: “Câu văn luộm thuộm thì tư duy cũng luộm thuộm”.



Richard Matthew Stallman là một nhà phát triển phần mềm kiêm hacker. Năm 1983, ông khởi xướng dự án GNU tạo nên Hệ điều hành Unix. Ông còn là người phát triển trình soạn thảo Emacs gốc, GNU Compiler Collection (GCC), và GNU Debugger.



Bjarne Stroustrup là một nhà khoa học máy tính Đan Mạch. Ông đã thiết kế và phát triển ngôn ngữ lập trình C++ vào năm 1983.



Linus Benedict Torvalds - cha đẻ của chim cánh cụt Linux khi còn là 1 SV trường ĐH Helsinki (Phần Lan).



Larry Wall là lập trình viên, nhà ngôn ngữ học và nhà văn. Ông tạo ra ngôn ngữ nổi tiếng Perl. Các hacker ngày nay cần phải cám ơn ông rất nhiều.



Stephan Gary “Woz” Wozniak - đồng sáng lập Apple cùng Steve Jobs.



Dennis MacAlistair RitchieKenneth Lane Thompson - cha đẻ Unix. Ken Thompson tạo ra ngôn ngữ B còn Dennis Ritchie tạo ra ngôn ngữ C.



Bill GatesPaul Allen - miễn bình luận!



Loyd Blankenship, biệt danh: The Mentor (người cố vấn) được biết đến như 1 hacker khét tiếng và là nhà văn từ những năm 1980, khi ông còn là thành viên của các tổ chức hacker Extasyy Elite và Legion of Doom.



Riley Eller, biệt danh: Caezar, là thành viên của Ghetto Hackers.



Dan Farmer là 1 chuyên viên an minh máy tính. Sau khi tốt nghiệp ĐH Purdue, ông bắt đầu phát triển chương trình COPS, chương trình này giải thích tại sao Unix bảo mật đến như vậy. Năm 1995, ông và Wietse Venema sáng lập ra SATAN (Security Administrator Tool for Analyzing Networks). Nhìn ông này trông giống tay vocal của Kreator.



Susan Lynn Headley, biệt danh: Thunder, là 1 trong số ít ỏi các nữ hacker, cô là thành viên của Roscoe Gang.



Richard Pryce - khi mới 16 tuổi, cậu sinh viên âm nhạc này đã nổi danh như cồn vì thành tích phá vỡ hệ thống hàng trăm máy tính của Griffiths Air Force Base, NASA và Korean Atomic Research Institute.



Bruce Schneier là một chuyên gia an minh mạng, 1 nhà mật mã học. Ông là tác giả 1 vài cuốn sách viết về bảo mật và mật mã. Ông phát minh ra các thuật toán Blowfish và Twofish.






Kết luận :
Hackers là những người... tóc dài hoặc rậm râu ! (hoặc cả 2)



Con đường thành nerd/geek vẫn còn xa quá !!