Hậu quả từ những trường trọng Java

Manh

March 19, 2016

Bài dịch

Tác giả: Joel Spolsky

Joel Spolsky là Co-founder sáng lập ra Stack Overflow vào năm 2008, hiện nay anh là CEO của Stack Exchange.

Thông tin thêm: http://www.joelonsoftware.com/AboutMe.html

Bài gốc: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html

Mấy chàng lười.

Có điều gì đó đã xảy ra với tính chuyên cần.

“Người ta quả là may mắn. Chúng tôi từng sống 3 tháng bên trong túi giấy nâu trong một hố vệ sinh tự hoại. Chúng tôi thức dậy lúc 6 giờ sáng, dọn dẹp túi giấy, ăn cái vỏ ngoài của đống bánh mỳ hỏng rồi xuống cối xay làm việc, 14 tiếng một ngày, tuần nào cũng như tuần nào, và đến lúc chúng tôi về nhà thì Cha của chúng tôi sẽ cho ngủ cùng với trận đòn bằng thắt lưng của ông ấy luôn.” – Trích “Gánh xiếc bay của Monty Python”, vở kịch Four Yorkshiremen.

Một dấu hiệu hiển nhiên cho cái tính già cỗi của tôi đang tiến đến đó là tỏ ra cực đoan và càu nhàu về “lũ trẻ thời nay”, và chuyện là chúng sẽ không làm và cũng không thể làm những điều khó khăn một chút nào nữa.

