Những nguyên tắc cơ bản nhất trong Java

1/ Khi constructor() có quá nhiều parameters thì nên dùng Builder. (vì quá đơn giản nên ko cần ví dụ link tham khảo)

2/ Nên dùng try-with-resources hơn là try-finally

Không nên:
static String firstLineOfFile(String path) throws IOException {
   BufferedReader br = new BufferedReader(new FileReader(path));
   try {
      return br.readLine();
   } finally {
      br.close();
   }
}

Nên:
static String firstLineOfFile(String path) throws IOException {
   try (BufferedReader br = new BufferedReader(new FileReader(path))) {
      return br.readLine();
   }
}
Không Nên:
static void copy(String src, String dst) throws IOException {
   InputStream in = new FileInputStream(src);
   try {
      OutputStream out = new FileOutputStream(dst);
      try {
         byte[] buf = new byte[BUFFER_SIZE];
         int n;
         while ((n = in.read(buf)) = 0)
            out.write(buf, 0, n);
      } finally {
         out.close();
      }
   } finally {
      in.close();
   }
 }

Nên:

static void copy(String src, String dst) throws IOException {
   try (InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst)) {
      byte[] buf = new byte[BUFFER_SIZE];
      int n;
      while ((n = in.read(buf)) = 0)
         out.write(buf, 0, n);
   }
}

3/ Nếu có override equals() thì phải luôn luôn override hashCode() : mình thường hay dùng Eclipse generate code cho hashCode method, review lại cần thì edit lại một ít.

4/ Luôn luôn override toString() cho bean hay POJO, vì mỗi khi ghi log hay debug dễ dàng hơn, vẫn. dùng Eclipse generate.

5/ Làm thế nào để tạo immutable class: thường hay thấy mọi người chém gió với nhau là StringBuilder vs StringBuffer, StringBuilder vs String, hay là tạo immutable class thế nào. Immutable class là 1 class sau khi dc khởi tạo thì giá trị của class không thay đổi nên những gì làm thay đổi giá trị của class thì nên bỏ như setter chẳng hạn.

1. remove Setter method.
2. final class: không cho class dc extend
3. final private fields, thì phải có constructor full parameters để khởi tạo.
4. Chắc chắc những Getter method không phải thay đổi giá trị, lưu ý những fields kiểu Date hay kiểu Object thì nên clone trước để bảo đảm giá trị không bị reference.

public final class FinalClassExample {
   private final int id;
   private final String name;
   private final Date birthDate;
   private final Map<String, String> testMap;

   public FinalClassExample(int id, String name, Date birthDate, Map<String, String> testMap) {    // (3)
      this.id = id;
      this.name = name;

      birthDate = birthDate.clone();   // (4)
      //
      Map<String, String> tempMap = new HashMap<>();
      String key;
      Iterator<String> it = testMap.keySet().iterator();
      while (it.hasNext()) {
         key = it.next();
         tempMap.put(key, testMap.get(key));
      }
      this.testMap=tempMap;
   }

   public int getId() {
      return id;
   }

   public String getName() {
      return name;
   }

   public Date getBirthDate() {
      return birthDate.clone();
   }

   public Map<String, String> getTestMap() {
      // need to clone like code in constructor.
   }

}

6/ Interface vs Abstract, Composition vs Inheritance, has-a vs is-a. Là những khái niệm cơ bản. Mình thì mình thích Interface, Composition hơn gì độ uyển chuyển.

7/ Constant thì nên dùng class, không dùng interface

Không Nên:
public interface PhysicalConstants {
   // Avogadro's number (1/mol)
   static final double AVOGADROS_NUMBER = 6.022_140_857e23;

   // Boltzmann constant (J/K)
   static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23; 

   // Mass of the electron (kg)
   static final double ELECTRON_MASS = 9.109_383_56e-31;
}

Nên:
public class PhysicalConstants {
   private PhysicalConstants();      // không cho khởi tạo.

   // Avogadro's number (1/mol)
   static final double AVOGADROS_NUMBER = 6.022_140_857e23;

   // Boltzmann constant (J/K)
   static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23; 

   // Mass of the electron (kg)
   static final double ELECTRON_MASS = 9.109_383_56e-31;
}

8/ if….return thì không cần else nữa, minh review code projects nào cũng gặp kiểu viết như vậy, thật là không nên. Nếu if else nhiều quá thì xem xem có thể chuyển sang switch case dc ko.

9/ Dùng enums thay thế cho int constants. Có rất nhiều lợi ích.

Không nên:

   // The int enum pattern - severely deficient!
   public static final int APPLE_FUJI         = 0;
   public static final int APPLE_PIPPIN       = 1;
   public static final int APPLE_GRANNY_SMITH = 2;

   public static final int ORANGE_NAVEL  = 0;
   public static final int ORANGE_TEMPLE = 1;
   public static final int ORANGE_BLOOD  = 2;

Nên:
 public enum Apple { FUJI, PIPPIN, GRANNY_SMITH }
 public enum Orange { NAVEL, TEMPLE, BLOOD } 

Lợi ích:
1/ Đối tượng hoá và có thể dùng switch ...case.
2/ An toàn về kiểu và giá trị, giống như constants không thể gõ nhầm dc.
3/ Dùng Enum.valueOf để validate dễ dàng

10/ Collection nên dùng interface và diamond operator <>, code review projects nào cũng gặp.

Không nên:
ArrayList&lt;String&gt; item = new ArrayList&lt;String&gt;();

Nên:

List&lt;String&gt; item = new ArrayList&lt;&gt;();

11/ Nếu project đang dùng java 8 thì nên dùng lambdas.

Không nên
// Anonymous class instance as a function object - lỗi thời rồi!
   Collections.sort(words, new Comparator&lt;String&gt;() {
      public int compare(String s1, String s2) {
          return Integer.compare(s1.length(), s2.length());
      }
});

Nên:
// Lambda expression as function object (replaces anonymous class)
Collections.sort(words,
                  (s1, s2) -> Integer.compare(s1.length(), s2.length()));  

Có thể viết theo một cách khác
Collections.sort(words, comparingInt(String::length));

Hoặc
words.sort(comparingInt(String::length));

12/ Nên dùng method references lambdas, nếu dùng method references để viết mà code chổ đó đọc khó hiểu quá thì nên dùng kiểu lambdas thường. Quan trọng là viết code cho người đọc và dễ maintain.
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
https://www.codementor.io/eh3rrera/using-java-8-method-reference-du10866vx

