Thứ Ba, tháng 5 29, 2012

Tự Học Lập Trình trong 10 năm (Peter Norvig)


Tại sao mọi người lại vội vã như vậy?
Bước vào bất cư một hiệu sách nào, và bạn sẽ nhìn thấy cuốn Tự học Java trong 7 ngày cùng với vô số những cuốn sách tương tự giúp bạn tự học Visual Basic, Windows, Internet, … trong vòng một vài ngày, thậm chí một vài giờ. Tôi đã dùng công cụ Power Search của Amazon thử tìm những cuốn sách xuất bản sau năm 1992 với mục đích giúp bạn học một thứ gì đó trong vòng vài ngày và tìm được 248 cuốn. 78 cuốn đầu tiên là sách về computer (đứng thứ 79 là cuốn Learn Bengali in 30 days). Tôi thử thay thế “ngày” bằng “giờ” và kết quả giống nhau một cách kinh ngạc: 253 cuốn sách nữa, đầu tiên là 77 cuốn sách computer và đứng thứ 78 là cuốn Teach Yourself Grammar and Style in 24 Hours. Trong số 200 cuốn đầu tiên, 96% là sách máy tính.


Có thể kết luận rằng (1)Mọi người đang đổ xô đi học computer, (2) hoặc computer cực kỳ dễ học, dễ học hơn bất cứ một thứ gì khác. Chẳng có cuốn sách nào dạy bạn nghe Beethoven, dạy Vật lý lượng tử, hay thậm chí dạy cắt lông chó... chỉ trong vòng một vài ngày.
Thử phân tích tựa đề của cuốn Học Pascal trong 3 ngày (Learn Pascal in Three Days)

  • Học: Trong 3 ngày bạn sẽ không đủ thời gian để viết được những chương trình thực sự phức tạp, và học từ những thành công cũng như thất bại của bạn. Bạn cũng không đủ thời gian để làm việc với một lập trình viên giàu kinh nghiệm, và cũng không kịp hiểu cuộc sống trong môi trường đó là như thế nào. Nói một cách ngắn gọn bạn không đủ thời gian để học được nhiều. Đó chỉ có thể là một thứ kiến thức nông cạn chứ không thể là một hiểu biết sâu sắc. Theo như Alexander Pope thì: học một chút là một điều nguy hiểm.

  • Pascal: Trong 3 ngày có lẽ bạn sẽ học được cú pháp của Pascal (nếu bạn đã biết một ngôn ngữ tương tự), nhưng bạn không có nhiều thời gian để học cách sử dụng cú pháp ấy. Nếu bạn là lập trình viên BASIC, bạn sẽ viết một chương trình theo phong cách của BASIC nhưng lại dùng cúp pháp của Pascal, tuy nhiên bạn sẽ không học được Pascal hay ở đâu và dở ở chỗ nào. Vậy thì học Pascal để làm gì? Alan Perlis có nói “Nếu một ngôn ngữ không làm thay đổi cách suy nghĩ của bạn về lập trình thì ngôn ngữ đó không đáng học”. Rất có thể lý do bạn phải học một chút Pascal (hoặc thực tế hơn là Visual Basic hay Javascript) là vì bạn phải dùng một công cụ sẵn có nào đó để hoàn thành nhiệm vụ của bạn. Trong trường hợp này, bạn không học lập trình, bạn đang học cách hoàn thành nhiệm vụ.
  • Trong 3 ngày: Thật đáng tiếc, 3 ngày không đủ cho bạn, như sẽ thảo luận chi tiết hơn ở phần tiếp theo.

