Bản gốc:
Tác giả gốc: John Washam
Đóng góp cho bản dịch tiếng Việt:
Ghi chú riêng cho việc duy trì và cập nhật bản dịch tiếng Việt:
Bản dịch này nhằm mục đích khuyến khích các bạn trẻ yêu thích công nghệ nhưng chưa vững tiếng Anh dễ tiếp cận, và tìm được hướng nghiên cứu. Để đi xa hơn trong ngành công nghệ thông tin (CNTT), sớm hay muộn, bạn cũng cần phải trau dồi vốn tiếng Anh của mình. Vì vậy, các thuật ngữ chuyên ngành, mình xin được giữ nguyên gốc. Ví dụ như: stack
, heap
, queue
,...
Mình cố gắng dịch thoát nghĩa, sao cho các bạn với ít kiến thức công nghệ thông tin nhất cũng có thể hiểu được. Trong quá trình dịch khó có thể trách khỏi sai sót, xin được lượng thứ.
Mọi ý kiến, đóng góp về bản dịch, vui lòng tạo một issue mới hoặc bạn có thể chỉnh sửa và tạo Pull Request, đồng thời cc trực tiếp các dịch giả để kiểm tra.
Đây là kế hoạch học tập trong nhiều tháng của tôi, để từ một nhà phát triển web (tự học, không có bằng cấp về Khoa Học Máy Tính - KHMT) trở thành một kỹ sư phần mềm ở Google.
Danh sách dài này được trích và mở rộng từ Ghi chú huấn luyện của Google, vậy nên đây là những gì bạn cần biết. Một vài mục tôi thêm vào ở cuối danh sách có thể xuất hiện trong cuộc phỏng vấn hoặc hữu ích cho việc giải quyết các bài toán. Nhiều mục đến từ bài viết Lấy được việc ở Google (Get that job at Google)" của Steve Yegge.
Tôi lược bớt những gì bạn cần từ lời khuyên của yegge. Tôi cũng chỉnh sửa lại các yêu cầu dựa trên thông tin tôi có được từ bạn bè ở Google. Danh sách này được thiết kế cho Kỹ sư phần mềm hoặc những ai chuyển từ phát triển web hoặc phần mềm sang kỹ nghệ phần mềm (khi mà kiến thức về Khoa Học Máy Tính là bắt buộc). Nếu bạn có nhiều kinh nghiệm và muốn khẳng định nhiều năm trong đó bạn làm việc như một kỹ sư phần mềm, hãy sẵn sàng cho một buổi phòng vấn khó hơn. Xem thêm ở đây.
Nếu bạn có kinh nghiệm trong phát triển web hoặc ứng dụng, hãy chú ý rằng Google xem việc xây dựng phần mềm khác với web và ứng dụng thông thường. Họ yêu cầu kiến thức về Khoa Học Máy Tính.
Thêm vào đó, nếu bạn muốn trở thành một kỹ sư hệ thống (System Engineer), hãy học thêm từ danh sách bổ sung (mạng máy tính, bảo mật,...)
---------------- Everything below this point is optional ----------------
Tôi đang chuẩn bị tham gia phỏng vấn ở Google. Tôi từng làm web, xây dựng các dịch vụ và lập các công ty khởi nghiệp từ năm 1997. Tôi có bằng Kinh Tế, nhưng không có bằng Khoa Học Máy Yính. Tôi thấy sự nghiệp của mình khá thành công, nhưng như thế chưa đủ. Tôi muốn làm việc ở Google, được tham gia xử lý một hệ thống lớn; thực sự hiểu rõ về máy tính, sự hiệu quả của các thuật toán và cấu trúc dự liệu, các ngôn ngữ lập trình cấp thấp, và chúng hoạt động cùng nhau như thế nào. Và nếu bạn không biết về cái nào trong số đó, Google sẽ không tuyển bạn.
Khi tôi bắt đầu dự án này, tôi không phân biệt được stack và heap, không biết về Big-O, không có khái niệm gì về cây (tree
) hay việc duyệt đồ thị (graph traversal
). Và nếu buộc phải viết code cho một thuật toán sắp xếp, tôi đảm bảo rằng nó sẽ không chạy tốt.
Tất cả các cấu trúc dự liệu tôi từng sử dụng đều được cài đặt sẵn trong ngôn ngữ lập trình và tôi không nhất thiết phải biết chúng làm việc như thế nào. Tôi chưa từng phải tự quản lý vùng nhớ, trừ khi một tiến trình đang chạy ném lỗi "hết bộ nhớ" (out of memory
), và sau đó tôi phải tìm một cách giải quyết khác. Tồi từng sử dụng mảng nhiều chiều vài lần trong đời, và hàng ngàn mảng kết hợp (associate arrays
). Nhưng thực sự tôi chưa từng tự mình xây dựng một cấu trúc dữ liệu nào.
Nhưng, sau khi trải qua dự án này, tôi rất tự tin rằng mình sẽ được tuyển. Đây là một dự án dài hơi, sẽ tốn của tôi hàng tháng. Nếu bạn đã quen với nhiều nội dung trong này, bạn sẽ mất ít thời gian hơn.
Phần này được viết lại khá nhiều để thuận tiện cho các bạn tiếp cận. Dựa theo bản gốc, tác giả có vẻ như cũng đang cố hướng dẫn cho người mới dùng git.
Bạn có thể bỏ qua mục này nếu đã có kiến thức về Git, Github và Github Flavored Markdown
Nếu bạn chưa biết về git thì vui lòng tham khảo các bài hướng dẫn sau để nắm cách sử dụng:
Tiếp theo, bạn cần biết cách fork một repo trên github (Mình không tìm được hướng dẫn tiếng Việt nào thích hợp.)
Ok, bây giờ bạn có thể bắt đầu:
Clone bản fork của bạn về máy tính cá nhân.
git clone https://github.com/<your-username>/google-interview-university
Chạy các dòng lệnh sau
Tạo một branch mới để đánh dấu tiến độ của bạn:
git checkout -b progress
Check các phần đã hoàn thành bằng cách thêm x
vào giữa cặp ngoặc vuông ([ ]
), như thế này: [x]
.
Chạy git add .
để bắt đầu lưu lại các thay đổi.
Chạy git commit -m "commit message"
. Thay commit message
với ghi chú của bạn cho sự thay đổi đó.
Đồng bộ thay đổi với bản fork trên Github của bạn bằng git push origin master
.
In một (hay vài cái cũng được) đề can "future Googler" và để nó (chúng) ở đâu đó mà bạn luôn nhìn thấy và nghĩ đến được.
Tôi đang ở trong hàng đợi. Hy vọng sẽ sớm đến lược phỏng vấn.
Cảm ơn vì đồng ý giới thiệu tôi, JP.
Tôi cũng đang đi trên con đường này. Hãy cùng xem chúng ta đi được đến đâu:
Các kỹ sư của Google là những người xuất sắc, nhưng nhiều người vẫn cho rằng họ không đủ thông minh, mặc dù họ đang làm việc tại Google.
Bí mật của của Thiên Tài Lập Trình (The myth of the Genius Programmer) - video
ulie Pagano: Đi một mình rất nguy hiểm - Cuộc chiến với con quái vật vô hình trong công nghệ
Một vài video chỉ xem được khi bạn tham gia vào các lớp học online trên Coursera, EdX, hay Lynda.com. Các lớp đó được gọi là MOOC. Đôi khi các lớp không có sẵn, và bạn phải đợi một vài tháng đến khi chúng được mở lại, do đó bạn không thể truy cập vào video được. Lynda.com thì không miễn phí.
Tôi sẽ rất cảm kích sự hỗ trợ của các bạn trong việc thêm các nguồn video miễn phí và luôn sẵn có, ví dụ như Youtube, để hỗ trợ nguồn video từ các khóa học online.
Tôi cũng rất thích xem các bài giảng của các trường đại học.
[ ] Videos:
[ ] Bài viết:
[ ] Các khóa chuẩn bị:
[ ] Bổ sung (không được đề xuất từ Google, nhưng tôi vẫn thêm vào):
Tôi viết bài báo ngắn về điêu này: Quan trọng: Chọn ngôn ngữ lập trình cho phỏng vấn ớ Google
Bạn có thể chọn ngôn ngữ mà bạn quen thuộc để thực hiện phần viết mã trong lúc phỏng vấn, nhưng với Google, những ngôn ngữ sau đây là thích hợp nhất:
Bạn cũng có thể sử dụng các ngôn ngữ sau đây, nhưng hãy tìm hiểu thêm trước. Chúng có thể có bất lợi:
Dù sao, bạn cũng cần phải rất quen thuộc với ngôn ngử lập trình của mình.
Xem thêm về các sự lựa chọn:
Xem tài liệu về các ngôn ngữ ở đây
Bạn sẽ thấy vài tài liệu về C, C++ và Python bên dưới, vì tôi đang học chúng. Ngoài ra còn có một vài đầu sách nữa, xem ở cuối.
Đây là danh sách rút gọn từ những gì mà tôi đọc, để tiết kiệm thời gian cho bạn.
Tên sách được giữ nguyên gốc tiếng Anh.
Nếu bạn có nhiều thời gian hơn nữa:
Nếu không có nhiều thời gian:
Nếu bạn có nhiều thời gian (tôi đã muốn đọc quyển này):
Bạn phải chọn một ngôn ngữ cho cuộc phỏng vấn (xem ở trên). Đây là các khuyến nghị của tôi. Tôi không có tài liệu cho tất cả các ngôn ngữ lập trình, vậy nên, đóng góp từ bạn luôn được chào đón.
Nếu bạn muốn đọc xuyên suốt một trong những quyển sách này, bạn nên có kiến thức về cấu trúc dữ liệu và giải thuật. Bạn cũng nên luyện tập giải toán lập trình.
Bạn có thể bỏ qua bài giảng video trong project này, trừ khi bạn muốn tự đánh giá lại kiến thức của mình.
Đây là tài liệu ngôn ngữ lập trình bổ sung.
Tôi chưa đọc 2 cuốn này, nhưng chúng được đánh giá cao, và được viết bởi Sedgewick. Giáo sư Sedgewick rất xuất sắc.
Nếu bạn có đề xuất nào tốt hơn cho C++, hãy cho tôi biết. Tôi đang tìm một tài liệu súc tích.
hoặc:
Một vài người đề xuất mấy quyển này, nhưng tôi nghĩ chúng là quá nặng, trừ khi bạn có nhiều kinh nghiệm với kỹ nghệ phần mềm và đang mong đợi một cuộc phỏng vấn khó hơn nhiều:
[ ] Algorithm Design Manual (Skiena)
[ ] Introduction to Algorithms - Chú ý: Đọc cuốn này chỉ có một ít giá trị. Đây là một tổng hợp xuất sắc về giải thuật và cấu trúc dữ liệu, nhưng nó không dạy cho bạn cách viết code xuất sắc. Để làm một lập trình viên giỏi, bạn đồng thời phải có khả năng phát triển một giải pháp một cách hiệu quả nữa.
"Algorithms and Programming: Problems and Solutions" by Shen
- Sách tạm được, nhưng sau khi làm việc với các bài toán trong vài trang, tôi thấy nhức đầu với ngôn ngữ Pascal, do-while loop, mảng bắt đầu với số 1 (thay vì 0 như Java, C, C++, ...), và một vài thông tin không rõ ràng.
Danh sách này ngày càng dài theo năm tháng và tôi phải thừa nhận là nó ngoài tầm kiểm soát.
Sau đây là 1 vài lỗi tôi đã mắc phải, hy vọng rằng có thể mang lại cho bạn một chút kinh nghiệm.
Tôi đã xem hàng giờ video và viết rất nhiều ghi chú, và chỉ sau vài tháng không còn nhớ chút gì. Tôi đã bỏ ra 3 ngày đọc lại các ghi chú và làm thẻ ghi nhớ để có thể đọc dễ dàng hơn.
Hãy đọc để tránh phạm phải sai lầm tương tự:
Retaining Computer Science Knowledge
Để giải quyết vấn đề, tôi đã viết 1 trang web nhỏ về thẻ ghi nhớ để thêm các thẻ mới với 2 dạng chính: kiến thức chung và code. Mỗi loại có định dạng riêng.
Tôi đã làm một trang mobile-first (lấy mobile là trọng tâm phát triển trang web) để có thể xem trên điện thoại và máy tính bảng, ở bất cứ đâu.
Tự tạo cho mình hoàn toàn miễn phí:
Ghi chú dành cho các thẻ ghi nhớ: The first time you recognize you know the answer, don't mark it as known. Lần đầu tiên bạn nhận ra bạn biết câu trả lời, đừng đánh dấu là đã biết.Bạn phải xem thẻ tương tự và đưa ra câu trả lời chính xác vài lần trước khi bạn thực sự khẳng định đã nắm được vấn đề.Lặp đi lặp lại việc này sẽ giúp kiến thức được khắc sâu vào não bạn.
Có thể thay thế thẻ ghi nhớ với Anki, đây là ứng dụng mà bạn sẽ thấy tôi khuyến khích sử dụng rất nhiều lần. Nó sử dụng một hệ thống lặp để giúp bạn có thể ghi nhớ được kiến thức.
Đây là ứng dụng cực kì thân thiện với người dùng, có mặt trên tất cả các hệ điều hành, và có hệ thống lưu trữ đồng bộ đám mây. Tốn khoản 25$ cho iOS nhưng miễn phí trên các hệ điều hành khác.
Cơ sỏ dữ liệu thẻ ghi nhớ của tôi tuân theo chuẩn định dạng của Anki: https://ankiweb.net/shared/info/25173560 (cảm ơn @xiewenya)
Tôi giữ một danh sách xem nhanh các mã của ASCII, OSI stack, định nghĩa về Big-O, và nhiều hơn nữa. Tôi đọc bất cứ khi nào rảnh rỗi.
Khi gặp vấn đề trong lúc code, nghỉ ngơi chừng nửa giờ và đọc lại các thẻ ghi nhớ.
Có rất nhiều thứ lấy đi sự tập trung của ta, việc này tốn rất nhiều thời gian. Tập trung và toàn tâm toàn ý rất khó.
Danh sách lớn này bắt đầu như một bản To-do lược trích từ Huấn luyện phỏng vấn cho Google. Có vài công nghệ đang thịnh hành nhưng không được đề cập đến, ví dụ:
Một vài môn học chỉ mất một ngày, vài môn khác có thể mất nhiều ngày. Có vài môn chỉ có thể học thôi chứ không cài đặt được gì.
Mỗi ngày tôi sẽ chọn một trong các thứ liệt kê bên dưới, xem video bải giảng về nó, và viết mã trên:
struct
và các hàm nhận các struct
đó cùng với các tham số khác.std::list
cho danh sách liên kết.assert()
đơn giản.Bạn không cần luyện tất cả các ngôn ngữ đó. Chỉ cần một ngôn ngữ cho cuộc phỏng vấn là đủ.
Tại sao lại viết mã với tất cả các ngôn ngữ đó?
Tôi có lẽ không đủ thời gian để thử hết tất cả các bước trên với từng chủ đề, nhưng tôi sẽ cố.
Bạn có thể xem code của tôi ở các trang sau:
Bạn không cần phải ghi nhớ cặn kẽ từ giải thuật.
Hãy viết code trên bảng đen hoặc trên giấy. Đừng sử dụng máy tính. Chạy thử trên giấy với vài bộ dữ liệu mẫu, sau đó chạy thử thuật tóan của bạn trên một máy tính.
[ ] Học C
[ ] Máy tính thực thi một chương trình như thế nào?
[ ] Cheat sheet
Nếu một vài bài học quá chuyên sâu về toán, bạn có thể nhảy cóc tới các bài toán riêng lẻ để có kiến thức toàn diện hơn.
- Cấp phát mảng vector tự động tùy biến kích cỡ.
[ ] Video:
[ ] Các khóa học online:
- [ ] Cài đặt với mảng sử dụng thăm dò tuyến tính:
- hash(k, m) - m là kích thước của bảng băm
- add(key, value) - nếu khóa đã tồn tại, cập nhật giá trị
- exists(key)
- get(key)
- remove(key)
queue
)
Độ phức tạp thời gian: O(n)
Độ phức tạp không gian: tốt nhất: O(1), tệ nhất: O(n/2)=O(n)BST: Binary search tree - cây tìm kiếm nhị phân.
stack
và heap
- video[ ] Cài đặt:
insert
// thêm gíá trị vào câyget_node_count
// lấy số lượng nút trong câyprint_values
// In ra gíá trị trong cây, từ nhỏ nhất đến lớn nhấtdelete_tree
// Xóa câyis_in_tree
// cho biết gíá trị cho trước có tồn tại trong cây hay khôngget_height
// cho biết chiều cao của câyget_min
// cho biết giá trị nhỏ nhất trong câyget_max
// cho biết giá trị lớn nhất trong câyis_binary_search_tree
// kiểm tra xem cây cho trước có thỏa mãn điều kiện của một BST không.delete_value
// xóa một gíá trị trong câyget_successor
// Trả về phần tử cao nhất trong cây liền sau một gíá trị cho trước hoặc -1 nếu không tìm đượcO(n)
insert
sift_up
- cần thiết cho hàm insert
.get_max
- trả về phần tử lớn nhất mà không xóa nó khỏi heapget_size()
- trả về số lượng các phần từ trong một heapis_empty()
- trả về true
nếu heap rỗngextract_max
- trà về phần tử lớn nhất và đồng thời xóa nó khỏi heapsift_down
- cần thiết cho hàm extract_max
remove(i)
- xóa phần tử tại một vị trí i
cho trướcheapify
- tạo một heap từ một mảng các phần tử, cần thiết cho hàm heap_sort
heap_sort()
- nhận vào một mảng chưa sắp xếp, sắp xếp nó tại chỗ (không tốn thêm bộ nhớ) bằng một kỹ thuật sử dụng heap
In progress