Tránh 12 sai lầm lập trình này: Những cạm bẫy phổ biến trong phát triển phần mềm và cách ngăn chặn chúng

Thế giới nghệ thuật được đặc trưng bởi nhiều ý kiến trái ngược nhau về điều gì tạo nên một tác phẩm nghệ thuật tuyệt vời, và theo cách tương tự, các lập trình viên thường có những quan điểm khác nhau về điều gì tạo nên một đoạn mã xuất sắc, ngoài yêu cầu cơ bản là nó không bị lỗi. . Mỗi nhà phát triển có bộ nguyên tắc và tiêu chuẩn riêng của họ. Khi một nhà phát triển khuyên không nên làm điều gì đó, có thể là do trước đó họ đã thử làm điều đó và gặp phải lỗi nghiêm trọng.

Tuy nhiên, vấn đề có thể nảy sinh khi chúng ta phản ứng thái quá trước một lỗi lầm bằng cách đi quá xa theo hướng ngược lại. Chẳng hạn, một nhóm có thể tránh được sự cố với tùy chọn A bằng cách chọn tùy chọn B thay vào đó, nhưng hóa ra tùy chọn B cũng có một loạt vấn đề riêng, dẫn đến thời gian khắc phục sự cố kéo dài thêm.

Tin tốt là bạn có thể học hỏi từ cả sai lầm ban đầu và sửa chữa quá mức. Cách tiếp cận tốt nhất thường là cách ở giữa. Bài tiểu luận này thảo luận về một số lỗi lập trình phổ biến nhất cũng như những nguy hiểm khi đi theo con đường ngược lại.

Chơi nó nhanh và lỏng lẻo

Bỏ qua các nguyên tắc cơ bản là một cách đơn giản nhưng phổ biến để tạo mã không ổn định và dễ bị lỗi. Điều này có thể liên quan đến việc xem xét các hành động không thể đoán trước của người dùng có thể ảnh hưởng đến chương trình của bạn như thế nào. Số 0 có được sử dụng làm đầu vào cho phép chia không? Văn bản đã gửi sẽ luôn có độ dài chính xác? Các định dạng ngày của bạn có tuân thủ các tiêu chuẩn thích hợp không? Tên người dùng đã được xác thực đối với cơ sở dữ liệu chưa? Ngay cả sự giám sát nhỏ nhất cũng có thể dẫn đến lỗi phần mềm.

Một cách tiếp cận để giải quyết vấn đề này là tận dụng khả năng xử lý lỗi của mã. Nhà phát triển áp dụng cách tiếp cận lỏng lẻo có thể bao gồm toàn bộ ngăn xếp của họ bằng một khối bắt duy nhất cho tất cả các trường hợp ngoại lệ tiềm ẩn. Họ có thể chỉ cần ghi lại lỗi, trả lại mã lỗi và chuyển sự cố cho người khác xử lý.

Tập trung quá nhiều vào tiểu tiết cũng có thể gây ra những hậu quả tiêu cực.

Một số người tin rằng một lập trình viên lành nghề là người kiểm tra cả hai bên đường một chiều trước khi băng qua nó. Tuy nhiên, tương tự như chơi nhanh và lỏng lẻo, xu hướng này có thể dẫn đến các vấn đề. Phần mềm quá thận trọng có thể làm chậm hoạt động đáng kể. Trong khi việc kiểm tra một số con trỏ null có thể không có nhiều tác động, thì một số mã quá lo lắng, kiểm tra liên tục để đảm bảo rằng các cửa đã bị khóa, khiến cho không thể hoàn thành bất kỳ công việc nào. Loại hệ thống này bị sa lầy trong một mê cung các thủ tục xác minh và xác thực mà không có quá trình xử lý nào diễn ra.

Điều quan trọng là tổ chức các lớp mã của bạn để xác minh dữ liệu khi lần đầu tiên nhập và sau đó cho phép nó đi qua. Mặc dù có thể có một số lỗi do đó, đó là lý do tại sao việc kiểm tra lỗi được đưa vào.

Quá nhiều phức tạp về mặt lý thuyết

Một số lập trình viên ôm việc nghiên cứu các thuật toán. Họ thích thiết kế các thuật toán và cấu trúc dữ liệu phức tạp vì họ muốn xây dựng ngăn xếp hiệu quả nhất có thể. Mỗi lớp hoặc thư viện phải hoàn hảo.

Đó là một sự thôi thúc tốt đẹp nhưng trong nhiều trường hợp, kết quả cuối cùng là một ứng dụng khổng lồ ngốn quá nhiều bộ nhớ và chạy như mật mía vào tháng Giêng. Về lý thuyết, nó sẽ nhanh nhưng bạn sẽ không thấy nó cho đến khi có 100 tỷ người dùng với 50 triệu tài liệu cho mỗi người dùng.

