Các chương trình không có lỗi về mặt lý thuyết


12

Tôi đã đọc rất nhiều bài báo nói rằng mã không thể không có lỗi và họ đang nói về những định lý này:

Trên thực tế, định lý của Rice trông giống như một hàm ý của vấn đề tạm dừng và vấn đề tạm dừng có mối quan hệ chặt chẽ với định lý không hoàn chỉnh của Gôdel.

Có phải điều này ngụ ý rằng mọi chương trình sẽ có ít nhất một hành vi ngoài ý muốn? Hay nó có nghĩa là không thể viết mã để xác minh nó? Còn kiểm tra đệ quy thì sao? Giả sử rằng tôi có hai chương trình. Cả hai đều có lỗi, nhưng chúng không chia sẻ cùng một lỗi. Điều gì sẽ xảy ra nếu tôi chạy chúng đồng thời?

Và tất nhiên hầu hết các cuộc thảo luận đã nói về máy Turing. Điều gì về tự động giới hạn tuyến tính (máy tính thực)?


10
Tôi khá chắc chắn rằng chương trình python này thực hiện mọi thứ nó dự định làm và không còn nữa: print "Hello, World!"... bạn có thể rõ ràng hơn một chút không?
durron597

2
@ durron597: Có thị trường cho phần mềm như vậy không? Xin chào máy in thế giới, phiên bản tải lại? Bây giờ với nhiều hellos và nhiều thế giới hơn?
JensG

1
@Phoshi faugh. Có thể đủ để viết một chương trình đủ đơn giản (giả sử bằng cách sử dụng dây trên bảng mạch) để bạn có thể thấy toàn bộ phạm vi của quy trình cùng một lúc mà không có lỗi. Bạn đang tấn công các chi tiết của bình luận của tôi mà không giải quyết vấn đề chính của tôi, đó là có thể viết các chương trình cực kỳ đơn giản không có lỗi.
durron597

2
@Phoshi "Chứng minh trình thông dịch python của bạn không có lỗi." Lỗi trong việc thực hiện python không làm cho chương trình sai. Chương trình này là chính xác nếu nó thực hiện những gì nó được cho là việc triển khai Python phù hợp với đặc tả ngôn ngữ. Bất kỳ bằng chứng nào cũng lấy một số điều là tiên đề - ví dụ, bạn sẽ phải cho rằng vũ trụ sẽ tiếp tục tồn tại trong suốt quá trình thực hiện chương trình. Nếu CPython có lỗi, kết quả có thể sai, nhưng lỗi không nằm trong chương trình.
Doval

11
Không ai trong số những lý có bất cứ điều gì để làm với lỗi hay sự tồn tại của chương trình miễn phí lỗi. Chúng là những định lý về những câu hỏi có thể trả lời được bằng cách tính toán. Những định lý này cho thấy rằng có một số vấn đề không thể tính toán được và một số đề xuất toán học không thể chứng minh hoặc không được chứng minh, nhưng họ chắc chắn không nói rằng tất cả các chương trình đều có lỗi hoặc các chương trình cụ thể không thể được chứng minh là đúng.
Charles E. Grant

Câu trả lời:


18

Nó không quá nhiều đến nỗi các chương trình không thể có lỗi; thật khó để chứng minh rằng họ là như vậy, nếu chương trình bạn đang cố chứng minh là không tầm thường.

Không phải vì thiếu cố gắng, để tâm đến bạn. Loại hệ thống được cho là để cung cấp một số đảm bảo; Haskell có một hệ thống loại rất tinh vi thực hiện điều này, ở một mức độ. Nhưng bạn không bao giờ có thể loại bỏ tất cả sự không chắc chắn.

Hãy xem xét các chức năng sau:

int add(int a, int b) { return a + b; }

Điều gì có thể đi sai với chức năng này? Tôi đã biết bạn đang nghĩ gì. Giả sử rằng chúng ta đã bao phủ tất cả các căn cứ, như kiểm tra tràn, v.v ... Điều gì xảy ra nếu một tia vũ trụ tấn công bộ xử lý, khiến nó thực thi

LaunchMissiles();

thay thế?

