Các câu hỏi phỏng vấn cho lập trình viên Java (Phần 3)

java-interview-questions
Q: Static variable là gì?
Static variables là các biến ở class level, tất cả các đối tượng của class sẽ tham chiếu tới đó. Nếu một đối tượng thay đổi giá trị thì sẽ thay đổi trong tất cả các objects khác

Q: Có thể khai báo static variable trong một method không?
Static varaibles là các biến ở mức class level variables nên không thể khai báo trong method. Nếu khai báo thì lớp đó sẽ không được biên dịch

Q: Một method trong Interface có thể được khai báo là final không?
Khai báo này sẽ gây ra một lỗi biên dịch. Public và abstract sẽ được dùng để khai báo cho method trong một interface.

Q: Một Interface có thể extend Interface khác không?
Một Interface có thể được kế thừa từ Interface khác, Interface có thể extend nhiều hơn một Interface.

Q: Một Class có thể extend nhiều hơn một Class không?
Một lass cso thể extend duy nhất một class nhưng có thể implement số lượng Interface tuỳ ý.

Q: Một class có thể được định nghĩa trong Interface không?
Có. Một Interface cũng có thể được định nghĩa trong 1 class

Q: Externalizable là gì?
Externalizable là một Interface extends Serializable Interface. Nó gửi dữ liệu vào Streams dưới dạng Compressed Format, và có 2 method là writeExternal(ObjectOuput out) và readExternal(ObjectInput in)

Q: Class nào extended bởi tất cả các classes?
Object class được extended bởi tất cả các classes

Q: Nếu biến được khai báo private, nó có thể truy xuất từ đâu?
Một private variable có thể được truy xuất trong class mà nó được khai báo

Q: Một method được khai báo protected, nó có thể truy xuất từ đâu?
Một protected method có thể được truy xuất từ các classes hoặc interfaces trong cùng package hoặc subclasses của class mà nó được khai báo

Q: Sự khác biệt giữa public và non-public class?
Public class có thể truy xuất từ ngoài package. Non-public class không thể truy cập từ ngoài package của nó.

Advertisements

Các câu hỏi phỏng vấn cho lập trình viên Java (Phần 2)

java-interview-questions

Q:  Main() method có bắt buộc phải được sử dụng trong tất cả các java class không?
Không bắt buộc. Main() method nên được định nghĩa trong các lớp là java application.

Q: Main() method sẽ trả về kiểu dữ liệu nào?
Main() method được định nghĩa là void, và không trả về kiểu dữ liệu nào

Q: Đối số của main() method là loại nào?
Main() method nhận các đối số dạng mảng (array) của String object

Q: Package là gì?
Package là tập hợp các classes và interfaces có liên quan tới nhau. Package được khai báo ngay trên dòng đầu tiên trong mỗi java class.

Q: Package nào được mặc đinh import?
Package java.lang được mặc định import mà không cần khai báo.

Q: Nếu một class được khai báo là private trong package thì sao?
Class đó sẽ không thể truy cập từ bên ngoài package.

Q: Protected method có thể được truy cập từ đâu?
Có thể truy cập protected method bởi những classes trong cùng package hoặc từ subclasses của class đó ở tất cả các package.

Q: Mục đích của việc khai báo biến (variable) là final?
Final variable có giá tri không thể thay đổi. Final variables cần được khởi tạo trước khi sử dụng.

Q: Điều gì xảy ra khi khai báo method là final?
Method là final không thể ghi đè (overridden). Một sub-class không thể có method signature giống với implementation khác.

Q: Nếu không một class bị kế thừa (inherited) từ các class khác thì nên làm gì?
Nên khai báo class đó là final. Nhưng không thể định nghĩa một class là final,nếu nó là abstract class.

Q: Ví dụ về final classes trong Java API?
VD như java.lang.String, java.lang.Math.

Các câu hỏi phỏng vấn cho lập trình viên Java (Phần 1)

java-interview-questionsQ: Tính năng quan trọng nhất của Java là gì?
Java là một ngôn ngữ lập trình hướng đối tượng với nền tảng độc lập, có thể code java trên một môi trường (ví dụ Windows) nhưng thực thi trên một môi trường khác (ví dụ Solaris).