Phần lớn lý thuyết thuật toán tập trung vào mức độ mở rộng của các thuật toán và cấu trúc dữ liệu. Việc phân tích chỉ thực sự áp dụng khi dữ liệu phát triển lớn. Trong nhiều trường hợp, lý thuyết không tính đến việc cần bao nhiêu mã để loại bỏ thời gian.

Trong một số trường hợp, lý thuyết bỏ qua các chi tiết quan trọng. Một trong những thời gian mất nhiều thời gian nhất là tìm nạp dữ liệu từ bộ nhớ chính hoặc tệ hơn là từ cơ sở dữ liệu trên đám mây. Tập trung vào các vấn đề thực tế về nơi dữ liệu được lưu trữ và khi nào dữ liệu được truy cập sẽ tốt hơn là một cấu trúc dữ liệu phức tạp.

Không đủ phức tạp về mặt lý thuyết

Không đủ độ phức tạp về lý thuyết là vấn đề ngược lại với việc quá mải mê với lý thuyết lập trình.

Khi mã được viết mà không tính đến các khía cạnh lý thuyết của cấu trúc dữ liệu hoặc thuật toán, nó có thể hoạt động tốt trên dữ liệu thử nghiệm, nhưng có thể không xử lý được tải khi người dùng thực bắt đầu sử dụng.

Điều quan trọng là phải giải quyết các mối lo ngại về khả năng mở rộng trong giai đoạn lập kế hoạch, vì một số tính năng, chẳng hạn như so sánh từng mục nhập dữ liệu với nhau, có thể có độ phức tạp bậc hai cố hữu có thể dẫn đến tốc độ tối ưu hóa chậm theo cấp số nhân. Đôi khi, tốt hơn hết là quay lại những gì bạn đã hứa để tránh làm phức tạp hóa hệ thống.

Cân bằng sự phức tạp về mặt lý thuyết với những cân nhắc thực tế là một thách thức và đôi khi, tốt hơn hết là bạn nên tập trung vào kiểm tra tải và lặp lại cẩn thận hơn là tối ưu hóa sớm. Như người xưa vẫn nói, “tối ưu hóa sớm là lãng phí thời gian.” Bắt đầu với một chương trình cơ bản, kiểm tra nó và sau đó giải quyết những phần chậm nhất.

Quá tin tưởng vào trí tuệ nhân tạo

Chúng ta đang ở thời điểm mà mọi thứ trở nên rõ ràng rằng thuật toán AI có thể mang lại kết quả đáng kinh ngạc. Đầu ra là thực tế đáng kinh ngạc và tốt hơn mong đợi. Nhiều người tin rằng thời đại của máy tính có tri giác đã đến.

AI đôi khi cung cấp dữ liệu cực kỳ hữu ích. Các lập trình viên đã hoán đổi các công cụ tìm kiếm để lấy các mô hình ngôn ngữ lớn vì họ không thể chịu đựng được tất cả các quảng cáo và các tính năng “khuếch đại” do con người tạo ra. Họ không tin vào sự can thiệp của con người và đặt niềm tin vào học máy.

Tuy nhiên, điều quan trọng là phải nhận ra chính xác thuật toán có thể làm gì và chúng hoạt động như thế nào. Các hệ thống máy học phân tích dữ liệu, sau đó xây dựng một chức năng phức tạp bắt chước dữ liệu đó. Họ giống như những con vẹt thông minh khi gửi văn bản. Vấn đề là chúng được lập trình để cung cấp mọi thứ với cùng một thẩm quyền đáng tin cậy, ngay cả khi chúng hoàn toàn sai. Tệ nhất, AI có thể mắc sai lầm nghiêm trọng và không nhận ra điều đó nhiều hơn chúng ta.

Không đủ dữ liệu huấn luyện

Hiệu suất của mô hình AI chỉ phụ thuộc vào chất lượng dữ liệu đào tạo của nó. Khi các thuật toán học máy trở nên dễ tiếp cận hơn, các lập trình viên sẽ có nhiều cơ hội hơn để sử dụng chúng trong các dự án khác nhau.

Tuy nhiên, các công cụ AI thường không thể đoán trước và tạo ra kết quả không chính xác, chủ yếu là khi dữ liệu đào tạo không đầy đủ. Các tình huống hiếm gặp không có trong dữ liệu huấn luyện, được gọi là “thiên nga đen”, có thể khiến AI hoàn toàn nhầm lẫn, dẫn đến các phản ứng ngẫu nhiên.

