
Chinh phục Silicon Valley Part 2
Tiếp theo phần 1, mình xin kể tiếp câu chuyện phỏng vấn ở Silicon Valley. Sau lần thất bại đó, đơn vị tiếp tục đưa ứng viên thứ 2 ra phỏng vấn. Thật bất ngờ, khi bác Director of Software engineer lại sử dụng y chang bộ câu hỏi lần trước. Đó là tình huống không được tính đến, vì ai cũng nghĩ rằng cụ sẽ hỏi câu hỏi khác với mỗi lập trình viên khác nhau. Kết quả thì ai cũng biết, lại tạch.
Tuy nhiên, với phương châm không bỏ cuộc, never give up, vì nếu trượt phỏng vấn đồng nghĩa là mất luôn dự án, ảnh hưởng đến business của công ty. Theo chỉ thị của lãnh đạo, các ban bệ vào cuộc, toàn bộ record của phỏng vấn được nghe lại, mổ xẻ như phân tích băng ghi hình trận đá bóng. Câu hỏi phỏng vấn được Google search, gửi tới các chuyên gia để được tư vấn. Thậm chí còn được post lên diễn đàn công nghệ để tham khảo (bà con cũng nhảy vô cãi nhau ỏm tỏi, mỗi người 1 đáp án, gạch đá ném đủ xây nhà).
Sau hàng loạt các phân tích bình luận của các chuyên gia thì đã tìm ra câu trả lời có thể nói là chính xác nhất
Câu 1. Viết code ví dụ về Singleton class
Thật ra có đến mấy kiểu viết code về Singleton class trong Java trong đó có 2 kiểu thông dụng là:
Early Instantiation: Tạo instance tại thời điểm class load time
public class Singleton {
// singleton instance, this instance is created in JVM during start of the application
// which is early loading
private static final Singleton singletonInst = new Singleton();
// making constructor private so that no other class could use the default constructor
private Singleton() {
}
// the method which gives access to the only instance of Singleton
public static Singleton getInstance(){
return singletonInst;
}
}
Kiểu Lazy Loading: Instance được tạo khi Singleton class được dùng lần đầu tiên, như code đã trình bày ở phần 1
Cần phải trình bày cả trường hợp đa luồng như phần 1 nữa. Túm váy phải phân tích từng trường hợp, đánh giá ưu nhược điểm. Và 1 Singleton có thể tạm gọi là chuẩn man là như sau:
public class Singleton {
private static volatile Singleton self;
private Singleton() {
if (self != null) {
throw new UnsupportedOperationException("Use getInstance()");
}
}
public static synchronized Singleton getInstance() {
if (self == null) {
self = new Singleton();
}
return self;
}
}
Quan trọng nhất là câu hỏi này, quyết định việc fail hay pass
Có trường hợp nào Singleton có tạo nhiều instance không?
Câu trả lời đúng ở đây là YES
Java có một khái niệm là Reflection, API cho phép kiểm tra và modify behavior của methods, class at runtime.
Reflection này có thể gây ra việc destroy singleton property của singleton class
// Java code to explain effect of Reflection
// on Singleton property
import java.lang.reflect.Constructor;
// Singleton class
class Singleton
{
// public instance initialized when loading the class
public static Singleton instance = new Singleton();
private Singleton()
{
// private constructor
}
}
public class GFG
{
public static void main(String[] args)
{
Singleton instance1 = Singleton.instance;
Singleton instance2 = null;
try
{
Constructor[] constructors =
Singleton.class.getDeclaredConstructors();
for (Constructor constructor : constructors)
{
// Below code will destroy the singleton pattern
constructor.setAccessible(true);
instance2 = (Singleton) constructor.newInstance();
break;
}
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("instance1.hashCode():- "
+ instance1.hashCode());
System.out.println("instance2.hashCode():- "
+ instance2.hashCode());
}
}
Dẫn tới việc singleton bị destroy và tạo 2 object khác nhau thuộc sample class
Output:-
instance1.hashCode():- 366712642
instance2.hashCode():- 1829164700
Ngoài ra còn có trường hợp serialize/desterilize object cũng xảy ra
https://gurunh.com/2018/05/singleton-co-thuc-su-de/
Trích dẫn nguyên văn câu trong Head First Design Patterns
Be careful if you are using multiple class loaders; this could defeat Singleton implementation and result in multiple instances.
Câu 2: Coding
Viết chuỗi đảo ngược kí tự
Ngoài việc dùng vòng lặp đảo vị trí phần tử như phần 1, thì có thể sử dụng thuật toán đệ quy.
public static int[] reverseArray(int[] a,int left,int right){
//Tail Recursion.
if(left<right){
//swap elements a[i],a[j]
int temp=a[left];
a[left]=a[right];
a[right]=temp;
reverseArray(a, left+1, right-1);
}
return a;
}
Code đơn giản hơn, nhưng mình không nghĩ đệ quy là tối ưu nhất vì trong đệ quy, hàm sẽ được gọi nhiều lần và bộ nhớ stack sẽ bị chồng thêm dữ liệu dễ gây issue về bộ nhớ
Bài code số 2
Cho số dương integer n, tìm số cách để để chia n thành 5 số dương nhỏ hơn sao cho cộng lại thì vẫn là n
Ví dụ n = 5 thì output 1 vì chỉ có 1 case (1, 1, 1, 1, 1)
N = 12 thì có 7 cách
Nhờ sự trợ giúp của anh Guc Gồ thì đã phát hiện ra đằng sau bài toán này là cả 1 bầu trời kiến thức về toán học
https://www.mathpages.com/home/kmath556/kmath556.htm
Đọc xong cảm thấy ngu người luôn
Đại loại công thức để tìm số cách thế này. N là số dương cần chia, K là số lượng số dương < N
Câu 3: Câu hỏi về vấn đề hệ thống read data 99%, write 1% thì nên chọn loại dữ liệu gì
Câu trả lời là ArrayList như phần 1, nhưng trường hợp đa luồng thì vẫn có thể dùng ArrayList nhưng ko share list này giữa các luồng.
Hoặc 1 câu trả lời khác như sau (Xin tư vấn của 1 cao thủ Java)
Nếu là môi trường single-thread thì dùng ArrayList tốt hơn LinkedList trong trường hợp ở đây (nhất là khi list có kích thước tương đối lớn) là vì ArrayList là random access trong khi LinkedList thì ko.
Đổi lại thì thêm, remove phần tử trên ArrayList sẽ kém hơn về performance so với LinkedList (do phải xử lý cái backed array). Tất nhiên là performance của hệ thống thì ko thể dựa hoàn toàn trên tính toán định tính, mà cần dựa trên các công cụ monitor với con số cụ thể.
Nếu là môi trường multi-thread thì nên dùng CopyOnWriteArrayList, lý do là nó đảm bảo thread-safe trong khi implement của hàm read() trong mô hình CopyOnWrite nó ko đòi hỏi phải sử dụng lock.
OK, vậy là sau khi tổng hợp đủ các thông tin cần thiết, team đã xây dựng thành 1 bộ đề phỏng vấn bao gồm câu hỏi và đáp án. Y chang kiểu bộ đề tuyển sinh đại học.
Công việc tiếp theo là trao bộ đề lại cho 1 thanh niên thứ 3 đi phỏng vấn, và cầu mong cho ông cụ hỏi đúng câu cũ.
Ứng viên thứ 3 có English khá tốt, bộ đề, đáp án đã được bàn giao và đọc trước. Khác với lần phỏng vấn trước, lần này có đầy đủ ban bệ lãnh đạo có mặt. Vì xác định lần này tạch thì coi như mất dự án, anh em treo niêu.
Anh em đã làm hết sức mình, còn lại trông chờ vào kĩ năng chém gió của ứng viên. Nghe nói, ngoài tổ tư vấn, tổ kỹ thuật, em manager tối còn phải đốt hương khấn vái tổ tâm linh.
Đồng hồ dịch chuyển dần đến giờ phỏng vấn 9:30, mọi người hồi hộp chờ đợi….
Lại bác Director of Software engineering xuất hiện, nụ cười hiền từ.
Câu hỏi thứ nhất
Câu 1) Viết code ví dụ về Singleton class
Câu 2) Viết code đảo chiều chuỗi…
Câu 3) ….
Cô thương. Đúng là kiếp trước ăn ở tốt, trời phật phù hộ độ trì, các câu hỏi y chang. Kết quả thế nào đã rõ…
Cảm xúc vỡ òa, đúng là bạc già không bằng gà son
Kết luận
Các cụ ngày xưa đã nói rằng “Người thất bại là người bỏ cuộc”, người chiến thắng là người không từ bỏ. Đôi khi thành công đến được còn cần 1 chút may mắn. Nhưng may mắn chỉ có được khi bạn đã cố gắng hết sức của mình. Thành công của người này có được có thể phải đánh đổi bằng sự hi sinh của người khác, nhưng đều dành cho mục đích chung.
Nguồn: http://www.giaosucan.com/
GIAOSUCAN’S BLOG – CHIA SẺ KIẾN THỨC KĨ THUẬT THEO CÁCH BÁ ĐẠO
Post Comment