OK, có lẽ đó là một chút giả định. Nhưng ngay cả các chức năng đơn giản như addchức năng trên cũng phải hoạt động trong môi trường mà bộ xử lý liên tục thay đổi bối cảnh, chuyển đổi giữa nhiều luồng và lõi. Trong một môi trường như thế, bất cứ điều gì cũng có thể xảy ra. Nếu bạn nghi ngờ điều này, thì hãy xem xét rằng RAM là đáng tin cậy, không phải vì nó không có lỗi, mà bởi vì nó có một hệ thống tích hợp để sửa các lỗi bit chắc chắn xảy ra.

Tôi biết bạn đang nghĩ gì. "Nhưng tôi đang nói về phần mềm, không phải phần cứng."

Có nhiều kỹ thuật có thể cải thiện mức độ tự tin của bạn rằng phần mềm hoạt động theo cách nó được yêu cầu. Lập trình chức năng là một trong số đó. Lập trình chức năng cho phép bạn lý do tốt hơn về đồng thời. Nhưng lập trình chức năng không phải là một bằng chứng, nhiều hơn các bài kiểm tra đơn vị.

Tại sao? Bởi vì bạn có những thứ gọi là trường hợp cạnh.

Và một khi bạn chỉ nhận được một chút ngoài sự đơn giản return a + b, việc chứng minh tính đúng đắn của chương trình trở nên khó khăn đáng kể .

Đọc thêm
Họ viết những thứ phù hợp
Vụ nổ Ariane 5


6
Hãy xem xét các chức năng hoàn toàn gõ-đúng: int add(int a, int b) { return a - b; }...
Donal Fellows

@DonalFellows: Đó chính xác là lý do tôi đưa vào liên kết về Ariane 5.
Robert Harvey

2
@DonalFellows - Đặc tính toán học không giải quyết được vấn đề, nó chỉ di chuyển nó đi nơi khác. Làm thế nào để bạn chứng minh rằng mô hình toán học thực sự đại diện cho khách hàng cần?
mouviciel

1
@JohnGaughan Điều đó giả định sự phụ thuộc lẫn nhau giữa các mô-đun. Với các mô-đun đã được chứng minh là đúng và được chứng minh là độc lập với nhau, bạn có thể kết hợp đệ quy chúng thành các mô-đun lớn hơn còn được gọi là infinitum quảng cáo chính xác và độc lập.
Doval

1
@JohnGaughan Nếu việc tích hợp các mô-đun gây ra lỗi thì bạn đã không chứng minh được chúng độc lập. Xây dựng bằng chứng mới từ các bằng chứng đã được thiết lập không khó hơn việc xây dựng bằng chứng từ các tiên đề. Nếu toán học trở nên khó khăn hơn theo cấp số nhân, các nhà toán học sẽ bị lừa. Bạn có thể có lỗi trong tập lệnh xây dựng của mình, nhưng đó là một chương trình riêng biệt. Không có yếu tố bí ẩn nào sai khi bạn cố gắng soạn thảo mọi thứ, nhưng tùy thuộc vào số lượng tác dụng phụ, có thể khó chứng minh rằng không có trạng thái chia sẻ.
Doval

12

Trước tiên, hãy thiết lập bối cảnh mà bạn muốn thảo luận về vấn đề này. Các lập trình viên Hỏi & Đáp tại Stack Exchange gợi ý rằng bạn rất có thể quan tâm đến sự tồn tại của các công cụ / ngôn ngữ trong thế giới thực hơn là các kết quả lý thuyết và các định lý Khoa học Máy tính .

Tôi đã đọc rất nhiều bài viết nói rằng mã không thể không có lỗi

Tôi hy vọng không, bởi vì tuyên bố như vậy là không chính xác. Mặc dù người ta thường chấp nhận rằng hầu hết các ứng dụng quy mô lớn không có lỗi với kiến ​​thức và kinh nghiệm tốt nhất của tôi.

Thông thường hơn được chấp nhận là không tồn tại (tức là tồn tại, không có khả năng) một công cụ xác định hoàn hảo liệu một chương trình được viết bằng ngôn ngữ lập trình Turing-Complete hoàn toàn không có lỗi.

Một bằng chứng không phải là một phần mở rộng trực quan của Vấn đề Ngừng, kết hợp với dữ liệu quan sát về trải nghiệm hàng ngày.

không tồn tại phần mềm có thể làm "bằng chứng của tính đúng đắn " mà xác minh rằng một chương trình đáp ứng tương ứng chính thức thông số kỹ thuật cho chương trình.

Có phải điều này ngụ ý rằng mọi chương trình sẽ có ít nhất một hành vi ngoài ý muốn?

