Bài viết được dịch từ blog của Kyle Kingsbury, bài gốc tiếng Anh
https://aphyr.com/posts/265-getting-started-in-software
Bằng cách nào mà Software (phần mềm) được tạo ra
Lĩnh vực phần mềm, về mặt kỹ thuật được chia làm 2 khu vực lớn, thường được biết đến với tên gọi là "development" và "operations". Phát Triển - Development là quá trình viết và tinh chỉnh phần mềm, còn Vận Hành - Operations là công việc xuất bản và triển khai/duy trì chúng. Nói chung, Tôi nghĩ rằng công việc Phát Triển thì có chút thiên về vận dụng đầu óc và ngôn ngữ hơn, còn Vận Hành thì lại thiên về kinh nghiệm xử lý và tích hợp những thành phần khác nhau.
Ngoài 2 khu vực kỹ thuật ra, thì cũng có những công việc xung quanh sản phẩm và thiết kế. "Product" (Nhóm sản phẩm) chính là cách mà bạn hiểu về một vấn đề đang gặp phải, gặp những người cần giải pháp cho vấn đề đó, hiểu những công cụ mà bạn có, và mường tượng được hình hài của giải pháp tổng thể. "Design" (Nhóm thiết kế) thì tập trung diễn đạt giải pháp cho người dùng. Tất cả mọi thứ, từ ý tưởng cốt lõi cho đến một mô hình trực quan, đến những chi tiết cụ thể nhất như màu sắc, sắp xếp, font chữ, tiếng động, hình ảnh...
Hãy tưởng tượng đến một cuộc đua xe xuyên sa mạc. Product team là nhóm lên kế hoạch tìm đường, tìm kiếm tài xế, và quyết định loại xe sẽ sử dụng. Developers sẽ thiết kế động cơ, cân bằng khí động học, tối ưu hóa về mặt hoá học, tính toán kích thước và xây dựng khung gầm. Designers thì sẽ định hình vẻ bề ngoài, kiểu dáng xe, chọn màu sơn, vị trí của các bộ điều khiển để tài xế có thể kiểm soát chiếc xe. Operations - đội vận hành sẽ hoạt động trên mặt đất, quan sát hiệu năng, công suất của xe, chữa cháy, thay thế thiết bị hư hỏng, hay đổi những chiếc bánh xe mới cho phù hợp với địa hình hơn.
Như vậy là có 4 nhóm việc trong ngành IT: nhóm "Product", nhóm "Design", nhóm "Develop", nhóm "Operation"
Designers và product team sẽ giao tiếp với nhau rất nhiều để giải quyết vấn đề, đưa ra giải pháp tốt nhất có thể cho người dùng. Developer và Designer làm việc chặt chẽ với nhau để định hình nên chiếc xe, trong đó: designers tùy chỉnh thiết kế cho hợp ý người dùng, và developers tùy chỉnh thiết kế cho máy tính hiểu. Developers sẽ phản hồi với product team về những gì đang được tạo ra và product team cũng thúc giục developers giải quyết những vấn đề còn tồn tại. Developers sẽ giúp đội vận hành (operations) hiểu về chiếc xe, về cách lắp ráp từng bộ phận, điểm yếu của của xe, giới hạn nhiệt, loại khí nào cần sử dụng... Đội vận hành cũng giúp developers hiểu thêm khi chiếc xe thực chạy trên đường, khi nào nó sẽ trục trặc, những bộ phận nào cần được củng cố, đâu là giới hạn tốc độ của chiếc xe...
Xây dựng nên web sites là một cách tiếp cận tốt để có thể tìm hiểu hết những vai trò kể trên. Bạn sẽ thử mỗi vai trò một ít để cảm nhận được đâu là vai trò thích hợp cho bạn.
Thành phần của một web site
Frontend, chính là phần mà bạn nhìn thấy trên browser - trình duyệt web. Nó được cấu thành từ HTML document (một dạnh văn bản có cấu trúc), CSS stylesheet (chỉ định vị trí, màu sắc, kích cỡ của các thành phần trong website) và Javascript (giúp tạo ra sự tương tác giữa các thành phần). Những "frontend dev" sẽ đảm nhận công việc liên quan 3 thứ này HTML, CSS và Javascript, và họ thường làm việc cùng designer nữa (UI và UX).
Phần backend nằm ở server - máy chủ. Nó thường được chia nhỏ ra làm nhiều thành phần phụ. Một phần phụ trong đó sẽ render những chi tiết frontend và đưa nó đến với người dùng khi họ yêu cầu. Một phần khác ghi thông tin xuống database. Các thành phần còn lại sẽ đảm nhận nhiệm vụ như gọi đến dịch vụ bên thứ 3, tính toán quỹ đạo, tạo cuộc gọi thoại, v.v... Những công việc này do "backend dev" đảm nhận.
Môi trường để những thứ "backend" chạy trên đó, như máy tính, hệ điều hành, dịch vụ lưu trữ, mạng, điều khiển... Mà một cô nào đó vận hành thì được gọi là "dev ops" (aka operations enginner), "netword administrator", "sysadmin" tùy theo đặc trưng riêng.
Nhiều lúc, những nhóm dev này làm việc độc lập với nhau, nhưng cũng có khi họ hoạt động sát cánh bên nhau. Một người cũng có thể đảm nhận một hoạt nhiều vai trò cùng lúc, tùy thuộc vào cách tổ chức nhóm.
Quá trình viết Code
Phát triển phần mềm rất giống với quá trình học thuật và nghiên cứu. Việc của bạn là phải hiểu đc bản chất vấn đề, tìm cách diễn đạt nó, viết về nó. Như cách mà bạn đưa ra lý lẽ để thuyết phục độc giả đọc bài luận của bạn vậy, giờ đây bạn hướng dẫn cho chiếc máy tính giải quyết vấn đề. Khác biệt lớn nhất ở đây là mức độ chi tiết: Ngôn ngữ máy tính đơn giản hơn, thực thi nhanh hơn, và sẽ ko bỏ qua lỗi lầm của con người.
Đầu tiên, khi tôi bắt đầu nghĩ về một bài toán, vấn đề. Tôi cố gắng diễn giải nó một cách đơn giản nhất. Chia nó ra thành các vấn đề nhỏ hơn để có thể dễ dàng tìm giải pháp. Tôi bắt đầu ghi chú, vẽ sơ đồ, từng bước đưa ra ví dụ đơn giản về vấn đề đó, tôi cũng tham khảo cách mà mọi người giải quyết nó. Đôi khi việc này chỉ mất vài giây, nhưng nó có thể kéo dài tới nhiều ngày.
Rồi tôi bắt đầu viết mã (code). Tôi chia nó ra thành nhiều functions (hàm số), mỗi function đó sẽ biểu diễn một ý tưởng khác nhau. Tôi đặt tên cho những thứ mà tôi đang cố gắng diễn đạt, và sử dụng chúng một cách nhất quán. Tiếp đó tôi tập hợp những function này lại với nhau thành một giải pháp tổng thể. Mỗi function này đều có chú thích, đây là phần mà tôi giải thích cách mà đoạn mã thực thi, giải quyết vấn đề, những chú thích này chủ yếu là viết cho con người đọc. Vì mã (code) luôn dành cho 2 đối tượng, là máy tính, và một người nào đó đến sau có thể thay đổi hoặc nâng cấp đoạn code đó. Vậy nên bạn phải diễn đạt và chú thích giải pháp thật rõ ràng và hiệu quả cho cả hai đối tượng này.
Functions trong lập trình cũng có thể coi là hàm số toán học, mặc dù nhiều ngôn ngữ khác nhau thể hiện nó theo nhiều cách, và có thể nó trông rất phức tạp và đồ sộ, nhưng về bản chất nó vẫn là một hàm số toán học.
Việc thứ 3, là Tôi sẽ kiểm thử giải pháp mà tôi vừa viết ra đó. Tôi ví dụ, nếu Tôi cần kiểm thử một function viết ra để làm phép cộng, Tôi biết rằng 1 + 1 = 2, và -3 + 5 = 2. Một phần mềm tốt thì cần có một bộ mẫu kiểm thử bao quát hết được toàn bộ các trường hợp xảy ra trong chương trình.
Cuối cùng, tôi tinh chỉnh nó. Có thể chương trình chưa được định dạng cho đúng, hoặc có thể Tôi đã viết sai vài từ ngữ. Cũng có thể chương trình đang bị lỗi về mặt logic. Trình biên dịch (compiler) và các mẫu kiểm thử sẽ làm việc với nhau để chứng tỏ rằng, giải pháp bạn đưa ra là đúng đắn. Có khi, giải pháp đúng, nhưng quá chậm. Nếu Tôi nhận ra vấn đề thì tôi sẽ thiết kế lại, hoặc tối ưu hoá nó nếu cần thiết. Đây thường là phần công việc khó khăn nhất.
Bức tranh lớn hơn
Viết một phần mềm phức tạp, là quá trình cập nhật liên tục. Bạn sẽ đi qua nhiều bản nháp, khám phá nhiều thứ mới mẻ, sắp xếp lại, rồi duyệt bởi chính bạn hoặc với những người khác. Trong công việc phát triển, bọn tôi gọi một bản nháp là một "version". Có những phần mềm chuyên dụng để kiểm soát những version này (Version Control Software), nó sẽ lưu tất cả versions và kết nối chúng lại thành một mạng lưới khổng lồ. Nó cho phép chúng tôi hiểu về lịch sử thay đổi của một tài liệu, và quan trọng hơn, nó còn cho phép tích hợp thay đổi đến từ mỗi người.
Khi nhiều người cùng làm phần mềm, chúng tôi cố gắng chia nhỏ nó ra. Như vậy mỗi người có thể làm trên một thành phần riêng rẽ và ko gây trở ngại tới người khác. Có rất nhiều cách tổ chức Mã Code, những cách này đều hướng đến việc chia nhỏ, phân loại sự phức tạp để giúp bạn có thể hiểu và thay đổi được những phần nhỏ một cách riêng lẻ.
Tưởng tượng việc viết một paper với một người bạn. Các bạn mỗi người nhận viết một section riêng, rồi sau đó kết hợp nó lại thành một tài liệu. Sau đó bạn có thể đọc phần của người còn lại và mở rộng nó, bạn có thể thay đổi từ ngữ, sắp xếp lại câu chữ. Môi lần bạn thay đổi thì bạn có thể lưu một "version" mới, và các bạn so sánh ghi chú vào buổi tối, bạn có thể chi tiết từng thay đổi/cập nhật đó, và quyết định cái nào sẽ phù hợp với toàn bộ tài liệu. Những thay đổi nhỏ thì càng dễ so sánh và tổng hợp hơn, nó cũng giúp bạn hiểu về lịch sử của tài liệu đó. Khi bạn tìm thấy một đoạn văn bị mất, bạn có thể đọc lại lịch sử để xem tại sao nó biết mất và biến mất ở giai đoạn nào.
Những công cụ thông dụng
Nếu bạn muốn bước vào sự nghiệp lập trình, bạn sẽ cần xây dựng những kĩ năng cơ bản trước. Những kĩ năng này thường có chút trừu tượng và chưa-thực-sự-cần-thiết, những chúng sẽ giúp bạn làm việc nhanh hơn về mặt lâu dài, đây cũng là những kỹ năng mà bạn cần liên tục củng cố. Thật sự, đây chỉ phần khởi động thôi, nhưng có ích.
Đầu tiên: Bạn cần một hệ điều hành. Thành thật mà nói, hầu hết những công cụ mà bạn cần và sẽ sử dụng, thì ko được thiết kế cho Windows. Vẫn có một số cách thức thay thế, nhưng lại hay lỗi thời. Linux là sự lựa chọn số 1, tiếp theo đó là Mac OS. Rất nhiều lập trình viên nền Windows mà Tôi quen, vẫn phải chạy một máy ảo Ubuntu.
Thứ 2: Bạn sẽ cần một trình biên tập (editor), là thứ sẽ giúp bạn viết code, biên tập. Nhiều người sử dụng Textmate, Sublime Text, hoặc Notepad++, nhưng những lập trình viên giỏi nhất mà tôi biết thường dùng Emacs hoặc Vim. Cả 2 đều mạnh mẽ, nhưng bạn sẽ cần thử thách trí nhớ của mình khi dùng đến. Bạn có thể thay đổi sau, nhưng thường ai cũng gắn bó với lựa chọn đầu tiên của họ. Một số ngôn ngữ như Objective C hay Java cần rất nhiều contextual information - như foreign language dictionaries, proofreaders... để viết tốt. Nếu bạn làm việc với những ngôn ngữ như vậy, bạn sẽ cần một trình biên tập đặc biệt khác, gọi là IDE.
Thứ 3: version control. Có rất nhiều sự lựa chọn, đa số người quen và dự án mà Tôi làm việc đều sử dụng Git và Github. Bạn có thể học những thứ căn bản về git trong nửa giờ và nó sẽ giúp cuộc đời bạn sáng sủa hơn khi bắt đầu một dự án.
Ngôn ngữ lập trình
Ok đây là ý kiến cá nhân của Tôi. Mỗi người đều có lý tưởng riêng và bạn sẽ nhận được câu trả lời khác nhau khi bạn hỏi nhiều người khác. Bạn sẽ bắt đầu khám phá ra và có ý kiến của bạn khi bắt đầu công việc. Hiện tại, bất kể là ngôn ngữ nào, mà bạn đang sử dụng, nó chính là Ngôn ngữ lập trình tốt nhất rồi.
Javascript là một... tội ác, nhưng cần thiết, nó là thứ tệ hại nhất trên thế giới này. Nó là cách duy nhất để bạn viết code cho sự tương tác ở frontend, vậy nên bạn muốn làm một website có tính tương tác, bạn cần dùng nó. Javascript được ném ra làm ngôn ngữ lập trình một cách chóng vánh, dĩ nhiên là kèm theo một thiết kế tồi. Javascript có rất nhiều ngoại lệ. Việc tổ chức, sắp xếp code của nó rất khó. Những thứ cơ bản của ngôn ngữ như numbers, strings, lists thì lại có thể thay hình đổi dạng sang kiểu khác một cách mà ko ai mong đợi. Bạn cần hiểu rằng khi bạn code với Javascript, bạn sẽ cảm thấy thất vọng hoặc bối rối và ko hiểu lý do, đó là vì ngôn ngữ này có nhiều giới hạn. Tóm lại nó là pidgin.
Đọc về Pidgin. Tóm gọn lại pidgin là một loại ngôn ngữ tối giản, pha trộn lai tạp và vay mượn chữ nghĩa.
Vẫn tồn tại một thể loại frontend khác, là dành cho phone và tablet. Ở đây 2 tay chơi bự nhất là iOS (dành cho iPhone và iPad), sử dụng Objective-C (thêm Swift nữa) và Android, sử dụng Java (thêm Kotlin nữa). Cả 2 đều khá cân bằng về mức độ phức tạp và sức mạnh, như tiếng Pháp và tiếng Đức vậy. Có thể nói rằng, cả 2 đều có mức độ diễn đạt (expressiveness) ở mức khá. Và code của nó còn đòi hỏi tỉ mỉ hơn cả viết code ở backend. Khá nhiều ngoại lệ và một chút khó khăn khi bắt đầu. Nhưng, chẳng có phép nhiệm màu nào ở đây cả, và nếu có, có thể là một cơ hội tốt cho bạn.
Phía backend thì có nhiều sự lựa chọn hơn. Rất nhiều người chọn Ruby hoặc Python. Giống như tiếng Pháp và tiếng Tây Ban Nha vậy, chúng đều khá phổ biến, gần giống nhau và có hiệu năng và sức mạnh ngang nhau. Vì phổ biến, nên bạn sẽ dễ dàng tìm thấy những thư viện (các đoạn code viết sẵn để giải quyết một vấn đề).
Muốn một hiệu năng tốt hơn, những hệ thống lớn thích dùng Java, và ít phổ biến hơn như C hoặc C++. Java nhìn chung mang đến tốc độ nhanh nhưng cũng khá nặng, và rất chậm cải tiến. Tôi cảm thấy khá rối khi viết code Java. Nó giống như khi bạn viết mà ko thể dùng dấu phẩy vậy, và phải chia tách mỗi suy nghĩ, viết ra thành một câu đơn giản. C và các biến thể của nó thì cực kỳ nhanh nhưng cũng rất đáng sợ. Tôi khuyên bạn hãy chỉ chọn chúng làm ngôn ngữ thứ 2.
Tôi sẽ né PHP và Perl. Đây là những ngôn ngữ khá ổn nhưng nó ko có điểm mạnh nào đáng kể. PHP thiết kế thiếu cẩn trọng và trở nên giống như tiếng Anh vậy: ko ai đồng ý / chắc chắn về từ ngữ nào nên dùng.
Lisp và các biến thể của nó thì như tiếng Latin vậy. Rất cổ xưa, cực kỳ đơn giản, mức độ biểu đạt rất cao. Nhưng ít được nhắc đến, kể cả sự xuất hiện của Clojure. Hầu như toàn bộ các ngôn ngữ khác đều có thể xem là một subset của Lisp. Nó sẽ thay đổi bạn, thay đổi cách nghĩ của bạn và hoàn thiện kỹ năng lập trình của bạn đối với những ngôn ngữ khác.
Khi bạn bắt đầu lập trình, suy nghĩ của bạn thường rời rạc và gói gọn, như khi bạn học tiếng mới vậy. Nhưng bạn sẽ trưởng thành dần khi bắt đầu giải quyết những bài toán lớn hơn, trừu tượng hơn. Mỗi ngôn ngữ đều có một mức trừu tượng khác nhau, là phần mà bạn ko thể giải thích trực tiếp. Ví dụ, tiếng Anh cho phép bạn đặt tên cho các đối tượng mới. Tiếng Đức cho phép bạn sinh ra những động từ mới từ việc pha trộn, nhưng thực tế thì tiếng Anh và tiếng Đức đều có khả năng mô tả, diễn tả ngang nhau, chỉ là cách tiếp cận vấn đề khác nhau. Ngôn ngữ lập trình cũng như vậy. Lisp... cho bạn năng lực chế được cả ngữ pháp mới.
Vậy, ko có nhiều nơi tuyển dụng Clojure hoặc biến thể khác của Lisp, tuy ít, nhưng công việc liên quan đến nó thường rất hay ho. Tôi đề cử Clojure (và biến thể của Lisp), nếu bạn có thời gian, hãy học nó.
Hầu hết các ngôn ngữ hiện đại đều khá giống nhau. Ruby, Python, Perl, PHP, Java, và C đều là Germanic, ẩn sâu bên trong chúng đều là cùng một nguồn gốc, cùng lý tưởng. À, ngoài ra còn một họ ngôn ngữ khác mà bạn cần biết, nó tương tự như tiếng Nhật hay A-rập vậy, và cũng ko nhiều người sử dụng chúng. Haskell và OCaml là ngôn ngữ lập trình hàm kiểu mạnh (strongly-typed fucntional /lẽ ra ko nên dịch cụm từ này/), rất khác biệt so với các ngôn ngữ khác và có một mức độ trừu tượng rất cao. Erlang là một ngôn ngữ lập trình hàm phân tán, code thực thi trên nhiều máy tính cùng lúc. Nếu bạn theo đuổi những kiểu ngôn ngữ này, nó có thể mang đến phần thưởng rất lớn cho bạn (và nó sẽ khiến bạn trở thành lập trình viên xuất sắc), nhưng bạn sẽ phải học rất nhiều và rất lâu trước khi bạn có thể kiếm được một công việc.
Giả định công việc đầu tiên
Khi bạn bắt đầu học một ngôn ngữ lập trình, bạn sẽ thu được kinh nghiệm về ngôn ngữ, về những công cụ cơ bản. Qua thời gian bạn sẽ xây dựng một dự án, lúc này bạn sẽ học một số thư viện chuyên biệt, như vẽ hình, lưu trữ dữ liệu, hay làm web. Một khi có đủ tự tin, bạn sẽ bắt đầu viết code theo phong cách riêng, dựa vào kỹ năng của bạn. Bạn publish những project đó lên Github. Ko ai quan tâm.
Khi bạn cảm thấy sẵn sàng, với những project nhỏ, demos hoặc thư viện nào đó mà có thể chứng tỏ được khả năng viết code một cách bài bản: rõ ràng, có ghi chú, dễ test. Thì bạn hãy gửi resume kèm theo link github. Lúc này mới có người đọc code của bạn và có thể họ sẽ thấy tiềm năng của bạn.
Bạn tìm được một công việc trong một startup nhỏ, và bắt đầu lạc lối với hàng triệu thứ mà ko ai nhắc trước với bạn. Bạn cảm thấy mình vô dụng, một chút, nhưng bạn bắt đầu đuổi kịp công việc và đồng nghiệp. Trong một tháng (hoặc có thể 1 ngày), code của bạn sẽ lên sóng, và thứ gì đó bạn code, sẽ hiện trên màn hình của chục ngàn người dùng. Những vấn đề trong công việc mà bạn gặp phải sẽ thúc đẩy bạn học những thư viện mới, thuật toán, hay thậm chí là ngôn ngữ mới. Bạn sẽ viết code để xử lý ngôn ngữ tự nhiên, và sếp của bạn khuyến khích bạn đẩy lên github.
Từ đây trở đi, nó sẽ như một dòng chảy. Profile của bạn có nêu những đóng góp về mã nguồn mở, code của bạn chất lượng hơn và nhiều người bắt đầu để ý đến code của bạn. Rồi bạn sẽ nhận được những đề xuất hoặc lời mời gọi từ bên ngoài. Bạn sẽ cần mở rộng vốn liếng, làm quen môi trường khác, và học hỏi thêm, từ đồng nghiệp của mình.
Ok, bắt đầu khởi động nào, Kyle
Option A: Theo đuổi frontend
Bạn và tôi sẽ bắt đầu viết một website, ngay ngày mai. Những thứ căn bản nhất, như notepad. Chúng ta sẽ bắt đầu học Ruby như là một ngôn ngữ và học cả Sinatra cho server framework, HTML+CSS để hiển thị trang web. Chỉ cần viết khoảng 100 dòng code là bạn có thể có một khung sườn tốt để khám phá. Bạn sẽ có một cái nhìn về "full stack" từ frontend sang backend, và version control. Thời điểm này bạn sẽ học 3 ngôn ngữ khác nhau một lần, bạn sẽ thấy bối rối. Testing (kiểm thử) frontend thì rất là thử thách, chúng ta chưa cần bàn tới vội. Mặt khác, bạn có thể thấy kết quả của code ngay trên trình duyệt, và bạn sẽ cảm thấy yêu đời.
Option B: Theo đuổi backend
Chúng ta sẽ bắt đầu bằng các bài toán trong Project Euler trước. Các bài toán nhỏ này chỉ có một đáp án, và mục tiêu rất rõ ràng, bạn sẽ càng tự tin hơn mỗi khi giải được bài toán. Những bài toán này bắt đầu từ dễ, và khó dần, thông qua việc giải toán bạn cũng sẽ học được những kỹ thuật mạnh mẽ để giải quyết vấn đề. Chúng ta có thể dùng bất kỳ ngôn ngữ nào, tôi thì gợi ý nên dùng Clojure hoặc Ruby. Con đường này sẽ đưa bạn đến với những khái niệm như kiểm thử, thuật toán, debug... tất cả những qui trình giải quyết vấn đề bằng code. Bạn chỉ cần học một ngôn ngữ, và tôi sẽ giúp bạn hiểu sâu hơn về ngôn ngữ và các kỹ thuật nâng cao.
Project Euler cũng là nơi tôi luyện tập lúc rảnh rỗi, rất đáng để cày bừa nhé, link đây
Option C: Làm những gì bạn thích
Hãy bắt đầu bằng một vấn đề mà bạn hứng thú. Chỉ dựa vào một mình bạn. Ko thành vấn đề nếu mọi người ko ai quan tâm, bạn chỉ cần tập trung giải quyết vấn đề của bạn thôi. Có thể bạn muốn làm chương trình dịch tiếng Latin, tạo một chương trình chat, viết game, đánh dấu papers... bất cứ thứ gì. Tôi sẽ giúp bạn thiết kế giải pháp, bất kỳ ngôn ngữ nào cũng được.
Và bạn cũng có thể thay đổi giữa 3 options trên khi bạn thấy chán. Tất cả những lựa chọn trên sẽ dần dần hé mở thêm những ngôn ngữ cùng với kỹ thuật cần thiết để tìm kiếm job.
#ntechdevelopers