13/ Nên viết Unit Test.

14/ DRY (Don’t repeat yourself) Principle: chổ nào thấy codes lặp lại 2 lần thì nên viết method để dùng chung.

15/ Dùng varargs cẩn thận.

Không nên:    

static int min(int... args) {
   if (args.length == 0) {
      throw new IllegalArgumentException("Too few arguments");
   }
   int min = args[0];
   for (int i = 1; i <= args.length; i++) {
      if (args[i] > min) {
         min = args[i];
      }
   }
   return min;
}
Sẽ bị lỗi khi không truyền parameters nào.

Nên: 

static int min(int firstArg, int... remainingArgs) {
   int min = firstArg;
   for (int arg : remainingArgs) {
      if (arg &amp;lt; min) {
         min = arg;
      }
   }
   return min;
}
Cho nên mới cần Unit Test.

16/ Nên return empty collections or arrays, không nên return null. Nhớ dùng Collections.emptyList() vì nó là Singleton.

Không Nên:&amp;lt;/span&amp;gt;
public List<Cheese> getCheeses() {
   final List<Cheese> cheeseInStock = .....;
   return cheesesInStock.isEmpty() ? null : new ArrayList<>(cheesesInStock);
} 

Nên:
public List<Cheese> getCheeses() {
final List<Cheese> cheeseInStock = .....;
return cheesesInStock.isEmpty() ? Collections.emptyList() :
                                    new ArrayList<>(cheesesInStock);
}

17/ Cộng chuỗi String số lần > 3 thì nên cân nhắc có nên dùng StringBuilder hay StringBuffer nhé. Nếu đang dùng Thread cần thread-safe thì dùng StringBuffer, còn ko thì dùng StringBuilder. Còn lấy mấy lý do nguỵ biện như làm biếng viết hay giờ mấy cấu hình server khủng rồi, nhanh chậm vài miliseconds giây thì cũng ko ảnh hưởng thì miễn bàn hen. Ở đây đang nói về học thuật và nguyên tắc.

18/ https://stackify.com/best-practices-exceptions-java/

19/ Nên viết java doc, document những exposed API nhất là những micro services thì bắt buôc phải có, nếu dc thì document luôn soupui hay export postman.

20/ Keep methods small and focused: nếu 1 method có quá nhiều code thì nên extract method đó ra thành nhiều method nhỏ.

21/ Nên sử dụng thư viện hơn là tự viết. 2017 là năm của functional programming rồi.

22/ Tuyệt đối tránh dùng float, double để tính toán tỉ giá, thành tiền hay tiền tệ. hay trong thiết kế database cũng vây, phải dùng BigDecimal, int, long.

System.out.println(1.03 - 0.42);

Output:   0.6100000000000001

23/ Có bao nhiều loại Exception, hơ hỏi bắt ngờ quá cũng hem nhớ nữa. Hỏi cách khác rõ hơn đi. Có bao nhiêu loại Throwables in Java. Câu trả lời là 2 loại:

Checked Exception: (FileNotFoundException)
Unchecked Exception: (NullPointerException, … )
Error: thrown bởi JVM (OutOfMemoryError)
Runtime Exception.
https://www.w3resource.com/java-tutorial/types-of-exception.php

24/ Serialization: là gì và khi nào dùng, mình cũng hem biết. Bạn nào biết thì comment bên dưới chỉ mình nhé.

Thanks.

Advertisements

Xuất phát thấp

Hôm nay tôi chia sẻ chủ đề rất nhiều người quan tâm: Nếu hiện tại, bạn trẻ, bạn đang bước vào đời với xuất phát thấp, thì phải làm sao?

Trước hết, thế nào là thấp?
– Là bạn sinh ra trong một gia đình nghèo, thiếu điều kiện
– Là bạn sinh ra với một ngoại hình xấu xí, bị chê bai
– Là bạn vốn không được thông minh lanh lợi, học hoài ko giỏi được
– Là từ nhỏ tới lớn cứ liên tục gặp bất hạnh
– Là bạn thiếu thốn tình cảm, bị cô độc
….

Cái thấp này là bởi bạn so sánh với những người khác trong xã hội nom ai cũng khá giả hơn, đẹp hơn, giỏi hơn, thông minh hơn và may mắn hơn mình. Bạn dễ cảm thấy mình bất hạnh, sinh nhầm ngôi sao xấu, đời bất công và đâm ra bạn sẽ dễ nhụt chí.

Thực ra, hãy nhớ kĩ điều này. Tỉ lệ phần trăm những người vào đời với xuất phát cao, như sinh ra trong nhung lụa, con ông này bà kia, xinh đẹp thông minh vốn sẵn tính trời, liên tục gặp vận hên, được ai cũng yêu mến…thật ra rất hiếm. Chuyện cổ tích thôi. Số ấy không đại trà. Đừng so sánh rồi tủi thân hay đố kị, phí thời gian.

Thực tế cuộc sống chúng ta đa phần là những người xuất phát bình thường, hoặc thấp, như ta cả. Mỗi người có cảnh ngộ riêng, bất ổn riêng, họ ko nói ra mà thôi.

Đó chắc chắn ko phải là những người than thở và đầu hàng số phận. Không phải là những người há miệng chờ sung. Ko phải những người trông chờ may mắn. Những người yếm thế lười biếng “cái số thế rồi”. Ko phải những người chụp giựt, dối gạt, đi đường tắt.

Người muốn thay đổi cái xuất phát thấp, phải bắt đầu từ việc CHẤP NHẬN những gì cuộc đời đưa đến. Và NỖ LỰC không ngừng để CẢI THIỆN và TIẾN BỘ.