Không. Mặc dù hầu hết các ứng dụng đã được tìm thấy có ít nhất một lỗi hoặc hành vi ngoài ý muốn.

Hay nó có nghĩa là không thể viết mã để xác minh nó?

Không, bạn có thể sử dụng thông số kỹ thuật chính thức và trợ lý chứng minh để xác minh theo thông số kỹ thuật , nhưng vì kinh nghiệm cho thấy lỗi vẫn có thể tồn tại trong toàn bộ hệ thống, chẳng hạn như các yếu tố bên ngoài đặc tả - trình dịch & phần cứng mã nguồn, và hầu hết các lỗi thường gặp trong các thông số kỹ thuật chính mình.

Để biết thêm chi tiết, xem Coq là một công cụ / ngôn ngữ / hệ thống như vậy.

Còn kiểm tra đệ quy thì sao?

Tôi không biết. Tôi không quen thuộc với nó và tôi không chắc đó là vấn đề tính toán hay vấn đề tối ưu hóa trình biên dịch.


1
+1 vì là người đầu tiên nói về thông số kỹ thuật chính thức và trợ lý chứng minh. Đây là một điểm rất quan trọng, điều còn thiếu trong các câu trả lời trước.
Arseni Mourzenko

6

Tôi muốn hỏi, nó có ngụ ý rằng mọi mã sẽ nhận được ít nhất một hành vi ngoài ý muốn?

Không. Chương trình chính xác có thể và được viết. Xin lưu ý bạn, một chương trình có thể đúng, nhưng việc thực thi có thể thất bại do, ví dụ, hoàn cảnh vật lý (như người dùng Robert Harvey đã viết trong câu trả lời của anh ta ở đây ), nhưng đây là một vấn đề khác biệt: mã chương trình đó vẫn đúng. Nói chính xác hơn, lỗi không phải do lỗi hoặc lỗi trong chính chương trình, mà là ở máy bên dưới thực thi nó (*).

(*) Tôi đang mượn các định nghĩa về lỗi , lỗilỗi từ trường độ tin cậy tương ứng là lỗi tĩnh, trạng thái bên trong không chính xác và hành vi quan sát bên ngoài không chính xác theo thông số kỹ thuật của nó (xem <bất kỳ giấy nào từ trường đó>) .

Hoặc, điều đó có nghĩa là tôi không thể viết mã, điều này sẽ kiểm tra nó?

Tham khảo trường hợp chung trong tuyên bố trên và bạn đã đúng.

Bạn có thể viết chương trình kiểm tra xem chương trình X cụ thể có đúng không. Ví dụ, nếu bạn xác định một chương trình "hello world" là một trong hai hướng dẫn theo thứ tự, cụ thể là print("hello world")exit, bạn có thể viết một chương trình mà kiểm tra nếu đầu vào của nó là một chương trình gồm có hai hướng dẫn những theo thứ tự, do đó báo cáo nếu nó là một có đúng chương trình "xin chào thế giới" hay không.

Những gì bạn không thể làm bằng cách sử dụng các công thức hiện tại là viết một chương trình để kiểm tra xem có bất kỳ chương trình tùy ý nào dừng lại hay không, điều này hàm ý việc không thể kiểm tra tính chính xác trong các trường hợp chung.


4

Chạy hai hoặc nhiều biến thể của cùng một chương trình là một kỹ thuật chống lỗi nổi tiếng được gọi là lập trình biến thể N (hoặc phiên bản N). Đó là một sự thừa nhận về sự hiện diện của các lỗi trong phần mềm.

Thông thường các biến thể này được mã hóa bởi các nhóm phát triển khác nhau, sử dụng các trình biên dịch khác nhau và đôi khi được thực thi trên các CPU khác nhau với các HĐH khác nhau. Kết quả được bỏ phiếu trước khi là đầu ra cho người dùng. Boeing và Airbus thích loại kiến ​​trúc này.

Hai liên kết yếu vẫn còn, dẫn đến lỗi chế độ phổ biến:

  • Chỉ có một đặc điểm kỹ thuật.
  • hệ thống bỏ phiếu là duy nhất hoặc phức tạp.