Tự học lập trình trong 10 năm
Một số nhà nghiên cứu (Hayes, Bloom) cho rằng phải mất khoảng 10 năm để đạt đến mức tinh thông về một lĩnh vực nào đó – bao gồm đánh cờ, soạn nhạc, vẽ tranh, chơi đàn piano, bơi, tennis… Hình như không có trường hợp ngoại lệ nào: ngay cả Mozart, người được xem là thần đồng âm nhạc vào năm lên 4, cũng phải mất đến 13 năm nữa mới sáng tác ra những kiệt tác âm nhạc. Trong một thể loại khác, ban nhạc The Beatles dường như đã từ chỗ vô danh leo thẳng lên vị trí số 1 bằng một loạt các #1 hit, và xuất hiện trong sô của Ed Sullivan năm 1964. Thực ra, The Beatles đã bắt đầu chơi trong các quán bar nhỏ ở Liverpool và Hamburg từ năm 1957, mặc dù họ đã tạo được sự thu hút từ rất sớm, nhưng thành công lớn thực sự của The Beatles – Sgt. Peppers – ra đời năm 1967. Sammuel Johnson cho rằng để đạt được sự hoàn hảo phải mất hơn 10 năm: “Sự hoàn hảo trong bất cứ một lĩnh vực nào chỉ có thể đạt được bằng cách làm việc cật lực trong suốt cuộc đời; nó không thể mua được với một cái giá rẻ hơn”. Còn Chaucer thì than phiền “Đời thì quá ngắn, mà thời gian học nghề thì quá lâu”
Còn đây là công thức của tôi để thành công trong lập trình:
  • Tìm thấy hứng thú trong việc lập trình và đảm bảo bạn còn đủ hứng thú để đeo đuổi công việc này trong 10 năm.
  • Trao đổi với các lập trình viên khác. Đọc những chương trình do người khác viết. Điều này quan trọng hơn bất cứ cuốn sách học khóa huấn luyện nào.
  • Lập trình. Cách học tốt nhất là vừa học vừa làm. Nói theo cách của giới chuyên môn thì “năng suất tối đa của mỗi người không đơn thuần chỉ do kinh nghiệm, năng suất tăng lên - ngay cả đối với người giàu kinh nghiệm - là kết quả của những cố gắng để hoàn thiện.” và “cách học có hiệu quả nhất cần có: mục đích được xác định rõ ràng với độ khó thích hợp, ý kiến đóng góp phê bình, cơ hội làm lại và sửa sai.” CuốnCognition in Practice: Mind, Mathematics, and Culture in Everyday Life là một tài liệu tham khảo thú vị cho quan điểm này.
  • Nếu bạn muốn hãy theo học đại học (hoặc cao học). Như vậy, bạn sẽ thêm cơ hội để làm những công việc đòi hỏi bằng cấp, và cũng giúp bạn có một hiểu biết sâu sắc hơn, nhưng nếu bạn không thích môi trường trường học, bạn vẫn có thể (với một chút cố gắng nhất định) thu được kiến thức tương tự từ công việc. Trong mọi trường hợp, học từ sách sẽ không đủ. Eric Raymond, tác giả cuốn The New Hacker’s Dictionary nói: “Các chương trình giảng dạy về máy tính không thể biến bạn thành một chuyên gia máy tính, cũng giống như nghiên cứu chổi vẽ và bột màu cũng chẳng biến bạn thành một họa sĩ”. Một trong số những lập trình viên xuất sắc nhất mà tôi đã từng mướn chỉ học hết trung học; anh ta đã viết rất nhiều phần mềm tuyệt vời; có news group của riêng anh; và kiếm được đủ tiền từ stock options để mua cho mình một nightclub.
  • Làm việc chung với các lập trình viên khác. Hãy là lập trình viên giỏi nhất trong một số projects; là người kém nhất trong vài projects khác. Khi bạn là người giỏi nhất, bạn kiểm tra khả năng lãnh đạo của mình, và truyền cảm hứng cho người khác từ sư sắc sảo và tầm nhìn của mình. Khi bạn là người kém nhất, bạn học từ những việc mà người giỏi làm, và từ những việc họ không thích làm (vì họ sẽ bắt bạn làm thay họ)
  • Làm việc với các projects sau những lập trình viên khác. Cố gắng hiểu các chương trình viết bởi người khác. Để ý xem cần phải có những gì để hiểu và sửa nó lúc không có tác giả của chương trình. Thiết kế chương trình của bạn để những người làm việc sau bạn có thể bảo trì, sửa chữa nó một cách dễ dàng.
  • Học ít nhất là nửa tá ngôn ngữ lập trình. Bao gồm ít nhất là một ngôn ngữ hỗ trợ class abstractions (như Java hay C++), một ngôn ngữ hỗ trợ functional abstraction (như LISP hay ML), môt ngôn ngữ hỗ trợ syntactic abstraction (như LISP), môt ngôn ngữ hỗ trợ declarative specifications (như Prolog hay C++ template), một ngôn ngữ hỗ trợ coroutines (như Icon hay Scheme) và một ngôn ngữ hỗ trợ parallelism (như Sisal).
  • Nhớ rằng có chữ “computer” trong “computer science”. Bạn cần biết thời gian máy tính của bạn thực hiện một lệnh là bao lâu; thời gian để máy tính tìm một word trong bộ nhớ (khi word đó có và không có trong cache); thời gian đọc các word kế tiếp nhau từ đĩa cứng; và thời gian tìm đến một vị trí mới trong đĩa cứng.
  • Tham gia vào các cố gắng để tiêu chuẩn hóa ngôn ngữ lập trình. Đó có thể là cuộc họp của hội đồng ANSI C++, nhưng cũng có thể chỉ là quyết định xem nhóm lập trình của bạn sẽ dùng 2 hay 4 khoảng trắng ở đầu mỗi dòng. Bằng cách nào thì bạn cũng học được mọi người thích gì ở một ngôn ngũ lập trình, mức độ, và có lẽ hiểu được một chút tại sao họ lại cảm thấy như vậy.
  • Hoàn tất việc tiêu chuẩn hóa ngôn ngữ càng nhanh càng tốt.