Đây là lời khuyên từ kinh nghiệm của chính tôi:

  1. Hãy luôn nhớ: học, học, và học. Học ở trường, học ở ngoài đời, học trên internet. Học những gì mình chưa biết. Nhất là học từ sai lầm và thất bại, học về sự ngộ nhận và tự làm mình tổn thương. Hãy nhớ mình đi lên từ số 0, thì chỉ cần tiến một chút là mừng, ko cần phải nhảy vọt.
  2. Hãy dành thời gian đọc nhiều những sách về tâm linh, tâm lí, triết học, quy luật cuộc sống, ứng xử, giao tiếp, để hiểu những lẽ cơ bản của cuộc đời, sẽ tiết kiệm được thời gian thay vì phải vấp ngã hoài mới khôn lên.
  3. Hãy giao tiếp với những người giỏi hơn, hiểu đời hơn, tích cực hơn, để được lan truyền năng lượng từ họ.
  4. Làm tốt nhất công việc hiện tại mình đang làm, tập trung hết khả năng, ko xao nhãng, ko ngó nghiêng, ko so sánh, hơn thua. Việc mình mình làm. Quan sát những người giỏi và tìm ra pattern (khung mẫu) cho riêng mình.
  5. Luôn chớp lấy khi có cơ hội và nỗ lực 200% với nó, dù cho kết quả ra sao. Xuất phát thấp nên cơ hội sẽ ko nhiều, hãy luôn trân trọng.
  6. Sống vun vén, tiết kiệm, trong thu nhập của mình, không vung tay quá trán, ko đợi nước tới chân mới nhảy. Nên nhớ, ta xuất phát thấp, ko ai chống đỡ, té, chỉ có ta tự đứng lên.
  7. Luôn có 1 cuốn sổ nhỏ ghi ra những yếu kém của bản thân và tích cực sửa chữa mỗi ngày. Ghi cả những điều nho nhỏ mình đã làm được để tự động viên bản thân.
  8. Dành thời gian cho gia đình, người thân, bạn bè, coi đó là điểm tựa tinh thần. Ko cần nhiều, chất quý hơn lượng.
  9. Đừng sa đà việc tô vẽ bề ngoài. Hãy chú trọng cái bên trong. Ta biết ta có gì là đủ. Ko để nhận xét và cách nhìn của người khác chi phối.
  10. Học cách sống một mình, đừng lệ thuộc vào bất kì ai. Đối diện các vấn đề và chịu trách nhiệm, ko đổ thừa.
  11. Luôn giữ sức khoẻ thể chất, niềm lạc quan trong tinh thần, cho dù cuộc sống thăng trầm ra sao.
  12. Sau cùng, nếu mình đã làm hết sức, mà cuộc đời mình vẫn chỉ ở mức trung bình, thì chấp nhận và vui vẻ. Ta ko cưỡng lại được số phận. (nên xem xét xem mình đã thật sự nghiêm túc và làm hết sức chưa). Vì chỉ cần mình tiến bộ mỗi ngày và đạt dc mục đích đề ra là đã thành công rồi.

Tôi đã từ xuất phát thấp đi lên, đi qua những tháng ngày vất vả và chặng đường chưa bao giờ dừng lại. Tôi vẫn tiếp tục học ngày ngày và càng hạnh phúc hơn khi hiểu ra được quy luật căn bản của cuộc sống hoá ra đơn giản vậy thôi: Phần ta cứ cố gắng hết sức, còn lại tạo hoá tự biết an bài.

Hãy cố lên nhé, những người đồng cảnh ngộ

st

 

Some tips work with Java restful.

Nowadays most people are acquired with microservices restful. Here are some websites very useful.

  • https://codebeautify.org/jsonviewer : json formatter
  • https://www.base64decode.org/ : Decode from Base64 format
  • https://www.freeformatter.com/json-escape.html : Convert string to String in Java and otherwise.
  • What http client in java do you prefer to use ?
    • Java core: of course HttpClient (Apache) but the project on which I’m working is Spring MVC, thus I prefer to use RestTemplate.
  • What a library do you use to parse son ?
    • I’m using GSON because my project is a micro services that deals with lots of small JSON requests, then GSON is the library of interest. If you have an environment that deals often with big JSON files, then Jackson is suitable library. GSON struggles the most with big files.
  • What tools do you use to test RESTful APIs ?
    • Postman, SOUP UI.

source: https://quachson.com/tips-work-java-restful/

 

Phím tắt Mac OS X toàn tập

Bạn có thể sử dụng phím tắt để làm việc trên máy Mac bằng cách sử dụng các tổ hợp phím trên bàn phím.

Sử dụng phím tắt

Để sử dụng phím tắt, chúng ta cần ấn Phím Chức Năng cùng lúc với phím ký tự. Ví dụ: Ấn Command key (⌘) và sau đó ấn “c” để copy bất kể gì vào Clipboard. Vậy ta có Command-C là phím tắt. Bạn cũng có thể thấy các phím tắt bằng cách nhìn vào Menu của chương trình.

Phím chức năng là một phần của các tổ hợp phím tắt. Phím chức năng làm thay đổi tổ hợp khi sử dụng chuột, trackpad bằng nhiều cách khác nhau trên OS X. Phím chức năng bao gồm các phím: Command, Shift, Option, Control, Caps Lock và phím fn. Các phím trên được hiển thị bằng các kí hiệu khi bạn nhìn thấy trên Menu hoặc những phần khác của OS X:

TỔ HỢP PHÍM CHỨC NĂNG
fn Phím Funtion (fn)
Phím Command
Phím Control
Phím Caps lock
Phím Option
Phím Shift

Khi phím fn được sử dụng cùng với dãy phím của hàng trên cùng trên bàn phím, nó sẽ ra các chức năng khác. Ví dụ: nếu phím tắt Control-F2, bạn có thể ấn fn-Control-Brightness trên bàn phím. Nếu bạn nhìn sát vào phím Brightness ở trên bàn phím sẽ thấy biểu tượng F2 và phím đó hoạt động như chức năng hiển thị (F2 hoặc funtion2) khi bạn sẽ fn trên bàn phím.

Nếu bạn sử dụng bàn phím không phải của Apple và có phím Windows, phím Alt sẽ hoạt động tương tự như Option, và phím Windows hoạt động như phím Command. Bạn có thể thay đổi những phím trên trong Keyboard pane of System Prefrences. (Bấm vào biểu tượng Apple > System Prefrences > Keyboard > Modifier Keys, sau đó chọn các phím muốn thay đổi và lựa chọn, nếu muốn quay lại mặc địch các bạn bấm Restore Defaults.)

Cut, Copy và Paste

Bạn có thể sử dụng trong phần lớn các ứng dụng với lệnh cut, copy, paste. Có thể là ảnh, chữ, nhạc và nhiều thứ khác. Bạn có thể copy, paste files trong Finder để Copy sang chỗ khác.