Thu thập và sắp xếp dữ liệu để đào tạo mô hình AI là một nhiệm vụ quan trọng đòi hỏi tư duy khác với lập trình truyền thống. Điều cần thiết là thu thập dữ liệu đại diện và rộng rãi để tạo ra một mô hình AI đáng tin cậy, điều này thường không phải là một phần trong quá trình đào tạo lập trình viên.

Tin tưởng bảo mật của bạn vào hộp ma thuật

Chỉ dựa vào “hộp ma thuật” để bảo mật có thể gặp rủi ro. Một số nhân viên bán hàng có thể đề xuất thêm mật mã như một cách khắc phục nhanh, nhưng điều này có thể tạo ra cảm giác an toàn sai lầm. Mặc dù các nhà khoa học máy tính đã tạo ra các thư viện cung cấp vô số tùy chọn để giải quyết các vấn đề mã hóa, nhưng việc sử dụng chúng cũng có thể che giấu các vấn đề phức tạp và thậm chí giới thiệu những vấn đề mới.

Vấn đề chia sẻ quá nhiều mã giữa các thư viện khác nhau chỉ mới bắt đầu được hiểu rõ, như đã thấy với lỗi Log4j. Mật mã cũng có thể là một nguồn dễ bị tổn thương và giả định rằng việc liên kết thư viện mã hóa sẽ cung cấp bảo mật hoàn toàn là một sai lầm.

Trên thực tế, Viện Tiêu chuẩn và Công nghệ Quốc gia gần đây đã ngừng sử dụng SHA‑1 do những điểm yếu của nó. Nhiều thuật toán trong số này có những điểm yếu tinh vi và việc hiểu đầy đủ về chúng đòi hỏi nhiều hơn là chỉ đọc nhanh phần “bắt đầu nhanh” của sách hướng dẫn.

Phát triển mật mã của riêng bạn

Bạn có thể thực sự dựa vào chính mình, ngay cả khi bạn không tin tưởng người khác? Các nhà phát triển thường tưởng tượng về việc tạo thư viện của riêng họ. Tuy nhiên, suy nghĩ này có thể dẫn đến những vấn đề không lường trước được trong tương lai.

John Viega cảnh báo: “Tin tặc rất vui khi thấy mã hóa tự chế, đồng thời lưu ý rằng ngay cả những lập trình viên giàu kinh nghiệm nhất cũng có thể mắc lỗi trong việc bảo vệ hệ thống của họ khỏi bị khai thác. Vậy bạn nên tin ai? Bản thân bạn hay những người được gọi là chuyên gia cũng mắc lỗi? Giải pháp có thể được tìm thấy trong quản lý rủi ro.

Nhiều thư viện không cần phải hoàn hảo, vì vậy sẽ hiệu quả hơn nếu sử dụng thư viện có sẵn thay vì viết mã của riêng bạn. Thư viện chứa các quy trình được tối ưu hóa do một nhóm phát triển. Họ có thể mắc lỗi, nhưng quy trình lớn hơn có thể loại bỏ nhiều lỗi trong số đó.

Quá tin tưởng vào khách hàng

Các nhà phát triển thường bỏ qua thực tế là họ không có quyền kiểm soát tuyệt đối đối với phần mềm của mình khi phần mềm đó đang chạy trên máy của người khác. Một số lỗ hổng bảo mật nghiêm trọng nhất xuất hiện khi các nhà phát triển cho rằng thiết bị khách sẽ hoạt động phù hợp. Chẳng hạn, mã dự định chạy trên trình duyệt có thể được trình duyệt sửa đổi để thực hiện bất kỳ hành động nào. Nếu nhà phát triển không xác thực được tất cả dữ liệu đến, mọi thứ có thể trở nên tồi tệ.

Một trong những phương pháp tấn công dễ dàng nhất phụ thuộc vào thực tế là một số nhà phát triển nhất định chỉ chuyển dữ liệu của khách hàng tới cơ sở dữ liệu, hoạt động tốt cho đến khi khách hàng gửi SQL thay vì câu trả lời hợp lệ. Chẳng hạn, nếu một trang web yêu cầu tên người dùng và thêm tên đó vào truy vấn, kẻ tấn công có thể nhập tên “x; Người dùng DROP TABLE;”. Cơ sở dữ liệu giả định nhầm rằng tên đó là “x” và sau đó tiến hành xóa bảng chứa tất cả người dùng.

Những cá nhân tháo vát có thể thao túng lòng tin của máy chủ theo nhiều cách khác. Ví dụ, các cuộc khảo sát trên web là một cơ hội để giới thiệu sự thiên vị. Lỗi tràn bộ đệm vẫn là một trong những cách dễ dàng nhất để can thiệp vào phần mềm.