Nếu theo công thức này, bạn thử tính xem bạn có thể học được bao nhiêu chỉ từ sách vở. Trước khi đứa con đầu lòng của tôi ra đời, tôi đã nghiền ngẫm tất cả các cuốn sách Làm cách nào để … mà vẫn cảm thấy mình vẫn chẳng biết gì. 30 tháng sau, khi đứa con thứ 2 của tôi chào đời, tôi có đọc lại những cuốn sách đó không? Không. Thay vào đó tôi dựa theo kinh nghiệm của mình, mà hóa ra là những kinh nghiệm này lại có ích và làm cho tôi yên tâm hơn hàng ngàn trang sách viết bởi các chuyên gia.
Fred Brooks, trong bài No Silver Bullets đã đưa ra một kế hoạch gồm 3 giai đoạn để tìm một người thiết kế phần mềm xuất sắc:
  • Tìm kiếm có một cách có hệ thống những người thiết kế phần mềm giỏi nhất càng sớm càng tốt.
  • Phân công các cố vấn nghề nghiệp để giúp đỡ họ thăng tiến trong công việc và theo dõi hồ sơ nghề nghiệp của họ.
  • Tạo cơ hộ để họ trao đổi và cạnh tranh lẫn nhau

Kế hoạch này dựa trên giả thiết là đã tìm được những người đã có sẵn các đức tính để trở thành một người thiết kế phần mềm xuất sắc, và công việc chỉ là tạo điều kiện để họ phát triển. Alan Perlis nói một cách ngắn gọn hơn: “Nếu tất cả mọi người đều có thể học được điêu khắc thì có lẽ Michelangelo đã được dạy để làm ngược lại. Với các lập trình viên xuất sắc cũng vậy.”
Bạn cứ mua cuốn sách Java đó đi, có lẽ bạn sẽ thấy nó có ích. Nhưng, là một lập trình viên, bạn sẽ không thay đổi cuộc đời bạn, hay trình độ của bạn trong 24 giờ, 24 ngày, thậm chí 24 tháng.