TỔ HỢP PHÍM CHỨC NĂNG
Command-C Copy dữ liệu lựa chọn vào Clipboard
Command-X Xóa bỏ dữ liệu được copy và Clipboard
Command-V Tạo bản sao với nội dung trong Clipboard vào trong tài liệu hoặc ứng dụng đang lựa chọn

Chụp ảnh màn hình

Sử dụng phím tắt này để chụp những gì bạn thấy trên màn hình. Hoặc bạn có thể sử dụng Grab để chụp màn hình, Grab nằm trong thư mục Applications > Utilities

TỔ HỢP PHÍM CHỨC NĂNG
Command-Shift-3 Chụp lại toàn màn hình và lưu ra file
Command-Shift-Control-3 Chụp toàn màn hình và lưu vào Clipboard
Command-Shift-4 Chụp lại một phần màn hình bạn lựa chọn và lưu ra file hoặc bấm Spacebar để chụp mỗi cửa sổ bạn chọn lựa.
Command-Shift-Control-4 Chụp một phần màn hình bạn lựa chọn và lưu vào Clipboard, hoặc bấm Spacebar để chụp cửa sổ bạn chọn lựa.

Phím tắt khi khởi động

Sử dụng các tổ hợp phím này để thay đổi tính năng khi bạn khởi động máy, Bấm và giữ phím hoặc tổ hợp phím ngay lập tức sau khi bật máy Mac của bạn cho đến khi chức năng xuất hiện, ví dụ: bấm và giữ phím Option trong khi khởi động cho đến khi Startup Manager xuất hiện.

Lưu ý: Nếu bạn đang sử dụng một bàn phím được sản xuất bởi một công ty khác không phải của Apple, phím Alt thường có chức năng như phím Option. Nếu ban làm tác vụ tương tự nhưng không hoạt động hãy thử sử dụng một bàn phím Apple thay thế.

TỔ HỢP PHÍM CHỨC NĂNG
Option hoặc Alt Hiển thị tất cả phân vùng khởi động (Startup Manager)
Shift Khởi động với Safe Mode
C Khởi động từ DVD, CD, USB
T Khởi động trong Target disk mode (chế độ này cho phép Mac khởi động qua cổng FireWire hay Thunderbolt. hoặc kết nối với 1 máy Mac khác như ổ đĩa ngoài.)
N Khởi động từ NetBoot server – bạn có thể cài hoặc khởi động OS X thông qua mạng sử dụng dịch vụ OS X Server.
X Khởi động trực tiếp vào Mac OS X (khi không có phân vùng cài OS X có sẵn)
D Khởi chạy chế độ kiểm tra phần cứng (Apple Hardware Test)
Command-R Sử dụng OS X Recovery (từ OS X Lion về sau)
Command-Option-R Sử dụng Internet Recovery trên những máy có hỗ trợ
Command-V Khởi động vào Verbose Mode
Command-S Khởi động vào Single User Mode
Command-Option-P-R RESET NVRAM (nhấn và giữ tổ hợp phím cho đến khi Mac phát ra tiếng khởi động 2 lần. Có tác dụng giải phóng PRAM đưa về cấu hình mặc định của display setting, time and date, time zone, speaker volume, DVD setting, Region.)
Giữ phím Media Eject (⏏) , F12, hoặc Chuột hoặc bấm trackpad Eject ổ di động

Phím tắt khi Sleep, Shut down và Log out

Sử dụng các tổ hợp phím sau khi Mac của bạn bắt đầu Sleep, Shut down, Log out, hoặc khởi động lại máy tính của bạn.

TỔ HỢP PHÍM CHỨC NĂNG
Nút Power Bấm để bật máy, Khi Mac đã bật, bấm để sleep hoặc bật máy lại.
Giữ nút Power trong 1,5s Hiển thị bảng Restart / Sleep / Shut Down
Giữ nút Power trong 5s Ép máy Mac tắt
Control-nút Power Hiển thị bảng Restart / Sleep / Shut down
Command-Control-nút Power Ép Mac khởi động lại
Command-Option-nút Power Đưa máy vào chế độ Sleep
Command-Control-nút Power Thoát tất cả ứng dụng (máy sẽ hỏi bạn có lưu lại các tài liệu đang sử dụng hay không) sau đó khởi động lại máy
Shift-Control-nút Power Đưa màn hình vào chế độ Sleep
Command-Shift-Q Log Out
Command-Shift-Option-Q Log Out ngay lập tức

Phím tắt trong các Ứng dụng

Các phím tắt sau hoạt động trong phần lớn các ứng dụng.