Tệ hơn nữa, các lỗ hổng bảo mật nghiêm trọng có thể phát sinh khi các lỗ hổng có vẻ lành tính được liên kết với nhau. Một nhà phát triển có thể cho phép khách hàng ghi một tệp, hy vọng rằng các quyền đối với thư mục sẽ ngăn chặn bất kỳ việc ghi nhầm nào. Một nhà phát triển khác có thể tiết lộ quyền chỉ để giải quyết một lỗi ngẫu nhiên. Riêng lẻ, các lựa chọn mã hóa này là vô hại, nhưng khi kết hợp với nhau, chúng có thể cho phép truy cập máy khách tùy ý.

Không đủ tin tưởng vào khách hàng

Các biện pháp bảo mật quá mức có thể gây ra sự cố cho doanh nghiệp, ngay cả khi không có vi phạm bảo mật nghiêm trọng nào. Quá nhiều biện pháp bảo mật và thu thập dữ liệu xâm nhập có thể khiến mọi người không muốn tham gia vào các trang web truyền thông xã hội và quảng cáo trực tuyến, dẫn đến việc họ nói dối hoặc bỏ cuộc. Ngoài ra, các giao thức bảo mật quá nghiêm ngặt có thể cản trở các hoạt động khác, như đã thấy trong ví dụ về việc phải nới lỏng các biện pháp bảo mật để giải quyết sự cố phần mềm. Do đó, nhiều nhà phát triển web hiện đang cố gắng giảm thiểu các biện pháp bảo mật để giúp người dùng tương tác với sản phẩm của họ dễ dàng hơn và giảm lượng dữ liệu họ cần bảo vệ. Chẳng hạn, một số trang web đã loại bỏ mật khẩu và thay vào đó sử dụng email dùng một lần để đăng nhập. Đây là một cơ chế đơn giản hơn và gần như an toàn như mật khẩu. Cuốn sách “Cơ sở dữ liệu trong mờ” đưa ra một số chiến lược để cơ sở dữ liệu lưu trữ ít thông tin hơn trong khi vẫn cung cấp các dịch vụ giống nhau.

Đóng nguồn

Việc xác định mức độ thích hợp của việc chia sẻ mã phần mềm với người dùng là một vấn đề phức tạp đối với các công ty. Theo John Gilmore, người đồng sáng lập Cygnus Solutions, một trong những công ty phần mềm nguồn mở sớm nhất, việc chọn không phân phối mã là đi ngược lại tính toàn vẹn của mã. Gilmore tin rằng việc phân phối mã là một cách đơn giản để thúc đẩy sự đổi mới và quan trọng là để xác định và giải quyết các lỗi phần mềm. Bằng cách chia sẻ mã, các cá nhân bên ngoài công ty có thể góp phần cải thiện mã bằng cách xác định và sửa lỗi, thêm tính năng và cải thiện tài liệu. Mặc dù những đóng góp của họ có thể không phải lúc nào cũng hoàn hảo, nhưng nó thường dẫn đến mã hài hòa hơn và có cấu trúc tốt hơn. Hơn nữa, việc mở mã có thể khuyến khích việc tạo ra nhiều phần mềm mô-đun hơn và được tổ chức tốt hơn, khi những người khác biên dịch và chuyển nó sang các nền tảng khác. Khi các điều chỉnh nhỏ được thực hiện để chia sẻ mã, kết quả sẽ được đưa trở lại cơ sở mã, dẫn đến một sản phẩm tốt hơn và dễ tiếp cận hơn.

Cởi mở như một liều thuốc chữa bách bệnh

Mặc dù có hàng triệu dự án nguồn mở tồn tại, nhưng chỉ một phần nhỏ thu hút đủ những người đóng góp để duy trì, sửa đổi hoặc mở rộng mã. Thực tế đơn thuần là một dự án đang mở không đảm bảo kết quả thực tế, vì những người đóng góp bên ngoài có thể không có động cơ để đưa vào công việc. Hơn nữa, việc mở một dự án có thể thêm chi phí mới cho thông tin liên lạc và tài liệu. Công việc làm thêm này có thể đáng giá đối với các dự án lớn hơn nhưng có thể đè nặng lên các dự án nhỏ hơn. Ngoài ra, việc mở một dự án có thể tước đi sự hỗ trợ tài chính và khuyến khích sự cai trị của đám đông. Mặc dù sự cạnh tranh và sáng tạo mở có thể mang lại kết quả tuyệt vời, nhưng một số nhà phát triển có thể quay lại các dự án nguồn đóng để có cấu trúc, hệ thống phân cấp và quyền hạn hỗ trợ sự phát triển có phương pháp.

Liên kết nguồn
agilino, March 23, 2023