Phụ lục: Lựa chọn ngôn ngữ lập trình
Rất nhiều người hỏi tôi: nên bắt đầu từ ngôn ngữ lập trình nào. Không có một câu trả lời chung, nhưng bạn hãy cân nhắc những điểm sau:
Dùng ngôn ngữ lập trình mà bạn bè dùng: Khi người ta hỏi tôi: “Tôi nên dùng hệ điều hành nào, Windows, Unix, hay Mac?” câu trả lời của thôi thường là “Hãy dùng hệ điều hành mà bạn bè của bạn dùng”. Những gì bạn học từ bạn bè quá đủ đề bù đắp những điểm khác nhau giữa các hệ điều hành, hoặc giữa các ngôn ngữ lập trình. Cũng nên xem xét đến những bạn bè tương lai của bạn: cộng đồng lập trình viên mà bạn sẽ là tham gia nếu bạn tiếp tục. Ngôn ngữ mà bạn chọn có một cộng đồng đang phát triển hay đang lụi tàn? Có sách, có website, có diễn đàn để tìm kiếm câu trả lời cho những vấn đề mà bạn gặp phải hay không? Bạn có thích mọi người trên các diễn đàn đó hay không?
Đơn giản. Những ngôn ngữ lập trình như C++ và Java được thiết kế cho những nhóm làm việc gồm nhiều lập trình viên giàu kinh nghiệm và mối quan tâm của họ là hiệu quả của chương trình. Hậu quả là chúng đã bị phức tạp hóa đề phục vụ cho mục đích này. Mối quan tâm chính của bạn là học lập trình, bạn chưa cần đến sự phức tạp đó. Bạn muốn một ngôn ngũ được thiết kế thật đơn giản, dễ học, dễ nhớ cho một người mới bắt đầu.
Chơi. Nếu bạn muốn học chơi piano, bạn sẽ học chơi theo cách nào: (1)bạn muốn nghe thấy note nhạc ngay sau khi bạn gõ vào phím đàn (interactive mode) hay (2) bạn muốn nghe lại toàn bộ các notes sau khi bạn hoàn tất bản nhạc (batch mode). Rõ ràng cách 1 giúp bạn học piano dễ dàng hơn, và học lập trình cũng vậy. Tìm một ngôn ngữ lập trình có hỗ trợ interactive mode và dùng nó.
Dựa trên những tiêu chuẩn trên, ngôn ngũ lập trình cho người mới bắt đầu mà tôi giới thiệu là Python hay Scheme. Nhưng tùy vào hoàn cảnh của bạn, còn có nhiều chọn lựa tốt khác. Với các lập trình viên tương lai còn đang trong lứa tuổi nhi đồng, thì Alice hoặc Squeak có lẽ thích hợp nhất. Điều quan trọng là bạn chọn nó và hãy bắt đầu.
Source here

Chủ Nhật, tháng 10 16, 2011

Một bài thơ vui

Tôi là bạn đồng hành
Tài sản hay gánh nặng ?
Tôi giúp anh thành công
Hay đẩy anh gục ngã
Thường những gì anh làm
Đều có tôi nhúng tay
Tôi giúp anh làm hay,
Tôi giúp anh làm giỏi
Không đợi anh phải hỏi
Chẳng bao giờ tôi sai
Nếu anh thật có tài,
Tôi nâng anh trên vai .
Nếu anh là kẻ thất bại
Thì tôi biết trách ai ?
Tôi không là cỗ máy
Thô ráp và vô tri
Nhưng tôi đúng từng li
Và thông minh kiệt xuất
Biết làm anh ngã gục
Biết làm anh vững vàng
Hãy dạy tôi nhẹ nhàng
Những gì anh mong ước
Vì một điều biết trước
Rằng tôi sẽ vâng lời
Anh biết rồi bạn ơi
Thói quen - tên tôi đó  .

Chủ Nhật, tháng 9 25, 2011

[Kiến thức cơ bản] Tìm hiểu về Linux Kernel và những chức năng chính của chúng

Với hơn 13 triệu dòng lệnh, Linux kernel là 1 trong những dự án mã nguồn mở rộng lớn nhất trên thế giới, nhưng chính xác chúng là gì và chúng làm gì trong hệ thống?

Kernel là gì?
Tìm hiểu về linux kernel
Khái niệm kernel ở đây nói đến những phần mềm, ứng dụng ở mức thấp (low-level) trong hệ thống, có khả năng thay đổi linh hoạt để phù hợp với phần cứng. Chúng tương tác với tất cả ứng dụng và hoạt động trong chế độ user mode, cho phép các quá trình khác – hay còn gọi là server, nhận thông tin từ các thành phần khác qua inter-process communication (IPC).
Các loại kernel khác nhau