TỔ HỢP PHÍM CHỨC NĂNG
Command-A Chọn tất cả hoặc toàn bộ chữ trong cửa sổ đầu tiên
Command-Z Hoàn tác lệnh trước đó (một số ứng dụng cho phép bạn thực hiện nhiều lần)
Command-Shift-Z Làm lại, đặt lại các thay đổi cuối thực hiện với Undo (một số ứng dụng cho phép bạn làm lại nhiều lần)
Command-Space bar Hiển thị hoặc ẩn đi ô tìm kiếm Spotlight
Command-Option-Space bar Hiển thị cửa sổ kết quả tìm kiếm Spotlight
Command-Tab Di chuyển tiếp đến các ứng dụng gần đây nhất được sử dụng tiếp theo trong danh sách các ứng dụng đang mở
Option-Media Eject (⏏) Eject ổ đĩa quang
Command-Brightness down (F1) Chuyển chế độ “Mirror Displays” cho màn hình đa cấu hình
Command-Brightness up (F2) Chuyển chế độ Target Display Mode
Command-Mission Control  (F3) Hiển thị Desktop
Command-F5 Bật tắt VoiceOver
Option-Brightness (F2) Bật “Displays” tron System Preference
Option-Mission Control (F3) Mở thiết lập Mission Control
Option-Volume key (F12) Mở thiết lập âm thanh
Command-Minus (–) Giảm kích cỡ của mục được chọn
Command-Colon (:) Hiển thị cửa sổ Spelling and Grammar
Command-Semicolon (;) Tìm từ sai chính tả trong các tài liệu
Command-Comma (,) Mở Preferences (Thiếp lập) của ứng dụng đang hiển thị
Command-Question Mark (?) Mở Help
Command-plus (+) or Command-Shift-Equals (=) Tăng kích cỡ của mục được chọn
Command-Option-D Hiển thị hoặc ẩn Dock
Command-Control-D Hiển thị hoặc ẩn định nghĩa của từ đang được chọn
Command-D Chọn thư mục Desktop Desktop trong cửa sổ hiển thị Open và Save
Command-Delete Lựa chọn không lưu (don’t save) trong hộp thoại có chưa nút Xóa (delete) hoặc (don’t save)
Command-E Sử dụng lựa chọn để tìm kiếm
Command-F Mở cửa sổ Tìm kiếm hoặc tìm từ trong văn bản
Command-Option-F Chuyển đến mục tìm kiếm nâng cao
Command-G Tìm tới sự tìm kiếm tiếp theo của lựa chọn
Command-Shift-G Tìm tới sự tìm kiếm trước đó của lựa chọn
Command-H Ẩn cửa sổ của các ứng dụng đang chạy
Command-Option-H Ẩn cửa sổ của tất cả các ứng dụng đang chạy
Command-Option-I Hiển thị thông tin
Command-M Thu nhỏ cửa sổ đang làm việc vào Dock
Command-Option-M Thu nhỏ toàn bộ các cửa sổ vào Dock
Command-N Tạo một tài liệu mới trong ứng dụng
Command-O Hiển thị hộp thoại cho việc lựa chọn tài liệu mở trong ứng dụng
Command-P In tài liệu hiện tại
Command-Shift-P Hiển thị cửa sổ để xác định các thông số tài liệu (Page Setup)
Command-Q Thoát khỏi ứng dụng đang thực thi
Command-S Lưu tài liệu đang sử dụng
Command-Shift-S Hiển thị hộp thoại Save As hoặc tạo bản sao các tài liệu hiện hành
Command-Option-T Ẩn hoặc hiển thị toolbar
Command-W Đóng cửa sổ đang thực thi
Command-Option-W Đóng tất cả cửa sổ trong ứng dụng hiện tại
Command-Option-esc Lựa chọn Ứng dụng để Force Quit
Command-Shift-Option-Esc (giữ trong 3s) Force Quit ứng dụng hiển thị

Làm việc với văn bản

Sử dụng các tổ hợp phím khi chỉnh sửa văn bản trong một trường hoặc tài liệu.

TỔ HỢP PHÍM CHỨC NĂNG
Command-B Bold văn bản đã chọn hoặc chuyển đổi đậm hoặc không
Command-I Italicize văn bản đã chọn hoặc chuyển đổi in nghiêng hoặc không
Command-U Underline văn bản đã chọn hoặc chuyển đổi gạch chân hoặc không
Command-T Hiển thị hay ẩn cửa sổ Fonts
fn-Delete Xóa phía trước (bên phải)
fn-Up Arrow Cuộn trang lên (Chức năng như phím Page Up)
fn-Down Arrow Cuộn trang xuống (Chức năng như phím Page Down)
fn-Left Arrow Cuộn tới đầu của văn bản (Chức năng như phím Home)
fn-Right Arrow Cuộn xuống cuối văn bản (chức năng như phím End)
Command-Right Arrow Di chuyển điểm chèn văn bản đến cuối dòng hiện tại
Command-Left Arrow Di chuyển điểm chèn văn bản vào đầu dòng hiện tại
Command-Down Arrow Di chuyển điểm chèn văn bản vào cuối tài liệu
Command-Up Arrow Di chuyển điểm chèn văn bản vào đầu tài liệu
Option-Right Arrow Di chuyển điểm chèn văn bản vào cuối của từ tiếp theo
Option-Left Arrow Di chuyển điểm chèn văn bản đến phía trước của từ trước đó
Option-Delete Xóa từ bên trái con trỏ, cũng như bất kỳ dấu cách hoặc dấu chấm câu sau từ
Command-Shift-Right Arrow Chọn văn bản giữa các điểm chèn và cuối dòng hiện tại (*)
Command-Shift-Left Arrow Chọn văn bản giữa các điểm chèn và sự khởi đầu của dòng hiện hành (*)
Command-Shift-Up Arrow Chọn văn bản giữa các điểm chèn và các đầu của tài liệu (*)
Command-Shift-Down Arrow Chọn văn bản giữa các điểm chèn và cuối của tài liệu (*)
Shift-Left Arrow Mở rộng văn bản lựa chọn một ký tự bên trái (*)
Shift-Right Arrow Mở rộng văn bản lựa chọn một ký tự bên phải (*)
Shift-Up Arrow Mở rộng văn bản lựa chọn lên 1 dòng
Shift-Down Arrow Mở rộng văn bản lựa chọn xuống 1 dòng
Shift-Option-Right Arrow Mở rộng văn bản lựa chọn theo từ sang phải
Shift-Option-Left Arrow Mở rộng văn bản lựa chọn theo từ sang trái
Shift-Option-Down Arrow Mở rộng văn bản lựa chọn theo từ xuống 1 dòng.
Shift-Option-Up Arrow Mở rộng văn bản lựa chọn theo từ lên 1 dòng.
Control-A Di chuyển đến đầu dòng hoặc đoạn
Control-B Di chuyển sang trái một kí tự
Control-D Xóa kí tự trước con trỏ (bên phải) (tương đương phím del bên Win)
Control-E Di chuyển đến đầu dòng hoặc đoạn
Control-F Di chuyển sang phải một kí tự
Control-H Xóa một kí tự bên trái con trỏ (tương đương phím delete)
Control-K Xóa đoạn văn bản từ bên phải con trỏ đến hết
Control-L Tìm con trỏ nhanh
Control-N Di chuyển xuống một dòng
Control-O Chén một dòng mới sau con trỏ
Control-P Di chuyển lên một dòng
Control-T Đổi ký tự chữ cái hiện tại con trỏ và chữ phía trước
Control-V Di chuyển xuống
Command-{ Lựa chọn căn lề trái (left-align)
Command-} Lựa chọn căn lề phải (right-align)
Command-| Lựa chọn căn giữa (center-align)
Command-Option-C Sao chép các thiết lập định dạng của văn bản và lưu vào Clipboard
Command-Option-V Áp dụng phong cách của một đoạn với các đoạn (Paste Style)
Command-Shift-Option-V Áp dụng phong cách của văn bản xung quanh để chèn vào (Paste and Match Style)
Command-Control-V Áp dụng các thiết lập định dạng với các đối tượng được chọn (Paste Ruler)