Q: Sự khác biệt của JDK và JRE là gì?
JDK là Java Development Kit với mục đích phục vụ cho việc phát triển ứng dụng, bao gồm cả môi trường thực thi.
JRE chỉ là môi trường runtime, không thể phiên dịch được mã nguồn trên đó.

Q: Lớp cơ sở của Java là gì?
java.lang.Object

Q: Java có hỗ trợ đa kế thừa (multiple inheritance) không?
Java không hỗ trợ multiple inheritance

Q: Path và Classpath khác nhau như thế nào?
Path là biến môi trường của hệ điều hành (operating system level environment variales). Path chỉ ra vị trí của executables files (file .exe)
Classpath chỉ ra chỗ của các .class file.

Q: Local variables là gì?
Local varaiables là biến cục bộ được khai báo trong block code như là methods. Local variables nên được khởi tạo trước khi truy cập tới chúng

Q: Instance variables là gì?
Instance variables được khai báo trong các lớp (class level). Instance variables không cần được khởi ạo trước khi sử dụng, chúng sẽ tự khởi tạo với giá trị mặc định.

Tạo ứng dụng đơn giản với Node.js và MongoDB

Bài viết hướng dẫn bạn có thể tạo một ứng dụng đơn giản với NodeJS và MongoDB. Application này chỉ kết nối và insert một vài dữ liệu vào MongoDB.
nodes
1. Tạo thư mục
# mkdir testapp
# cd testapp/

2. Tạo file package.json
# npm init

3. Lấy dependent module
# npm install mongodb –save

4. Kiểm tra kết quả
# cd node_modules/
# ls -ln
total 4
drwxr-xr-x 4 0 0 145 Jul 18 13:11 bson
drwxr-xr-x 2 0 0 77 Jul 18 13:11 buffer-shims
drwxr-xr-x 3 0 0 103 Jul 18 13:11 core-util-is
drwxr-xr-x 4 0 0 101 Jul 18 13:11 es6-promise
drwxr-xr-x 2 0 0 104 Jul 18 13:11 inherits
drwxr-xr-x 2 0 0 149 Jul 18 13:11 isarray
drwxr-xr-x 3 0 0 262 Jul 18 13:11 mongodb
drwxr-xr-x 3 0 0 251 Jul 18 13:11 mongodb-core
drwxr-xr-x 2 0 0 111 Jul 18 13:11 process-nextick-args
drwxr-xr-x 4 0 0 4096 Jul 18 13:11 readable-stream
drwxr-xr-x 3 0 0 141 Jul 18 13:11 require_optional
drwxr-xr-x 2 0 0 74 Jul 18 13:11 resolve-from
drwxr-xr-x 2 0 0 108 Jul 18 13:11 safe-buffer
drwxr-xr-x 3 0 0 103 Jul 18 13:11 semver
drwxr-xr-x 3 0 0 87 Jul 18 13:11 string_decoder
drwxr-xr-x 2 0 0 109 Jul 18 13:11 util-deprecate

5. Tạo application code

# cd /testapp
#vi app.js
var MongoClient = require('mongodb').MongoClient;

var dbhost = 'mongodb://localhost:27017/test',
myCollection = 'chapter';

var seedData = function(db, callback) {
db.collection(myCollection).find({}, {}, {})
.toArray(
function(err, docs) {
if (docs.length <= 0) {
console.log('No data. Seeding...');

var ihandler = function(err, recs) {
if (err) {
console.log(err);
throw err;
}
inserted++;
}

var toinsert = 2,
inserted = 0;

db.collection(myCollection).insert({
'Title': 'Snow Crash',
'Author': 'Neal Stephenson'
}, ihandler);
db.collection(myCollection).insert({
'Title': 'Neuromancer',
'Author': 'William Gibson'
}, ihandler);

var sync = setInterval(function() {
if (inserted === toinsert) {
clearInterval(sync);
callback(db);
}
}, 50);
return;
}
callback(db);
return;
}
);
}