Về bản chất, có nhiều cách để xây dựng cấu trúc và biên dịch 1 bộ kernel nhất định từ đầu. Nhìn chung, với hầu hết các kernel hiện nay, chúng ta có thể chia ra làm 3 loại: monolithic, microkernel, và hybrid. Linux sử dụng kernel monolithic trong khi OS X (XNU) và Windows 7 sử dụng kernel hybrid.
Microkernel:
Microkernel có đầy đủ các tính năng cần thiết để quản lý bộ vi xử lý, bộ nhớ và IPC. Có rất nhiều thứ khác trong máy tính có thể được nhìn thấy, tiếp xúc và quản lý trong chế độ người dùng. Microkernel có tính linh hoạt khá cao, vì vậy bạn không phải lo lắng khi thay đổi 1 thiết bị nào đó, ví dụ như card màn hình, ổ cứng lưu trữ… hoặc thậm chí là cả hệ điều hành. Microkernel với những thông số liên quan footprint rất nhỏ, tương tự với bộ nhớ và dung lượng lưu trữ, chúng còn có tính bảo mật khá cao vì chỉ định rõ ràng những tiến trình nào hoạt động trong chế độ user mode, mà không được cấp quyền như trong chế độ giám sát – supervisor mode.
Ưu điểm:
- Tính linh hoạt cao
- Bảo mật
- Sử dụng ít footprint cài đặt và lưu trữ
Nhược điểm:
- Phần cứng đôi khi “khó hiểu” hơn thông qua hệ thống driver
- Phần cứng hoạt động dưới mức hiệu suất thông thường vì các trình điều khiển ở trong chế độ user mode
- Các tiến trình phải chờ đợi để được nhận thông tin
- Các tiến trình không thể truy cập tới những ứng dụng khác mà không phải chờ đợi
Monolithic Kernel:
Với Monolithic thì khác, chúng có chức năng bao quát rộng hơn so với microkernel, không chỉ tham gia quản lý bộ vi xử lý, bộ nhớ, IRC, chúng còn can thiệp vào trình điều khiển driver, tính năng điều phối file hệ thống, các giao tiếp qua lại giữa server… Monolithic tốt hơn khi truy cập tới phần cứng và đa tác vụ, bởi vì nếu 1 chương trình muốn thu thập thông tin từ bộ nhớ và các tiến trình khác, chúng cần có quyền truy cập trực tiếp và không phải chờ đợi các tác vụ khác kết thúc. Nhưng đồng thời, chúng cũng là nguyên nhân gây ra sự bất ổn vì nhiều chương trình chạy trong chế độ supervisor mode hơn, chỉ cần 1 sự cố nhỏ cũng khiến cho cả hệ thống mất ổn định.
Ưu điểm:
- Truy cập trực tiếp đến các phần cứng
- Dễ dàng xử lý các tín hiệu và liên lạc giữa nhiều thành phần với nhau
- Nếu được hỗ trợ đầy đủ, hệ thống phần cứng sẽ không cần cài đặt thêm driver cũng như phần mềm khác
- Quá trình xử lý và tương tác nhanh hơn vì không cần phải chờ đợi
Nhược điểm:
- Tiêu tốn nhiều footprint cài đặt và lưu trữ
- Tính bảo mật kém hơn vì tất cả đều hoạt động trong chế độ giám sát – supervisor mode
Hybrid Kernel:
Khác với 2 loại kernel trên, Hybrid có khả năng chọn lựa và quyết định những ứng dụng nào được phép chạy trong chế độ user hoặc supervisor. Thông thường, những thứ như driver và file hệ thống I/O sẽ hoạt động trong chế độ user mode trong khi IPC và các gói tín hiệu từ server được giữ lại trong chế độ supervisor. Tính năng này thực sự rất có ích vì chúng đảm bảo tính hiệu quả của hệ thống, phân phối và điều chỉnh công việc phù hợp, dễ quản lý.
Ưu điểm:
- Các nhà phát triển có thể chọn và phân loại những ứng dụng nào sẽ chạy trong chế độ thích hợp
- Sử dụng ít footprint hơn so với monolithic kernel
- Có tính linh hoạt và cơ động cao nhất
Nhược điểm:
- Có thể bị bỏ lại trong quá trình gây treo hệ thống tương tự như với microkernel
- Các trình điều khiển thiết bị phải được quản lý bởi người dùng
Vậy những file Linux Kernel này ở đâu?
Các file kernel này, trong Ubuntu chúng được lưu trữ tại thư mục /boot và đặt tên theo vmlinuz-version. Khi bộ nhớ ảo bắt đầu được phát triển để thực hiện các tác vụ đa luồng, tiền tố vm sẽ được đặt vào đầu các file kernel để phân biệt khả năng hỗ trợ công nghệ ảo hóa. Kể từ đó, Linux kernel được gọi là vmlinux, nhưng hệ thống kernel này đã phát triển với tốc độ quá nhanh, lớn hơn so với dung lượng bộ nhớ boot chuẩn của hệ điều hành, vì vậy những file kernel này đã được nén theo chuẩn zlib – và ký tự z được thêm vào là do như vậy. Ngoài ra còn 1 số định dạng nén thường gặp khác là LZMA hoặc BZIP2, nhưng chúng vẫn được gọi chung là zImage.
Các phiên bản được sắp xếp thứ tự theo định dạng A.B.C.D, trong đó A.B thường là 2.6, C đại diện cho phiên bản, và D là ký hiệu các bản vá lỗi hoặc patch:
Trong thư mục /boot còn có rất nhiều file quan trọng khác như, initrd.img-version, system.map-version, và config-version. File initrd được dùng như 1 ổ đĩa RAM để giải nén và kích hoạt các file kernel thực sự, còn file system.map được dùng để quản lý bộ nhớ trước khi kernel được tải đầy đủ, và file config làm nhiệm vụ thông báo cho kernel biết những lựa chọn hoặc module nào sẽ được nạp vào quá trình hệ thống khởi động.
Cấu trúc file Linux Kernel
Thực tế, Windows đã có tất cả các trình điều khiển sẵn có và người sử dụng chỉ việc kích hoạt các trình điều khiển tương ứng để sử dụng. Và đó cũng chính là nhiệm vụ các module kernel Linux đảm nhiệm, hay còn được gọi là loadable kernel module (LKM), rất cần thiết để giữ các chức năng đi kèm với toàn bộ hệ thống phần cứng hoạt động mà không ảnh hưởng đến bộ nhớ. 1 module thông thường sẽ gán chức năng cơ bản tới các kernel như điều khiển driver, file hệ thống… LKM có phần đuôi mở rộng là .ko và được lưu trữ trong thư mục /lib/modules, người sử dụng có thể thiết lập thuộc tính tự khởi động, cho phép tải hoặc không trong khi hệ điều hành khởi động, bằng cách dùng lệnh menuconfig, can thiệp vào file /boot/config, hoặc bằng cách sử dụng lệnh modprobe.
Các module của các hãng thứ 3 thường có sẵn trên 1 số distributor, ví dụ như Ubuntu, hoặc không được tích hợp sẵn ở chế độ mặc định. Các nhà phát triển phần mềm (ví dụ nVidia, ATI hoặc các hãng khác), không cung cấp mã nguồn nhưng họ đã tự xây dựng và biên dịch các module cần thiết, sau đó cung cấp cho người sử dụng file .ko. Và tất nhiên, có nhiều module hoàn toàn miễn phí, trong khi một số khác thì không.
Như vậy, các bạn đã có thể hình dung được sự quan trọng của kernel. Kernel của Linux khác hẳn so với Mac OS X và Windows bởi trình điều khiển driver cũng như cách thức quản lý và hỗ trợ khác. Trên đây là 1 số thông tin cơ bản và cần thiết giúp mọi người có thể hiểu được kernel là gì, chúng hoạt động như thế nào và tại sao chúng lại cần thiết như vậy. Chúc các bạn thành công!
@ Nguồn: quantrimang.com.vn