$ git update-ref -d HEAD
15 tháng 1, 2019
15 tháng 10, 2018
Git delete branch by pattern
$ git branch --list 'pattern*' | sed 's/^* //' | xargs -r git branch -D
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()
và 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()
là 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.
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
.
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_SET
và Collections.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_SET
và Collections.EMPTY_MAP
thay vì trả về null
.
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
và @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.
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 Wrapper
là null
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 autoboxing
và unboxing
.
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ệ.
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.
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
.
(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
.

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.

Để làm được điều này ta thực hiện như sau:
- Trên thanh công cụ
menu
chọnFile|Settings
- Tiếp theo trong phần
Settings
, chọnEditor|Colors & Fonts|Android Logcat
- Click vào
Save As…
button và tạocolor 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

2 tháng 4, 2016
Enable Icons Menus Trong Hệ Điều Hành Linux
Để bật chế độ menu có icon, 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