var showDocs = function(db) {
console.log("Listing books:");
var options = {
sort: [
['Title', 1]
]
};
db.collection(myCollection).find({}, {}, options)
.toArray(
function(err, docs) {
if (err) throw err;

for (var d = 0; d < docs.length; d++) {
console.log(docs[d].Title + '; ' + docs[d].Author);
}

db.close();
}
);
}

MongoClient.connect(dbhost, function(err, db) {
if (err) throw err;

seedData(db, showDocs);
});

6. Kiểm tra lại kết nối đến DB trước khi thực thi code
# mongod

7. Thực thi code:
# node app.js
No data. Seeding...
Listing books:
Neuromancer; William Gibson
Snow Crash; Neal Stephenson

8. Kiểm tra dữ liệu trong mongodb:
# mongo
> use test
switched to db test
> show collections
Chapter
> db.chapter.find().pretty()
{
"_id" : ObjectId("596dae70660a5011998896aa"),
"Title" : "Snow Crash",
"Author" : "Neal Stephenson"
}
{
"_id" : ObjectId("596dae70660a5011998896ab"),
"Title" : "Neuromancer",
"Author" : "William Gibson"
}

Hướng dẫn Java Design Pattern – Null Object

Có một số trường hợp khi hệ thống phải sử dụng một vài chức năng và một vài trường hợp nó không sử dụng. Giả sử bạn phải thực hiện một class mà nó phải ghi log vào môt file hoặc console. Nhưng điều này chỉ là một tính năng bổ sung và các dữ liệu được ghi phụ thuộc vào cách cấu hình ghi log của bạn.

Nếu có những trường hợp khi một vài module không cần phải ghi lại log thì bạn phải thực hiện việc kiểm tra xem những module này có cần phải thực hiện log hay không trong một khối IF để kiểm tra trong file cấu hình. Như vậy, việc triển khai này không phải là một giải pháp hay. Và Null Object Design Pattern ra đời từ đây.

Null Object Design Pattern là gì?

Nó cung cấp một null object để thay thế cho trường hợp một instance bị NULL. Thay vì sử dụng một lệnh IF để check một null value, Null Object sẽ phản ánh một mối liên hệ không phải thực hiện – không làm gì cả.

Triển khai Null Object Design Pattern

Những class tham gia vào pattern này bao gồm:

AbstractClass – định nghĩa một behavior cho một cách thức triển khai cụ thể đối với từng null object.
RealClass – một class được thực hiện theo cách thông thường. Hay là class thực, có dữ liệu.
NullClass – một class thực hiện theo cách mà object không tồn tại.
Client – đơn thuần chỉ là một class sử dụng (2) và (3)

Kết luận

Khi các khối lệnh IF vô nghĩa có tồn tại trong ứng dụng thì bạn nên nghĩ tới việc sử dụng Null Object Design Pattern. Nó là giải pháp hay giúp cho source code của bạn đơn giản, tinh tế hơn rất nhiều với việc check null theo cách truyền thống.

Hướng dẫn Java Design Pattern – Prototype

Pattern Prototype là gì?

Ngày nay, development quan trọng nhất là chi phí. Tiết kiệm là một vấn đề lớn khi nhắc đến việc sử dụng tài nguyên máy tính, do đó, các lập trình viên đang cố gắng hết sức để tìm ra giải pháp cải thiện hiệu năng của phần mềm. Trong lập trình oop, khi nhắc đến việc khởi tạo object, bạn có thể tìm thấy một cách tốt hơn để tạo ra một object đó là cloning. Ý tưởng này là một design pattern đặc biệt có liên quan đến việc khởi tạo object, thay vì tạo ra object, prototype pattern sử dụng cloning. Nếu việc tạo ra object lớn và tốn nhiều tài nguyên, bạn hãy nên sử dụng prototype pattern này.

Prototype pattern nó cho phép một object tạo ra những customized object mà không cần biết class của nó và bất kỳ chi tiết gì làm thế nào để tạo ra chúng. Ở thời điểm hiện tại, sẽ có rất nhiều người đang confuse khái niệm này với Factory Pattern, những giữa chúng thì hoàn toàn khác nhau. Sự khác nhau này, tôi sẽ trình bày vào một bài viết khác, ở đây tôi chỉ tập trung cho prototype pattern.