Phím tắt trong Finder

TỔ HỢP PHÍM CHỨC NĂNG
Command-A Lựa chọn toàn bộ tập tin trong cửa sổ
Command-Option-A Bỏ chọn toàn bộ
Command-C Sao chép (Copy) tập tin được chọn, sau đó sử dụng Paste (Dán) hoặc Move (Di chuyển) để di chuyển files
Command-D Tạo bản sao với files được chọn lựa
Command-E Eject
Command-F Tìm bất kỳ thuộc tính phù hợp với Spotlight
Command-I Hiển thị cửa sổ Get Info với file được chọn lựa
Command-Shift-C Mở cửa sổ Computer
Command-Shift-D Mở thư mực desktop
Command-Shift-F Hiển thị cửa sổ All My Files
Command-Shift-G Go to Folder
Command-Shift-H Mở thư mục Home của tài khoản đang được sử dụng
Command-Shift-I Mở iCloud Drive
Command-Shift-K Mở cửa sổ Network
Command-Shift-L Mở thư mục Downloads
Command-Shift-O Mở thư mục Documents
Command-Shift-R Mở cửa sổ AirDrop
Command-Shift-U Mở thư mục Utilities
Command-Control-T Thêm vào Sidebar (OS X Mavericks)
Command-Option-I Ẩn hoặc hiển thị cửa sổ thông tin (inspector)
Command-Control-I Lấy thông tin tổng hợp giống như properties
Command-Option-P Ẩn hoặc hiện thanh đường dẫn
Command-Option-S Ẩn hoặc hiện thanh Sidebar
Command-forward slash (/) Ẩn hoặc hiện thanh Status
Command-J Hiển thị thiết lập tùy chọn xem
Command-K Kết nối tới Server
Command-L Tạo alias của mục được chọn
Command-N Mở cửa sổ Finder mới
Command-Shift-N Tạo thư mục mới
Command-Option-N Tạo Smart Folder mới
Command-O Mở mục được chọn
Command-R Hiển thị bản gốc (của alias)
Command-T Hiển thị hay ẩn thanh tab khi một tab đang được mở trong Finder
Command-Shift-T Hiển thị hoặc ẩn thanh Tab
Command-Option-T Ẩn hoặc hiển thị thanh công cụ (Toolbar) khi một tab đang được mở trong Finder
Command-V Dán (Paste) bản sao mà bạn đã sao chép tới mục hiện tại
Command-Option-V Di chuyển các tập tin mà bạn đã đặt vào clipboard từ vị trí ban đầu tới vị trí hiện tại.
Command-Option-Y Xem slideshow QuickLook slideshow của các tập tin đã được chọn lựa
Command-1 Xem theo dạng biểu tượng (Icon)
Command-2 Xem theo dạng danh sách (List)
Command-3 Xem theo dạng cột (Columns)
Command-4 Xem heo dạng Cover Flow (Mac OS X v10.5 và cao hơn)
Command-Comma (,) Mở thiết lập Finder
Command-Left Bracket ([) Quay lại thư mục trước folder
Command-Right Bracket (]) Vào thư mục tiếp theo
Command-Up Arrow Mở thư mục chưa thư mục hiện tại
Command-Control-Up Arrow Mở thư mục chứa thư mục hiện tại trong cửa sổ mới
Command-Down Arrow Mở mục đã chọn
Right Arrow (in List view) Mở thư mục đã chọn
Left Arrow (in List view) Đóng thư mục được lựa chọn
Option-click the disclosure triangle (in List view) Mở tất cả các thư mục trong thư mục đã chọn
Option–double-click Mở một thư mục trong một cửa sổ riêng biệt, đóng cửa sổ hiện tại
Command–double-click Mở một thư mục trong một tab riêng biệt hoặc cửa sổ
Command-click the window title Xem các thư mục có chứa các cửa sổ hiện tại
Command-Delete Chuyển vào Thùng rác
Command-Shift-Delete Dọn Thùng rác
Command-Shift-Option-Delete Dọn Thùng rác mà không cần hiển thị xác nhận
Space bar (or Command-Y) Quick Look tập tin được chọn
Command key while dragging Di chuyển các tập được lựa chọn vào phân vùng khác hoặc vị trí khác
Option key while dragging Sao chép các mục kéo
Command-Option key combination while dragging Tạo alias của các mục kéo

nguồn: https://quachson.com/phim-tat-mac-os-x-toan-tap/

 

NodeJS for beginners

Some keywords that you must find out if you want to learn nodejs: promise, asynchronous, callback, callback hell, eslint, ES6, functional programming, parameter as function.
IDE: Visual Studio Code (free), IntelliJ (license), Eclipse, Atom, sublime text, ….
These libraries that I used to use: npm, yarn, eslint, async, fs, lodash, expressJS, node-fetch, nconf, mongoosejs, graphql, react, redux , jsdoc, rimraf, husky
xml parser : sax, saxpath, xml2js.

If you’re similar ES6, you will learn Stream in Java 8 quickly.
Example: Find max multiples of 3 in array
nodejs

import { filter, max } from 'lodash';

const array = [99, 5, 4, 10, 8, 6, 33, 12, 45, 63];
console.log(max(filter(array, item =&gt; item % 3 == 0)));

java

int[] array = {99, 5, 4, 10, 8, 6, 33, 12, 45, 63};
Arrays.stream(array).filter(item -&gt; item % 3 == 0).reduce(Integer::max).ifPresent(System.out::println);

Machine Learning là gì ?

I. 3 dạng Machine Learning chính
1/ Supervised Learning: Nôm na nghĩa là máy sẽ đưa ra suy đoán dựa trên một tập dữ liệu cho trước đã được training.

Những vấn đề của supervised learning được chia làm 2 loại: hồi quy (regression) và phân loại (classification)
Ví dụ 1: Chúng ta có sẵn 1000 status facebook (gọi là dataset A) được phân loại theo các trạng thái như vui, buồn, giận dữ v.v.. (ứng với mỗi trạng thái là một tập hợp các đặc tính có liên quan, ví dụ các trạng thái status vui thì thường xuất hiện các cụm từ như “đáng yêu quá”, “thích quá”, “hay quá”…), supervised learning là phương pháp sử dụng dataset A này để xác định 100 status facebook khác chưa được gắn trạng thái.

