Hiển thị các bài đăng có nhãn Tips and Trick. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn Tips and Trick. Hiển thị tất cả bài đăng

29 tháng 4, 2017

Hạn chế sai lầm tỉ đô khi sử dụng ngôn ngữ Java

Trong ngành điện toán, khái niệm con trỏ rỗng chỉ một biến con trỏ có một giá trị định sẵn khiến cho nó không trỏ được tới bất kì một đối tượng chính tắc nào. Charles Antony Richard Hoare tác giả của ngôn ngữ Algol W từng nói rằng việc phát minh ra tham chiếu rỗng là một sai lầm tỉ đô của ông. Vậy tại sao ông lại gọi đó là sai lầm tỉ đô? Trong ngôn ngữ Java, tham chiếu đến một đối tượng rỗng sẽ sinh ra ngoại lệ NullPointerException, đây là một unchecked exception. Việc xác định exception này có xảy ra hay không, chỉ có thể thực hiện được ở thời điểm runtime và compiler trong quá trình biên dịch không thể giúp lập trình viên xác định được chuyện đó. Chính điều này dẫn đến việc cho dù sản phẩm của bạn đã vượt qua được cơ số các bài test của đội QA tại môi trường test, nhưng đến một thời điểm nào đó sau khi đã lên production thì hệ thống đột ngột lại ngừng hoạt động do phát sinh lỗi, hệ thống sụp đổ dẫn đến thiệt hại có thể lên đến cả tỉ đô la. Dưới đây là một số biện pháp có thể áp dụng để hạn chế điều tồi tệ trên có thể xảy ra trong quá trình phát triển phần mềm khi sử dụng ngôn ngữ Java:

1, Gọi phương thức equals()equalsIgnoreCase() trên các đối tượng String đã biết sẽ tốt hơn là gọi trên các Object chưa xác định


Hãy nhớ luôn gọi phương thức equals() trên một đối tượng String không null đã biết. Vì phương thức equals() là phương thức đối xứng, nên khi gọi a.equals(b) sẽ tương tự như khi gọi b.equals(a), và đây là lí do mà nhiều lập trình viên không chú ý đến hai đối tượng a và b. Hệ quả của việc gọi phương thức bất cẩn như thế có thể dẫn đến việc chương trình ném ra NullPointerException nếu như đối tượng gọi phương thức equals()null.

Object unknownObject = null;

// Cách thực hiện sai - có thể gây ra NullPointerException
if(unknownObject.equals("knownObject")) {
    System.err.println("This may result in NullPointerException if unknownObject is null");
}

// Cách thực hiện đúng - tránh được NullPointerException thậm chí nếu unknownObject là một đối tượng null
if("knownObject".equals(unknownObject)) {
    System.err.println("better coding avoided NullPointerException");
}

Đây là một trong các cách thực hiện dễ dàng nhất khi sử dụng ngôn ngữ Java để tránh được NullPointerException, nhưng kết quả mà nó mang lại được cải thiện vô cùng lớn vì phương thức equals() là một trong những phương thức được sử dụng phổ biến nhất.

2, Nên sử dụng valueOf() thay vì toString() khi cả hai phương thức trả về cùng một giá trị như nhau


Vì khi gọi phương thức toString() trên một đối tượng null, thì nó sẽ ném ra NullPointerException. Nếu sử dụng phương thức valueOf() mà cũng có thể trả về giá trị giống với khi sử dụng phương thức toString() thì ta nên sử dụng valueOf(), vì gọi phương thức valueOf() trên một đối tượng null nó sẽ trả về chuỗi "null", chứ không ném ra NullPointerException, đặc biệt là trong trường hợp các lớp Wrapper như Integer, Float, Double hoặc BigDecimal.

BigDecimal bd = getPrice();

/* Không ném ra NullPointerException */
System.out.println(String.valueOf(bd));

/* Ném ra "Exception trong "main" thread java.lang.NullPointerExxception" */
System.out.println(bd.toString());

Sử dụng cách này nếu bạn không chắc chắn một đối tượng là null hay không null.

3, Nên sử dụng các phương thức và thư viện null safe


Trong cộng đồng mã nguồn mở có rất nhiều thư viện có thể giúp bạn dễ dàng hơn trong việc kiểm tra null. Phổ biến nhất trong số này là lớp StringUtils từ thư viện Apache commons. Bạn có thể sử dụng StringUtils.íBlank(), isNumeric(), isWhitSpace() và các phương thức hữu ích khác mà không phải lo lắng về NullPointerException.