Giải pháp

Quy định cụ thể những loại object muốn tạo ra bằng cách sử dụng một prototypical instance tạo ra các object mới bằng cách sao chép chính nó.

Triển khai

Prototype pattern sẽ sử dụng những abstract class, class diagram dưới đây chỉ có 3 loại và làm cho việc thực hiện rất dễ dàng.

Prototype Design Pattern

Những class tham gia vào prototype pattern bao gồm :

Client class – Tạo mới object bằng cách gọi Prototype thực hiện clone chính nó.
Prototype – Khai báo một interface cho việc clone chính nó.
Concrete Prototype – Triển khai những operation cho việc clone chính nó.

Quá trình clone bắt đầu với việc initialized và instantiated class. Client class yêu cầu một object mới của loại đó và gửi yêu cầu tới class Prototype. Một ConcretePrototype, phụ thuộc vào loại object mà Client cần, sẽ đảm nhận việc clone object Client thông qua method clone(). Khi đó, một object mới thuộc loại Client sẽ được tạo ra.

Kết luận

Bạn nên sử dụng prototype pattern khi phát triển một hệ thống cần hạn chế sw ràng buộc với chính những products của nó được tạo ra. Vì nó chỉ tạo ra object vào thời điểm chương trình được chạy. Ngoài ra, nó còn làm giảm tối thiểu việc tạo ra những instance quá dài dòng theo cách mà ngôn ngữ lập trình cung cấp – từ khóa new.

Hướng dẫn Java Design Pattern – Wrapper

Wrapper Pattern là gì?

Wrapper Pattern là một trường hợp đặc biệt của Adapter Pattern. Nếu một Adapter chỉ đơn thuần là “nhúng” (wrap) các lớp với các giao diện không tương thích với nhau để chúng có thể hoạt động cùng nhau thì có thể được gọi bằng tên riêng Wrapper Pattern. Khi đó lớp Adapter còn được gọi là lớp Wrapper. Đây là quan hệ “có một”, tức là một giao diện không tương thích có thể được nhúng vào thành một phần của một giao diện khác.

Đặc điểm

Đối tượng Wrapper mô phỏng tất cả các hành vi (hàm, thủ tục) của giao diện được nhúng bởi các hành vi với tên y hệt. Thí dụ nếu lớp được nhúng A có thủ tục SpecificRequest() thì lớp Wrapper cũng phải có thủ tục SpecificRequest() tham chiếu đến thủ tục cùng tên của A. (Ngoài ra đối tượng Wrapper có thể được bổ sung các phương thức khác nếu cần thiết). Đặc điểm này được đưa ra dựa trên nguyên tắc thiết kế “Law of Demeter” nói rằng không nên tham chiếu một đối tượng sâu hơn một lớp.

Các phương thức trong Adapter được “nhúng” trong Wrapper bằng cách truyền lời gọi cùng với các tham số tới phương thức tương ứng trong Adapter, và trả về kết quả giống như vậy. Các thành viên (thuộc tính, trường, sự kiện) được nhúng trong Wrapper có tính chất giống hệt như trong các lớp được nhúng (tên, kiểu dữ liệu, phạm vi truy cập…).

Từ các đặc điểm ở trên, có thể thấy rằng Wrapper Pattern cho phép một module chương trình tương tác được trong một môi trường khác biệt với môi trường phát triển của module đó (ví dụ C++ và Java).

Khác biệt giữa Wrapper Pattern và Adapter Pattern

Sự khác biệt giữa Wrapper và Adapter nằm ở mục đích sử dụng: Adapter Pattern định hướng cho một đối tượng đang tồn tại có thể làm việc được với các đối tượng khác và biến đổi logic theo một cách thức nào đó, trong khi Wrapper Pattern chỉ đơn thuần cung cấp một giao diện kết hợp các đối tượng được xây dựng từ cùng một ngôn ngữ hoặc khác ngôn ngữ, trên cùng một hệ điều hành hoặc trên những hệ điều hành khác nhau.