Hồi còn nhỏ, tôi học lập trình bằng những cái phiếu đục lỗ (https://en.wikipedia.org/wiki/Punched_card). Nếu như làm sai, sẽ không có những thứ như nút Backspace để xóa đi và sửa lại nó như thời nay. Bạn quăng cái phiếu đi và làm lại từ đầu.

Khi tôi bắt đầu phỏng vấn các lập trình viên vào năm 1991, tôi để cho họ chọn bất cứ ngôn ngữ lập trình nào để giải quyết các vấn đề tôi giao cho họ. 99% những lần tôi hỏi, họ đều chọn C.

Giờ thì họ chuyển hướng sang chọn Java.

Ngay giờ thì bạn đừng hiểu nhầm tôi, chọn Java là một ngôn ngữ để hoàn thành công việc không có gì là sai cả.

Nhưng đợi chút, tôi muốn sửa lại câu đó. Tôi không định nói rằng, trong bài viết này, tôi nói đến các vấn đề không đúng khi chọn Java. Có rất nhiều vấn đề nhưng chắc là nên viết trong một bài khác.

Thay vào đó tôi muốn khẳng định rằng Java không phải, đại khái là, một ngôn ngữ lập trình đủ độ khó để sử dụng mà phân biệt giữa các lập trình viên giỏi và các lập trình viên cẩu thả. Nó là một ngôn ngữ rất ổn để làm việc, nhưng cũng không phải là vấn đề hiện tại đang cần quan tâm. Thậm chí tôi muốn nói kỹ hơn rằng Java không khó thì đó là đặc điểm của nó, không phải là khuyết điểm, nhưng nó có một vấn đề sau đây.

Nếu như tôi thật là trơ tráo, nó cũng là từ kinh nghiệm nhỏ nhoi của tôi rằng có 2 thứ phổ biến được dạy trong các trường đại học cho ngành Khoa học Máy tính (KHMT) mà rất nhiều người chẳng bao giờ thực sự hiểu, đó là Con trỏ và Đệ quy.

Bạn từng bắt đầu học trong đại học với một môn về Cấu trúc Dữ liệu (CTDL), gồm Danh sách liên kết và Bảng băm cộng với vài thứ khác, và thường xuyên sử dụng đến Con trỏ. Những môn học như vậy thường được dùng làm các môn để loại bỏ: nó khó đến nỗi mà những ai không thể vượt qua những thử thách tinh thần của ngành KHMT thì sẽ bỏ cuộc, điều này là tốt, bởi nếu bạn mà nghĩ Con trỏ khó, thì cứ đợi đến lúc phải chứng minh những thứ về Lý thuyết Rời rạc mà xem.

Tất cả những học sinh giỏi ở phổ thông mà viết được trò Pong bằng BASIC trên máy Apple II sẽ vào đại học và chọn khóa CompSci 101 (Nhập môn KHMT), thêm một khóa CTDL, và đến khi họ gặp con trỏ thì như bị loạn óc, và điều tiếp theo bạn sẽ biết là họ chuyển sang ngành Chính trị học (Khoa học Chính trị) bởi các trường Luật có vẻ ngon hơn. Tôi đã thấy đủ loại số liệu về việc bỏ giở ngành KHMT và nó thường ở  40% đến 70%. Các trường đại học thì nghiêng về việc nghĩ đây là một tổn thất, cá nhân tôi cho rằng đó chỉ là việc loại bỏ cần thiết cho những người sẽ không cảm thấy vui hoặc sẽ không thành công với nghiệp lập trình.

Một môn học khó khác dành cho các sinh viên KHMT trẻ tuổi là môn về lập trình hàm, bao gồm cả lập trình đệ quy. MIT yêu cầu rất cao cho những môn như thế này, đặt thêm một môn điều kiện, mã môn 6.001 (môn Cấu trúc và lối thông dịch của chương trình máy tính – http://sicp.csail.mit.edu/Fall-2005/) cùng một cuốn sách của Abelson & Sussman về vấn đề này (https://mitpress.mit.edu/sicp/full-text/book/book.html). Điều này cũng có mặt ở hàng tá trường, thậm chí hàng trăm trường danh tiếng về KHMT, suy ra từ thực thế thì nó chính là Nhập môn cho KHMT. (Bạn vẫn có thể, và nên xem lại những bài giảng thời ấy ở trên mạng: http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/)

Độ khó của những môn này thì thật là rực rỡ. Trong bài đầu tiên bạn đã phải học hầu hết mọi thứ về Scheme, và đã chuẩn bị được dạy về hàm số rời rạc. Khi mà tôi vật vã qua cái một cái môn như môn CSE121 (Ngôn ngữ Lập trình và Kỹ thuật lập trình) ở Penn (University of Pennsylvania) , tôi chứng kiến rất nhiều, nếu như không phải là toàn bộ các học sinh đều không thể vượt qua. Nội dung học quá khó. Tôi đã viết một bức thư kể khổ với Giảng viên nói rằng “Thật là không công bằng”. Và ai đó ở Penn hẳn là đã nghe lời tôi (hoặc ai đó cũng đi phàn nàn), bởi giờ thì cái môn đó được dạy bằng Java.

Giá mà họ đừng nghe những lời phàn nàn.

Và cũng có nhiều tranh cãi. Hàng năm trời ca thán của những sinh viên KHMT lười nhác như tôi, cộng với trong ngành phàn nàn rằng những chuyên gia KHMT tốt nghiệp từ các trường của Mỹ ít đến mức nào, đã đánh lên một tiếng chuông, và trong 10 năm trở lại đây thì một lượng lớn các trường tuy rất tốt nhưng cũng đã chạy theo 100% Java. Đó là chạy theo xu hướng, và những nhà tuyển dụng chuyên dùng “grep” để đánh giá những hồ sơ việc làm rất là thích thú (grep là một câu lệnh tìm kiếm trên của Linux (Unix), ý bảo những ông này nhìn thấy trong hồ sơ liệt kê ra giống các tiêu chí mình cần thì sẽ đánh giá cao hồ sơ đó, phương pháp tuyển dụng ngây thơ), và, hay hơn là, chả có gì khó khăn về Java để loại đi những lập trình viên mà trong đầu không cái phần não làm việc về Con trỏ và Đệ quy, nên tỉ lệ bỏ ngành thấp hơn, Khoa KHMT của trường có nhiều sinh viên hơn, lợi nhuận lớn hơn, và mọi thứ nó tốt đẹp.

Bạn nghĩ rằng mình đủ những thứ cần thiết, thử test xem: http://www.joelonsoftware.com/articles/TestYourself.html

(Tài liệu trong này đã cũ, tác giả khuyến cáo cần cân nhắc kỹ khi dùng)

Những chàng gặp hên của những trường trọng Java sẽ chả bao giờ gặp những segfault lạ lẫm khi đang cài đặt một bảng băm bằng con trỏ. Họ sẽ chẳng bao giờ trở nên hoàn toàn điên loạn để cố đưa dữ liệu của mình vào trong các bit. Họ sẽ chẳng bao giờ phải vắt óc ra mà nghĩ rằng tại sao, trong một chương trình hàm thuần túy, giá trị của các biến không hề thay đổi, mà nó vẫn luôn thay đổi mọi lúc! Thật là nghịch lý!

Họ không cần phần não đó để được 4 điểm chuyên ngành.

Có phải tôi chỉ là một thằng cổ lỗ xấu tính, như những người trong Four Yorkshiremen, khoác lác về việc mình đã vượt qua tất cả những trở ngại khó khăn như thế nào.

Tào lao, năm 1900, Tiếng La-tinh và Tiếng Hy-lạp là các môn bắt buộc ở đại học, chả phải vì nó phục vụ cho một mục đích nào cả, mà nó như là yêu cầu bắt buộc để đánh giá những người có học hành. Theo tôi, trong một vài trường hợp, chẳng có khác biệt nào giữa những phát biểu từ người giỏi tiếng La-tinh (cả 4 người đó) (Ý nói người Giỏi La-tinh, dốt tiếng Hy-lạp và ngược lại, dốt cả 2 tiếng và giỏi cả 2 tiếng).

“Tiếng La-tinh rèn luyện suy luận và trí nhớ cho bạn. Hiểu rõ được một câu La-tinh là một bài tập xuất sắc cho suy nghĩ, là một câu nói trí tuệ thực sự, và cũng là một điều tốt để hướng tới suy nghĩ lô-gic” – Trích Scott Barker. Nhưng giờ không có trường nào bắt buộc học tiếng inh nữa. Con trỏ và Đệ quy có phải nó như tiếng La-tinh và Hy-lạp của KHMT hay không?

Hiện tại, tôi thoải mái thừa nhận rằng lập trình với con trỏ là không cần thiết trong 90% các dòng code được việt hiện nay, và thực tế đúng là nó không tốt cho production code (mã nguồn đạt quy chuẩn công nghiệp). OK. Điều đó đúng. Và cả lập trình hàm cũng chả mấy khi được sử dụng trong thực tế. Đồng ý.

Nhưng nó vẫn quan trong cho một số công việc lập trình thú vị nhất. Không biết con trỏ, ví dụ, bạn không bao giờ có thể làm việc với Linux kernel (mã nguồn Linux viết bằng lập trình C). Bạn không thể hiểu nổi một dòng code của Linux, mà thật ra là mọi loại hệ điều hành, mà không thực sự hiểu con trỏ.

Nếu không có lập trình hàm, bạn không thể làm ra MapReduce (http://research.google.com/archive/mapreduce.html), thuật toán làm cho Google vượt bậc cực kỳ xa. Các khái niệm Map và Reduce là đến từ Lisp và lập trình hàm. MapReduce là, tôi nhớ lại, và cũng như mọi người sẽ hiểu nếu còn nhớ từ môn 6.001 – nó tương tự như class trong lập trình mà các chương trình hàm thuẩn túy không có một tác nhân phụ nào, do đó có thể song song hóa ít trở ngại. Sự thật chính là Google phát minh ra MapReduce, mà Microsoft thì không, thử nói về việc tại sao Microsft vẫn còn đang cố dựng cho được những tính năng tìm kiếm đơn giản để có thể chạy được, trong khi Google đã chuyển sang vấn đề tiếp theo: xây dựng Skynet, một siêu máy tính song song lớn nhất thế giới. Tôi không nghĩ là Microsoft hoàn toàn hiểu được họ đã bị bỏ xa như thế nào trong cuộc đua này.

Nhưng đàng sau tầm quan trọng bạn vừa mới biết được của Con trỏ và Đệ quy, giá trị thực sự của chúng là khi xây dựng một hệ thống lớn yêu cầu những kỹ năng mà bạn học được từ chúng, và tinh thần của bạn cần phải tránh bị rớt môn mà những thứ này được dạy trong môn đó. Con trỏ và Đệ quy là một khả năng nhất định để suy luận, để tư duy theo trừu tượng, và, quan trọng nhất là để nhìn một vấn đề ở nhiều cấp độ trừu tượng một cách đồng thời. Vậy nên, khả năng hiểu về Con trỏ và Đệ quy của bạn nó liên quan trực tiếp đến khả năng mà bạn sẽ trở thành một lập trình viên tài giỏi.

Chẳng có gì cho một chương trình KHMT toàn Java có thể loại đi những sinh viên thiếu năng lực tinh thần để giải quyết những khái niệm này. Là một nhà tuyển dụng, tôi thấy rằng những trường 100% dạy các khóa học bằng Java đang băt đầu tạo ra lượng kha khá sinh viên tốt nghiệp KHMT không đủ thông minh để lập trình ra cái gì phức tạp hơn một chương trình Kế toán bằng Java, mặc dù họ có thể gắng chém gió ra vài thứ về mấy môn mà tôi vừa nói. Những sinh viên này sẽ không bao giờ trụ trụ nổi môn 6.001 ở MIT, hoặc CS 323 ở Yale (Nhập môn Lập trình Hệ thống và Kiến trúc Máy tính), thẳng thắn mà nói, đó là một lý do tại sao, là một nhà tuyển dụng, một tấm bằng KHMT của MIT hay Yale nó có trọng lượng hơn từ Duke hoặc từ Penn, trường mà đã thay Scheme và ML bằng Java để nỗ lực dạy cái môn mà gần như suýt giết chết tôi và bạn tôi, môn CSE 121. Không phải tôi không muốn thuê những người thông minh từ Duke và Penn, tôi muốn, chỉ là nó rất khó cho tôi để xác định được rõ họ thực sự là như thế nào. Tôi từng bảo rằng người thông minh thì họ có thể hiểu rõ một thuật toán đệ quy sau vài giây, hoặc cài đặt được một hàm tạo ra các Danh sách liên kết bằng con trỏ nhanh như họ có thể viết trên bảng. Nhưng với những người tốt nghiệp từ các trường trọng Java, tôi không biết được rằng họ chật vật trước những vấn đề này là do thất học hay là do thật sự là họ không có cái phần não mà họ sẽ cần để lập trình ra những thứ tuyệt vời. Paul Graham gọi họ là “những lập trình viên lơ mơ.

(Blub Programmers: http://www.paulgraham.com/avg.html)

Nhưng các trường trọng Java cũng còn thất bại trong việc rèn luyện cho trí não của sinh viên trở nên lão luyện, nhanh nhẹn và linh hoạt đủ để tạo ra thiết kế phần mềm tốt (và ý của tôi cũng chưa phải là thiết kế theo hướng đối tượng, trong khi bạn bỏ ra hàng giờ viết đi viết lại code của mình để “lúc lắc” cái hệ thống object của bạn, hoặc là cứ băn khoăn mãi về các vấn đề mô phỏng ví dụ như nó là một thứ hay nó sở hữu một thứ).

Chắc bạn đang tự hỏi rằng dạy OOP là một yếu tố để loại bớt thay thế cho Con trỏ và Đệ quy. Trả lời nhanh luôn là không phải. Thảo luận về OOP mà không nói đến các điểm mạnh của OOP thì không đủ độ khó để loại đi các lập trình viên kém cỏi. OOP trong trường học chỉ là học thuộc một mớ khái niệm như Tính đóng gói và Tính thừa kế và dùng những câu hỏi lựa chọn về sự khác nhau của Đa hình và Tái định nghĩa. Chả khó hơn việc nhớ những thời điểm và những cái tên nổi tiếng của môn Lịch sử, nên OOP không đủ thử thách cho các cậu năm nhất. Khi bạn vật lộn với vấn đề của OOP, chương trình của bạn thì vẫn chạy, có điều là nó rất khó để bảo trì. Giả sử là vậy. Nhưng nếu có vấn đề về con trỏ, chương trình in ra dòng Segmentation Fault và bạn chả biết được rằng điều gì đang xảy ra, cho đến khi bạn dừng lại và hít một hơi thật sâu để thực sự bảo trí não của mình hoạt động ở 2 mức trừu lượng cùng một lúc.

Tiện thể, về những nhà tuyển dụng dùng grep, bị tôi chế nhạo ở đây, cũng vì mục đích tốt thôi. Tôi chưa bao giờ thấy một người có thể dùng Scheme, Haskell, và Con trỏ C mà lại không thể học Java trong 2 ngày, và còn code Java tốt hơn người đã có 5 năm kinh nghiệm (với Java), nhưng mà cứ thử giải thích điều này cho mấy lão làm biếng phòng Nhân sự xem.

Nhưng Khoa KHMT của trường cũng phải có trách nhiệm chứ? Các trường đó không phải là những trường dạy nghề! Việc rèn luyện con người để làm việc cho công nghiệp không phải của họ. Điều đó dành cho các trường cộng đồng và những chương trình đào tạo lại nhân lực của nhà nước dành cho những người thất nghiệp (thất nghiệp này là do rủi ro công ty, phá sản,…). Đó là những gì họ sẽ nói với bạn. Nhiệm vụ của họ là đưa cho sinh viên những công cụ căn bản, không phải là để chuẩn bị cho tuần làm việc đầu tiên của họ, đúng không?

Vẫn có. KHMT là các thử nghiệm (đệ quy), các thuật toán (đệ quy), ngôn ngữ lập trình (giải tích lambda), hệ điều hành (con trỏ), trình biên dịch (giải tích lambda), và những trường Java mà không dạy C và Scheme thì không thực sự dạy được KHMT. Cũng vô ích như khái niệm về Function Currying (https://en.wikipedia.org/wiki/Currying) với thế giới thực, nhưng nó là điều tiên quyết cho một sinh viên tốt nghiệp KHMT. Tôi không thể hiểu tại sao  các giáo sư trong hội đồng chương trình ở các trường dạy KHMT lại để cho giáo trình của họ bị hạ xuống đến một mức mà vừa không thể tạo ra được những lập trình viên có thể sử dụng được, mà cũng không thể tạo ra sinh viên KHMT có khả năng sẽ đạt được PhD (tương đương tiến sỹ của VN) và cạnh tranh trong công việc của họ. Ồ mà đợi chút. Chắc khỏi bận tâm. Có lẽ tôi cũng hiểu được rồi.

Thật ra nếu bạn quay lại và nghiên cứu cuộc thảo luận ở một học viện về vấn đề “Một bước tiến vào Java”, bạn sẽ nhận ra mối quan tâm lớn nhất đó là Java có đủ đơn giản để dạy hay không.

Trời ạ, tôi nghĩ, họ đang muốn phá đi cái chương trình học hơn nữa! Sao không đến tận nơi mớm sẵn toàn bộ cho sinh viên luôn? Cho cả trợ giảng làm hộ bài kiểm tra nữa, rồi sẽ chẳng ai chuyển đến Mỹ học. Làm sao để một người có thể học được chút gì nếu như chương trình đã bị thiết kế lại để cho mọi thứ dễ hơn mặc dù nó đã vốn dễ? Hình như là có một lực lượng đặc biệt nào đó đang tìm ra những phần đơn giản của Java để dạy cho sinh viên, tạo ra những tài liệu tối giản để che đi những thứ vớ vẩn của EJB/J2EE từ chính cái tư duy dễ tự ái của chúng, và chúng không cần phải lo cho cái đầu nhỏ bé của mình vì môn nào cũng làm những bài tập chưa bao giờ dễ hơn.

Lý do đầy thiện cảm nhất mà Khoa KHMT đưa ra đó là nó sẽ cho họ nhiều thời gian hơn để dạy về KHMT thực sự. Điều đó chỉ xảy ra khi họ bỏ đi việc tốn đến 2 bài giảng để giải thích về sự khác nhau, ví dụ như một Java int và Integer. Nếu vậy thì 6.001 sẽ cho bạn một câu trả lời hoàn hảo: Scheme, một ngôn ngữ rất đơn giản, toàn bộ có thể dạy cho những học sính sáng dạ của mình trong khoảng 10 phút; rồi bạn có thể dành cả kỳ còn lại về Lý thuyết điểm cố định.

Phù.

Tôi trở về với 1 và 0 đây.

Bạn có những con số 1 ư? Lũ dở gặp hên! Mọi thứ chúng tôi từng có toàn là những con số 0.

Comments

comments