5
Tôi tin rằng NASA hoặc chương trình không gian khác đã gợi ý rằng biến thể N gặp phải vấn đề mà các lập trình viên quá thường nghĩ giống nhau và do đó kết thúc việc viết độc lập gần các chương trình tương đương với các lỗ hổng phổ biến khi lỗ hổng vượt quá mức tầm thường nhất. Ví dụ: tham khảo cùng một thông tin tham khảo (xem lỗi tồn tại lâu trong tìm kiếm nhị phân ), có xu hướng sử dụng cùng một thuật toán và thực hiện các loại lỗi tương tự.
mctylr

@mctylr - Đó là một điểm rất tốt. Nhưng thực ra, cho đến gần đây, không có đủ chỗ trong bộ nhớ để lưu trữ nhiều hơn một biến thể của phần mềm trên tàu vũ trụ. Câu trả lời của họ là kiểm tra, kiểm tra, kiểm tra, rửa sạch, lặp lại.
mouviciel

Chương trình tàu con thoi sử dụng cấu hình bỏ phiếu ba hệ thống độc lập. Bất kỳ phiếu bất đồng ý nghĩa nào (hoặc, thực sự, được đề xuất) rằng hệ thống đó không còn đúng nữa và đã bị lấy ngoại tuyến.

4

Một chương trình có một số đặc điểm kỹ thuật và chạy trong một số môi trường.

(tia vũ trụ dụ trong những người khác câu trả lời thay đổi addđể FireMissiles có thể được coi là một phần của "môi trường")

Giả sử bạn có thể chính thức chỉ định hành vi dự định của chương trình (tức là đặc điểm kỹ thuật của nó) và môi trường của nó, đôi khi bạn có thể chính thức chứng minh rằng chương trình đó - không có lỗi chính xác (vì vậy hành vi hoặc đầu ra của nó tôn trọng việc chính thức hóa đặc tả của nó trong việc chính thức hóa của môi trường của nó).

Cụ thể, bạn có thể sử dụng các máy phân tích nguồn tĩnh âm thanh, ví dụ như Frama-C .

(nhưng tình trạng hiện tại của nghệ thuật phân tích như vậy không cho phép phân tích toàn bộ chương trình & bằng chứng về các chương trình quy mô lớn như trình biên dịch GCC hoặc trình duyệt Firefox hoặc nhân Linux; và tôi tin rằng những bằng chứng đó sẽ không xảy ra trong đời tôi Tôi sinh năm 1959)

Tuy nhiên, những gì bạn đã chứng minh là hành vi chính xác của chương trình ghi một số đặc tả cụ thể trong một số (lớp) môi trường.

Nói một cách thực tế, bạn có thể (và NASA hoặc ESA có thể muốn) chứng minh rằng một số phần mềm tàu ​​vũ trụ là "không có lỗi" với một số đặc điểm kỹ thuật chính xác - và chính thức hóa. Nhưng điều đó không có nghĩa là hệ thống của bạn sẽ luôn hoạt động như bạn muốn.

Nói một cách đơn giản hơn, nếu robot tàu vũ trụ của bạn gặp một số ET và bạn không chỉ định điều đó, thì không có cách nào để robot của bạn hoạt động như bạn thực sự muốn ....

Đọc thêm các mục blog của J.Pitrat .

BTW, Vấn đề dừng hoặc định lý của Gôdel có lẽ cũng áp dụng cho bộ não con người, hoặc thậm chí cả loài người.


Có lẽ một ví dụ tốt của một SEU thay đổi cuộc gọi đến Addđể LaunchMissilessẽ là một SEU thay đổi một số giá trị dữ liệu mà cuối cùng dẫn đến một cuộc gọi sai lầm để LaunchMissiles. SEU là một vấn đề với các máy tính đi vào không gian. Đây là lý do tại sao tàu vũ trụ hiện đại thường bay nhiều máy tính. Điều này thêm một loạt các vấn đề mới, quản lý đồng thời và dự phòng.
David Hammen

3

Có phải điều này ngụ ý rằng mọi chương trình sẽ có ít nhất một hành vi ngoài ý muốn?

Không.

Vấn đề tạm dừng nói rằng không thể viết một chương trình kiểm tra xem mọi chương trình có dừng lại trong một khoảng thời gian hữu hạn hay không. Điều này không có nghĩa là không thể viết một chương trình có thể phân loại một số chương trình là tạm dừng, một số khác là không tạm dừng. Điều đó có nghĩa là luôn tồn tại một số chương trình mà máy phân tích tạm dừng không thể phân loại theo cách này hay cách khác.