Ví dụ 2:
(a) Hồi quy – Đưa ra tấm hình của 1 người, chúng ta dự đoán tuổi của người đó dựa trên tấm hình

(b) Phân loại – Với một bệnh nhân có khối u, chúng tôi-có để dự đoán xem khối u ác tính hoặc lành tính.

2/ Unsupervised Learning: Nôm na nghĩa là tay không bắt giặc 😀 máy sẽ tự tìm ra các mối quan hệ hoặc các pattern từ một dataset.
Ví dụ 1: Chúng ta có thể sử dụng phương pháp unsupervised learning để tìm ra các chủ đề được đề cập tới từ 1000 status facebook, ví dụ các status có chủ đề về bóng đá (vì trong những status này xuất hiện nhiều từ, cụm từ, hashtag có liên quan đến bóng đá chẳng hạn).

Ví dụ 2:
Clustering: Lấy một bộ sưu tập của một triệu gen khác nhau, và tìm cách tự động nhóm những gen có liên quan hoặc tương tự vào 1 nhóm lớn bởi những giá trị khác nhau như là tuổi thọ, vị trí, vai trò, …

Non-clustering: Các “Thuật toán tiệc Cocktail”, cho phép bạn tìm thấy một cấu trúc trong môi trường hỗn loạn. (Nghĩa là: Xác định tiếng nói riêng và âm nhạc từ một mạng lưới các âm thanh tại một bữa tiệc cocktail).

3/ Reinforcement Learning: Nôm na nghĩa là máy có thể tự cập nhật cách giải quyết vấn đề theo kiểu thử và sửa liên tục.
Ví dụ: DeepMind AlphaGo với việc chiến thắng Lee Sedol trong bộ môn cờ vây là ví dụ nổi tiếng nhất về RL (thực tế DeepMind gọi là Deep Reinforcement Learning).

II. 10 thuật toán Machine Learning quan trọng nhất
Để kết luận 10 thuật toán ML nào quan trọng nhất thực sự là việc rất phức tạp vì chúng ta không biết xếp theo tiêu chí nào? Ví dụ độ phổ biến, tính hữu dụng, tính đơn giản, tính chính xác v.v.. Vì thế mình chỉ giả định nếu mình phỏng vấn một người cho vị trí Data Scientist / Data Engineer thì mình cần họ phải nắm được 10 thuật toán sau (theo thứ tự ưu tiên):

  • Linear Regression
  • Logistic Regression
  • Decision Trees
  • Naïve Bayes Classification
  • Ordinary Least Squares Regression
  • Support Vector Machines
  • Ensemble Methods
  • Clustering Algorithms
  • Principal Component Analysis
  • Singular Value Decomposition
  • Independent Component Analysis

1/ Linear Regression và Logistic Regression (Hồi quy tuyến tính và Hồi quy Logistic):

Dùng làm gì nhỉ? Thuật toán Linear Regression mô tả dữ liệu và thể hiện mối quan hệ giữa một biến phụ thuộc (x) với một (y) hoặc nhiều (yi) biến độc lập. Tức là nếu biến độc lập thay đổi thì ảnh hưởng đến biến phụ thuộc như thế nào. Nếu 1 biến độc lập gọi là Hồi quy tuyến tính đơn (Simple Linear Regression), nếu nhiều biến độc lập gọi là Hồi quy tuyến tính đa biến (Multiple Linear Regression).

Đơn: y = \beta 1 + \beta 2 x + \alpha

Đa: y = \beta 0 + \beta 1 x1 + \beta 2 x2 + ... + \beta n xn + \alpha

Nhìn vào phương trình ta thấy gì, y thay đổi khi x thay đổi.
Ok, tạm hiểu, thế sao người ta lại dùng Linear Regression mà không dùng thuật toán khác? Một số ưu điểm của Linear Regression là tính dễ hiểu của thuật toán (ví dụ trên chẳng hạn, những thuật toán sau ví dụ không dễ hiểu như vậy đâu :)); dễ chỉnh sửa (tuning); độ phổ biến cao và tốc độ giải thuật nhanh. Nghe có vẻ dễ đúng không? Cái khó nhất của các Generalized Linear Model (GLM – Mô hình tuyến tính tổng quát) là việc chọn independent variables chứ không phải là thuật toán.
Thế Linear Regression và Logistic Regression thì khác nhau cái gì? Cái khác nhau nhất chính là ở dependent variable, đối với Linear Regression thì DV có dạng liên tục (continuous) còn đối với Logistic Regression thì DV có thể chỉ là Có/Không, Sống/Chết, 0/1 (mô hình nhị phân) hoặc DV có thể ở dạng rời rạc (discrete). Continuos và discrete là hai khái niệm rất lớn trong toán học, các bạn có thể tìm hiểu thêm ở trên mạng, trong khuôn khổ bài này thì hơi khó để giải thích ngắn gọn được.
Ứng dụng trong đời thường như thế nào? Một trong những ứng dụng lớn nhất của GLM model (Mô hình tuyến tính tổng quát) là hệ thống quản lý rủi ro hoặc chấm điểm tín dụng của các ngân hàng. Chẳng hạn như để quyết định hạn mức thẻ Credit card của bạn, hệ thống sẽ sử dụng GLM để tính toán dựa trên các thông tin bạn cung cấp như mức lương hiện tại, độ tuổi, giới tính, công việc đang làm v.v..