// Các phương thức trong lớp StringUtils là null safe, chúng không ném ra NullPointerExcetion
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));

Output:
true
true
false
false

4, Không nên viết một phương thức trả về tập hợp là null, thay vào đó hãy trả về một empty collection hoặc empty array


Bằng việc trả về một empty collection hoặc empty array, bạn có thể chắc chắn đươc rằng khi gọi các phương thức cơ bản như size() hoặc length() chương trình sẽ xảy ra lỗi vì NullPointerException. Lớp Collections trong Java cung cấp tập hợp các đối tượng List, Set, Map rỗng thuận tiện sử dụng trong các trường hợp phù hợp, ví dụ như: Collections.EMPTY_LIST, Collections.EMPTY_SETCollections.EMPTY_MAP

Ví dụ:

@Service
public class EmployeeService {

    private EmployeeDao employeeDao;

    public List<Contact> getContacts(Employee employee) {
        List<Contact> contacts;
        try {
            contacts = this.employeeDao.getContacts(employee); 
        } catch (Exception e) {
            contacts = Collections.EMPTY_LIST;
        }
        return contacts;
    }

    @Autowired
    public void setEmployeeDao(EmployeeDao employeeDao) {
        Assert.notNull(employeeDao, "EmployeeDao must not be null!");
        this.employeeDao = employeeDao;
    }
}

Tương tự, bạn có thể sử dụng Collections.EMPTY_SETCollections.EMPTY_MAP thay vì trả về null.

5, Hãy sử dụng annotation @NotNull@Nullable


Trong khi viết code, ta có thể đánh dấu một đoạn code có khả năng gây ra null bằng cách sử dụng annotation @NotNull@Nullable, hai annotation này sẽ đánh dấu liệu một phương thức có phải là null safe hay không. Nhiều trình biên dịch, IDE hoặc tool hiện nay đều có thể đọc được hai annotation này và nó sẽ gợi ý cho bạn khi có thiếu sót trong việc kiểm tra null, hoặc những công cụ này cũng có thể sẽ thông báo cho bạn nếu như việc kiểm tra null tại một đoạn code nào đó là không cần thiết. IntelliJ IDE và plugin findbugs là một trong những công cụ có hỗ trợ tính năng này. Hai annotation này là một phần trong JSR 305, nhưng ngay cả khi không có công cụ hoặc IDE nào hỗ trợ thì việc đánh dấu code bằng các annotaiton này thì điều này cũng giống như một tài liệu cho source code, giúp cho các lập trình viên khi nhìn vào có thể đưa ra quyết định có kiểm tra null hay không.

6, Tránh sử dụng autoboxing và unboxing không cần thiết trong code


Mặc dù cách thực hiện này gây ra những bất lợi khác như là tạo ra object tạm thời, nhưng vì nếu lớp Wrappernull thì autoboxing rất dễ gây ra NullPointerException. Ví dụ, khi thực hiện đoạn code sau sẽ bị lỗi và ném ra NullPointerException nếu đối tượng Person không có phone number và chương trình sẽ trả về null nếu bạn cố gắng thực hiện phương thức getPhone().

Person person = new Person("Psyduck");
int phone = person.getPhone();

Không chỉ khi so sánh tương đương mà khi sử dụng các toán tử <, > cũng có thể gây ra NullPointerException nếu như được sử dụng cùng với autoboxingunboxing.

7, Theo sát Contract đã thiết kế và xác định các giá trị mặc định hợp lí


Trong Java, một cách đơn giản khác để tránh được NullPointerException đó là định nghĩa ra Contract và thực hiện theo đúng như thiết kế. Nhiều trường hợp dẫn đến NullPointerException đó là do Object được tạo ra có dữ liệu hoặc các dependency bắt buộc chưa được cung cấp đầy đủ. Nếu bạn định nghĩa ra các Contract không cho phép tạo đối tượng bị thiếu thông tin như vậy thì bạn sẽ có thể ngăn chặn sớm được việc chương trình bị lỗi do NullPointerException. Bạn cũng nên định nghĩa ra các giá trị mặc định hợp lí khi viết code, ví dụ như một đối tượng Employee không thể được tạo nếu thiếu các thuộc tính id, name, nhưng số điện thoại là tùy chọn. Nếu Employee không có số điện thoại thì thay vì trả về null, ta sẽ trả về giá trị mặc định, ví dụ như trả về 0, nhưng lựa chọn này cần phải được thực hiện một cách cẩn trọng vì trong một số trường hợp thì việc kiểm tra null sẽ dễ dàng hơn là gọi một số không hợp lệ.