Các định lý không hoàn chỉnh của Gôdel có một vùng màu xám tương tự như chúng. Với một hệ thống toán học đủ phức tạp, sẽ tồn tại một số tuyên bố được đưa ra trong bối cảnh của hệ thống đó mà tính xác thực không thể được đánh giá. Điều này không có nghĩa là các nhà toán học phải từ bỏ ý tưởng về bằng chứng. Bằng chứng vẫn là nền tảng của toán học.

Một số chương trình có thể được chứng minh là chính xác. Nó không dễ dàng, nhưng nó có thể được thực hiện. Đó là mục tiêu của việc chứng minh định lý chính thức (một phần của phương pháp chính thức). Các định lý không hoàn chỉnh của Gôdel thực hiện ở đây: Không phải tất cả các chương trình đều có thể được chứng minh là đúng. Điều đó không có nghĩa là hoàn toàn vô ích khi sử dụng các phương pháp chính thức bởi vì một số chương trình thực sự có thể được chứng minh là chính xác.

Lưu ý: Các phương thức chính thức loại trừ khả năng tia vũ trụ tấn công bộ xử lý và thực thi launch_missiles()thay vì a+b. Họ phân tích các chương trình trong bối cảnh của một cỗ máy trừu tượng chứ không phải là những cỗ máy thực sự chịu sự tác động của các sự kiện đơn lẻ như tia vũ trụ của Robert Harvey.


1

Có rất nhiều câu trả lời hay ở đây, nhưng tất cả đều có vẻ xoay quanh điểm quan trọng, đó là: tất cả các định lý này đều có cấu trúc tương tự và nói những điều tương tự, và những gì họ nói không phải là "không thể viết đúng chương trình"(đối với một số giá trị cụ thể của 'đúng' và 'chương trình' mà thay đổi theo từng trường hợp), nhưng những gì họ làm nói là 'nó không thể ngăn chặn ai đó viết một chương trình không chính xác mà chúng ta không thể chứng minh là không chính xác' ( Vân vân).

Lấy ví dụ cụ thể về vấn đề tạm dừng, sự khác biệt trở nên rõ ràng hơn: rõ ràng có những chương trình tạm dừng và các chương trình khác có thể chứng minh là không bao giờ dừng lại. Rằng có một loại chương trình thứ ba mà hành vi của chúng không thể được xác định theo cách nào đó không phải là vấn đề nếu tất cả những gì chúng ta muốn làm là viết một chương trình tạm dừng có thể chứng minh được, vì chúng ta có thể tránh việc viết một chương trình thuộc về lớp đó.

Điều này cũng đúng với định lý của Rice. Có, đối với bất kỳ tài sản không tầm thường nào của chương trình, chúng tôi có thể viết chương trình không thể chứng minh tài sản đó là đúng hoặc sai; chúng tôi cũng có thể tránh viết một chương trình như vậy bởi vì chúng tôi có thể xác định xem một chương trình có thể chứng minh được hay không.


0

Câu trả lời của tôi sẽ từ góc độ kinh doanh trong thế giới thực và những thách thức mà mọi nhóm phát triển phải đối mặt. Những gì tôi thấy trong câu hỏi này và rất nhiều câu trả lời thực sự là về việc kiểm soát khuyết điểm.

Mã có thể không có lỗi. Lấy bất kỳ mẫu mã "Hello World" nào cho bất kỳ ngôn ngữ lập trình nào và chạy trên nền tảng mà nó dự định và nó sẽ hoạt động ổn định và tạo ra kết quả mong muốn. Có kết thúc bất kỳ lý thuyết về sự bất khả thi của mã là không có lỗi.

Các lỗi tiềm ẩn xuất hiện khi logic trở nên phức tạp hơn. Ví dụ Hello World đơn giản không có logic và thực hiện cùng một điều tĩnh mỗi lần. Ngay khi bạn thêm hành vi động điều khiển logic là những gì giới thiệu sự phức tạp dẫn đến các lỗi. Bản thân logic có thể bị thiếu sót hoặc dữ liệu được nhập vào logic có thể thay đổi theo cách logic không xử lý.

Một ứng dụng hiện đại cũng phụ thuộc vào các lớp thư viện thời gian chạy, CLR, phần mềm trung gian, cơ sở dữ liệu, v.v.