2/ Decision Trees (Cây quyết định)
Dùng làm gì nhỉ?Cây quyết định là một công cụ dùng để hỗ trợ trong việc ra quyết định dựa trên một hoặc nhiều biểu đồ dạng cây. Biểu đồ này thể hiện số lượng câu hỏi yes/no tối thiểu mà một người cần hỏi, để đánh giá về khả năng ra được một quyết định đúng.
Ví dụ nhé,chúng ta có một dataset về dữ liệu về các cầu thủ trẻ trong khoảnng 10-16 tuổi. Chúng ta có thể collect được những dữ liệu như vị trí thi đấu, chiều cao, cân nặng, tỷ lệ sút bóng thành công, tỷ lệ xoạc bóng thành công, tỷ lệ chuyền bóng thành công, tốc độ, tỷ lệ đánh đầu thành công v.v…
Giả sử bạn là một HLV và đang có một lứa cầu thủ trẻ mới vào. Làm thế nào để quyết định được một cầu thủ trẻ nên chơi ở vị trí thi đấu nào là phù hợp nhất?
Sử dụng Cây quyết định sẽ giúp bạn làm được điều này, bằng cách thu thập những dữ liệu của lứa cầu thủ trẻ mới vào và so sánh dữ liệu mới này với dữ liệu có sẵn trong dataset, Cây quyết định sẽ giúp bạn xác định được vị trí thi đấu nào thích hợp nhất với một cầu thủ trẻ mới tuyển.
Nghe cool vãi, nhưng theo tôi biết thì đếch có thuật toán nào gọi là Cây quyết định cả :)) Oh đúng, xin lỗi :)) Cây quyết định thực ra là một họ tập hợp các thuật toán mà outcome của nó có thể biểu diễn dưới dạng cây. Một số thuật toán họ này rất phổ biến như C4.5 hoặc Random Forest v.v… Trong khuôn khổ bài mở đầu này, mình chỉ có thể giới thiệu khái quát như vậy, sẽ có những bài khác đi sâu hơn vào từng thuật toán trên.

decision-tree

Oh thế Cây quyết định thì có gì hay? Cái hay nhất của Cây quyết định là tính đơn giản và dễ interpret của kết quả. Hầu như bất kỳ ai nhìn vào một decision tree cũng có thể hiểu được mà không cần có kiến thức gì về Machine Learning cả.
Ứng dụng lớn nhất của Decision Trees là gì? Ứng dụng của Decision Trees cực nhiều, cực phổ biến, vì tính thực tiễn của nó trong việc hỗ trợ ra quyết định (mà trong thực tế thì công việc gì cũng cần quyết định). Ví dụ: quyết định cho vay, quyết định về chiến lược giá bán v.v..

Mình muốn kết thúc phần này bằng một câu nói của Andrew Ng – Chief Scientist của Baidu và Founder của Coursera: “Nếu bạn thành thạo thuật toán hồi quy tuyến tính, hồi quy logistic và nguyên tắc kiểm soát (regularization) thì bạn đã biết nhiều về Machine Learning hơn phần lớn các kỹ sư Machine Learning ở Silicon Valley rồi”. Để biết về các thuật toán này thì không khó nhưng để master nó thì không hề dễ chút nào (nhất là về regularization). Điều mà mình muốn nói ở đây chính là Machine Learning không hề khó, không phải là một black-box, ai cũng có thể học và master được nếu họ thực sự yêu thích và muốn nắm được một trong những vũ khí mạnh nhất của nhân loại hiện nay.
Tham khảo: Nguyễn Đức Anh

Những hạn chế của Classification

Classification là toán xác xuất nên để kỳ vọng tính chính xác 100% là rất khó vì nó phụ thuộc vào tập dataset. Classification chỉ có 2 giá trị: [0,1], [đúng, sai], về email thì [spam, not spam], [khẳng định, phủ định], thông thường thì có ngưỡng giữa tùy vào ta chọn như [0,1] ta chọn 0.5 cho đơn giản làm ví dụ, nếu < 0.5 ==> 0,  > 0.5 là 1. Kết quả trả về rơi nhiều vào giữa ngưỡng [0.4, 0.5, 0.6] có thể dẫn đến kết quả sai. Gọi là na ná giống nhau, nhưng về bản chất nhiều khi khác nhau xa lắm. Cho nên khi có kết quả gần đúng người ta sẽ dùng thuật toán khác filter thêm lần nữa để cho ra kết quả tốt hơn. Ta làm thử 1 ví dụ để xem tính chính xác của Classification như thế nào nhé.

Example: ta dùng tập [0,1] và chọn ngưỡng giữa là 0.5 và có tập kết quả là {1, 0, 0.6, 0.4, 1, 0}

– TP: đúng tuyệt đối, có giá trị là 1.

– FN: Sai tuyệt đối, có giá trị là 0.

– FP: Đúng ở ngưỡng giữa, 0.5, 0.6, 0.7… < 1

– TN: Sai ở ngưỡng giữa: 0.4, 0.3,0.2… > 0

Trong trường hợp này ta có.

TP = 2 (có 2 giá trị 1), đúng 100%

FN = 2 (có 2 giá trị 0), sai 100%

FP = 1 (0.6)

TN = 1 (0.4)

Ta có thể định nghĩa tính chính xác như sau:

Tính chính xác = (TP + TN)/(TP + TN + FP + FN) = (2 + 2)/(2 + 2 + 1 + 1) = 23

Ta có 4 mẫu đúng trên 6 mẫu. Bây giờ ta xem thêm ví dụ khác về lọc email spam.

Classified positive Classified negative
Positive class 10 15
Negative class 5 100

Trong trường hợp này, tính chính xác = (10 + 100)/(10 + 5 + 15 + 100) = 84.6%. Ta tạm thời cho rằng thuật toán phân loại làm việc rất hiệu quả, dò tìm dc gần 85% những email spam. Tuy nhiên điều gì sẽ xảy ra khi ta chuyển đổi thuật toán của Classficication rằng không có email spam nào cả.

Classified positive Classified negative
Positive class 0 0
Negative class 15 115

Tính chính xác = (0 + 115)/(0 + 15 + 0 + 115) = 88.5%. Thật không thể tin nổi. Ta thay đổi thuật toán để cho ra kết quả hoàn toàn vô nghĩa, với số 0 ta đã làm tăng tính chính xác.

Cái này dc gọi là nghịch lý chính xác (the accuracy paradox). Khi TP < FP, tính chính xác sẽ luôn tăng khi ta thay đổi thuật toán phân loại để luôn luôn ra kết quả sai. Ngược lại khi TN < FN tương tự như vậy khi ta thay đổi luật để luôn cho ra kết quả đúng.

Vậy thì ta có thể làm dc gì, Ta nên biết rằng không có thuật toán phân loại nào là tốt nhất, chính xác nhất cả, ta phải biết kết hợp nhiều thuật toán phân loại với nhau để cho ra kết quả chính xác nhất có thể.

Kết luận là lại chọn ngưỡng giữa cho Classification là rất quan trọng. Trong y học những triệu chứng bệnh na ná giống nhau là rất nhiều, khi phân loại dc bệnh rồi còn phải yêu cầu đi làm xét nghiệm nữa, nghĩa là phân loại thêm lần nữa để chính xác hơn.