8, Tạo ràng buộc trong database


Nếu bạn đang sử dụng cơ sở dữ liệu cho việc lưu trữ các domain object giống như Customers, Orders, Contacts, ... thì hãy nên định nghĩa ra các ràng buộc xác định rõ một trường dữ liệu có khả năng được nhận giá trị null hay không. Vì cơ sở dữ liệu có thể thu được dữ liệu từ nhiều nguồn khác nhau, vậy nên sử dụng các ràng buộc để kiểm tra dữ liệu đầu vào trước khi insert hay update sẽ đảm bảo được sự toàn vẹn của dữ liệu. Việc cung cấp các ràng buộc kiểm tra giá trị null cũng giảm số lần phải kiểm tra null khi thực hiện viết code Java. Khi thực hiện lấy dữ liệu về từ cơ sở dữ liệu để truyền vào các object, bạn đã nắm rõ được thuộc tính nào của object có thể là null, và thuộc tính nào sẽ không bao giờ có thể nhận giá trị null nên điều này sẽ giảm số lần kiểm tra != null không cần thiết trong code của bạn tới mức tối thiểu.

9, Sử dụng Null Object Pattern


Trong Java thì đây cũng là một cách để đảm bảo chương trình của bạn sẽ không ném ra NullPointerException.

Hạn chế sai lầm tỉ đô khi sử dụng ngôn ngữ Java


(by @dangquando)

13 tháng 9, 2016

Tạo Trigger tự động ghi lại thời gian sửa đổi lần cuối của dữ liệu trong PostgreSQL

1. Tạo Trigger Function

Tạo Trigger Function trên column có tên last_updated:

CREATE OR REPLACE FUNCTION public.update_timestam()
  RETURNS trigger AS
$BODY$
BEGIN
    NEW.last_updated = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql;

2. Tạo Trigger

Tạo Trigger cho bảng tbl_books.

CREATE TRIGGER trigger_upd_timestamp_last_updated_tbl_books
  BEFORE UPDATE
  ON public.tbl_books
  FOR EACH ROW
  EXECUTE PROCEDURE public.update_timestamp();

Note: bảng tbl_books phải có column last_updated.

Thay đổi màu sắc highlight Logcat trong Android Studio

Với màu sắc highlight Locat mặc định trong theme Dracula thì rất khó để nhận ra từng loại log.

Darcula theme Logcat highlighting

Ta có thể sửa lại màu sắc highlight Logcat theo theme Android Holo để dễ dàng nhận biết từng loại log khác nhau.

Holo theme Logcat highlighting

Để làm được điều này ta thực hiện như sau:

  • Trên thanh công cụ menu chọn File|Settings
  • Tiếp theo trong phần Settings, chọn Editor|Colors & Fonts|Android Logcat
  • Click vào Save As… button và tạo color schema mới
  • Thay đổi tất cả màu sắc theo ‘Holo theme colors’ (Bỏ lựa chọn ‘Use inherited attributes’ đối với từng loại màu)
Assert:  #AA66CC
Debug:   #33B5E5
Error:   #FF4444
Info:    #99CC00
Verbose: #FFFFFF
Warning: #FFBB33
Holo theme colors

2 tháng 4, 2016

Enable Icons Menus Trong Hệ Điều Hành Linux

Mặc định trong UbuntuFedora icon menu bị tắt đi. Dưới đây là cách bật icon menu trong hệ điều hành Linux:
Để bật chế độ menuicon, cần thực hiện lệnh sau:
#!/bin/bash
~$ gsettings set org.gnome.desktop.interface menus-have-icons true

hoặc:

~$ gsettings set org.gnome.settings-daemon.plugins.xsettings overrides "{'Gtk/ButtonImages': <1>, 'Gtk/MenuImages': <1>}"

Tạo desktop launcher cho Eclipse trong hệ điều hành Linux

1. Tạo file eclipse.desktop

Sử dụng một editor bất kì để tạo file trong thư mục /usr/share/applications.

Ví dụ sử dụng gedit:

$ sudo gedit /usr/share/applications/eclipse.desktop

2. Thêm nội dung sau vào file vừa tạo và lưu lại.

[Desktop Entry]
Encoding=UTF-8
Name=Eclipse
Comment=Eclipse Mars 4.5.1
Exec=/path/to/your/eclipse_folder/eclipse
Icon=/path/to/your/eclipse_folder/icon.xpm
Terminal=false
Type=Application
Categories=GNOME;Application;Development;
StartupNotify=true