Cuối cùng, chuỗi ứng dụng / hệ thống mà ứng dụng tiêu thụ dữ liệu cung cấp logic của nó là tất cả các nguồn lỗi tiềm ẩn trong logic của chúng hoặc trong phần mềm ngăn chặn các logic chạy trên đầu hoặc các hệ thống ngược dòng mà nó tiêu thụ dữ liệu.

Các nhà phát triển không kiểm soát 100% mọi hoạt động chuyển động hỗ trợ logic cho ứng dụng của họ. Thật ra, chúng tôi không kiểm soát được nhiều. Đó là lý do tại sao kiểm thử đơn vị là quan trọng và quản lý cấu hình và thay đổi là các quy trình quan trọng mà chúng ta không được bỏ qua hoặc lười biếng / cẩu thả.

Ngoài ra, các thỏa thuận được ghi lại giữa ứng dụng của bạn tiêu thụ dữ liệu từ một nguồn ngoài tầm kiểm soát của bạn, xác định định dạng và thông số kỹ thuật cụ thể cho dữ liệu được truyền, cũng như mọi giới hạn hoặc ràng buộc mà hệ thống của bạn chịu trách nhiệm để đảm bảo đầu ra nằm trong những giới hạn đó.

Trong ứng dụng công nghệ phần mềm trong thế giới thực, bạn sẽ không thể làm cho nó bay được bằng cách giải thích cho doanh nghiệp tại sao các ứng dụng về mặt lý thuyết không thể không có lỗi. Các cuộc thảo luận về bản chất này giữa công nghệ và doanh nghiệp sẽ không bao giờ xảy ra ngoại trừ hậu quả của sự cố công nghệ ảnh hưởng đến khả năng kiếm tiền của doanh nghiệp, ngăn ngừa mất tiền và / hoặc giữ cho mọi người sống. Câu trả lời cho "làm thế nào điều này có thể xảy ra" không thể là "hãy để tôi giải thích lý thuyết này để bạn hiểu."

Về mặt tính toán lớn mà về mặt lý thuyết có thể mất mãi mãi để thực hiện tính toán và nhận được kết quả, một ứng dụng không thể hoàn thành và trả về với kết quả - đó là một lỗi. Nếu bản chất của tính toán là rất tốn thời gian và tính toán chuyên sâu, bạn thực hiện yêu cầu đó và cung cấp phản hồi cho người dùng về cách thức / thời điểm họ có thể truy xuất kết quả và khởi động các luồng song song để xử lý nó. Nếu điều này cần diễn ra nhanh hơn có thể được thực hiện trên một máy chủ và kinh doanh đủ quan trọng, thì bạn hãy mở rộng nó ra càng nhiều hệ thống càng cần thiết. Đây là lý do tại sao đám mây rất hấp dẫn và khả năng quay các nút để đảm nhận công việc và quay chúng xuống khi hoàn thành.

Nếu khả năng tồn tại để nhận được một yêu cầu mà không có sức mạnh tính toán nào có thể hoàn thành, thì nó không nên tồn tại ở đó với vô số quy trình kinh doanh đang chờ câu trả lời cho những gì doanh nghiệp cho là vấn đề hữu hạn.


-2

Tôi không tin rằng mã không bao giờ có lỗi 100% vì mã không bao giờ thực sự kết thúc. Bạn luôn có thể cải thiện những gì bạn viết.

Lập trình là một lĩnh vực khoa học và toán học trong trường hợp cả hai là vô tận. Điều tuyệt vời khi trở thành một nhà phát triển là công việc của chúng tôi là vô tận.

Có hàng ngàn cách để viết một dòng mã. Ý tưởng là viết phiên bản tối ưu nhất của dòng mã đó nhưng điều đó có thể không có lỗi. Bug free đề cập đến ý tưởng rằng mã của bạn không thể phá vỡ và tất cả mã có thể bị phá vỡ ở một mức độ hoặc phương pháp nào đó.

Vì vậy, mã có thể được hiệu quả? Đúng.
Mã có thể được tối ưu hóa vô tận? Đúng.
Mã có thể không có lỗi? Không, bạn chỉ đơn giản là chưa tìm được cách phá vỡ nó.
Điều đó đang được nói, nếu bạn cố gắng cải thiện bản thân và thực hành viết mã, mã của bạn sẽ khó bị phá vỡ.


bài này khá khó đọc (tường văn bản). Bạn có phiền chỉnh sửa ing nó thành một hình dạng tốt hơn?
gnat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.