Page 1
goupee.vn goupee.com HỆ THỐNG ĐÀO TẠO LẬP TRÌNH HIỆN ĐẠI Sách HỌC TIẾNG ANH SONG NGỮ cho LẬP TRÌNH VIÊN (Phần 1) Phiên bản 1.0 - Tháng 02/2022fb.com/goupee.vn
Génération de l'aperçu...
goupee.vn goupee.com HỆ THỐNG ĐÀO TẠO LẬP TRÌNH HIỆN ĐẠI Sách HỌC TIẾNG ANH SONG NGỮ cho LẬP TRÌNH VIÊN (Phần 1) Phiên bản 1.0 - Tháng 02/2022fb.com/goupee.vn
goupee.vn goupee.com w h i l e ( ! ( s u c c e s sw h i l e ( ! ( s u c c e s s == t r y ( ) ) ) ;t r y ( ) ) ) ; LỜI MỞ ĐẦU Lập trình viên muốn giỏi tiếng Anh "như giỏi code", ngoài những phương pháp học đơn thuần như xem phim, học qua bài hát, video thì việc học qua những bài mẫu song ngữ và đã có highlight cụm từ quan trọng cũng vô cùng thú vị và hiệu quả. "Sách Song Ngữ Cho Lập Trình Viên (Phần 1)" được biên tập theo chương "Principles, Patterns, and Practices" từ cuốn sách "Agile Software Development" của tác giả Robert C. Martin. Nội dung kể về nhân vật Alphonse, một sinh viên IT mới ra trường và được nhận vào thực tập ở công ty của ông C (chính tác giả). Thông qua những câu chuyện, tình huống, bài học khi mới đặt chân vào ngành công nghiệp phần mềm được kể lại từ dưới chính góc nhìn Alphonse, các bạn có thể: - Được tiếp cận với ngôn ngữ chuẩn hơn - Được mở mang hiểu biết thông qua nguồn kiến thức, ý tưởng của tác giả từ các bài mẫu Anh - Việt - Vừa được tiếp xúc với tiếng Anh, vừa được ôn lại những bài toán lập trình cơ bản Mặc dù đội ngũ biên tập của CodeGym đã nỗ lực trong việc hoàn thiện cuốn sách này với tiêu chí dễ hiểu, khoa học và hiệu quả, tuy nhiên khó để tránh khỏi các sai sót trong quá trình biên soạn. Vì vậy, chúng mình rất mong nhận được các ý kiến phản hồi và đóng góp của mọi người thông qua email marketing@codegym.vn. Cảm ơn các bạn đã tải và đọc "Sách Song Ngữ Cho Lập Trình Viên (Phần 1)". Đừng quên chia sẻ tài liệu này để chúng mình có thêm động lực biên soạn các phần tiếp theo của cuốn sách nhé. Thân, Ban biên tập. fb.com/goupee.vn
goupee.vn goupee.com w h i l e ( ! ( s u c c e s sw h i l e ( ! ( s u c c e s s == t r y ( ) ) ) ;t r y ( ) ) ) ; LỜI MỞ ĐẦU 1 Thợ lành nghề #1 - Mở đầu Thảm họa 3 Thợ lành nghề #2 - Chế độ ăn kiêng tăng cường 8 Thợ lành nghề #3:Tính rõ ràng và cộng tác 16 Thợ lành nghề #4 - Bài kiểm tra tính kiên nhẫn 24 Thợ lành nghề #5: Bước nhỏ 30 Danh sách từ vựng tổng hợp 45 PHỤ LỤC: TÀI NGUYÊN LẬP TRÌNH 52 www.codegym.vnfb.com/goupee.vn/ Page 02
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; Thợ lành nghề #1 - Mở đầu Thảm họa 13 February 2002, Ngày 13 tháng 2 năm 2002. Dear Diary, Nhật ký thân mến, Today was a disaster – I really messed Ngày hôm nay đúng là một thảm hoạ it up. I wanted so much to impress the – Tôi đã làm hỏng mọi chuyện. Tôi rất journeymen here, but all I did was muốn gây ấn tượng với các ngài “cựu make a mess. học việc” ở đây nhưng rốt cuộc chỉ làm rối tung cả lên. It was my first day on the job as an Ðó là ngày đầu tiên tôi được làm một apprentice to Mr. C. I was lucky to get chân thực tập của ông C. Tôi quả rất this apprenticeship. Mr. C is a may mắn mới có được vị trí này. Ông well-recognized master of software C là một người có tiếng trong làng development. The competition for this phát triển phần mềm. Cuộc thi để position was fierce. giành được chân học việc này đúng là nảy lửa. Mr. C’s apprentices often become Những người theo học ông C thường journeymen in high demand. It means sẽ trở thành những người thợ lành something to have worked with Mr. C. nghề được đánh giá cao. Ðiều này có nghĩa được làm việc với ông C có giá trị rõ ràng. I thought I was going to meet him Tôi cứ ngỡ hôm nay sẽ được gặp ông today, but instead a journeyman C, nhưng tôi bị gã “cựu học việc” Jerry named Jerry took me aside. He told níu qua một bên. Gã bảo ông C luôn me that Mr. C always puts his luôn yêu cầu phần định hướng cho apprentices through an orientation người học việc trong những ngày đầu. www.codegym.vnfb.com/goupee.vn/ Page 03
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; during their first few days. He said this Gã nói ông C nhất quyết cho rằng orientation was to introduce phần định hướng này rất thiết thực với apprentices to the practices that Mr. C người học việc, và chất lượng mã insists we use, and to the level of nguồn mà ông mong đợi ở họ. quality he expects from our code. This excited me greatly. It was an Tôi háo hức kinh khủng. Ðây là cơ hội opportunity to show them how good để tôi cho họ thấy mình là một tay lập a programmer I am. So I told Jerry I trình giỏi cỡ nào. Thế là tôi bảo Jerry couldn’t wait to start. He responded by tôi không chờ được nữa. Gã đáp lại asking me to write a simple program sự háo hức của tôi bằng cách bảo tôi for him. He wanted me to use the thử viết một chương trình đơn giản. Sieve of Eratosthenes to calculate Gã muốn tôi dùng Sàng Eratosthenes prime numbers. He told me to have (Sieve) để tính các số nguyên tố. Gã the program, including all unit tests, còn bảo tôi phải chuẩn bị xong ready for review just after lunch. chương trình bao gồm trọn bộ các kiểm thử đơn vị để soát sau buổi ăn trưa. This was great! I had almost four Thật tuyệt! Tôi có gần 4 giờ đồng hồ hours to whip together a simple để “xào nấu” một chương trình đơn program like the Sieve. I am giản như Sieve. Tôi quyết tâm làm một determined to do a really impressive chương trình thật ấn tượng. Tôi đã job. Listing 1 shows what I wrote. I viết mã ở Mã dẫn 1. Tôi nắm chắc là made sure it was well commented, chương trình được chú thích cẩn and neatly formatted. thận và trình bày gọn gàng. Mã dẫn 1 /** * This class generates prime numbers up to a user-specified maximum. * The algorithm used is the Sieve of Eratosthenes. <p> Eratosthenes of Cyrene, b.c. * 276 BC, Cyrene, Libya; d.c.194 BC,Alexandria. He was the first man to * calculate the circumference of the Earth, and was also known for working on * calendars with leap years and running the library at Alexandria.</p> * The * algorithm is quite simple: Given an array of integers starting at 2, cross * out all multiples of 2. Find the next uncrossed integer, and cross out all of * its multiples. * Repeat until you have passed the square root of the maximum * value. * @authorAlphonse, www.codegym.vnfb.com/goupee.vn/ Page 04
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; * @version 13 Feb 2002 atp */ import java.util.*; public class GeneratePrimes { /** * @param maxValue is the generation limit. */ public static int[] generatePrimes(int maxValue) { if (maxValue >= 2) { // the only valid case // declarations int s = maxValue + 1; // size of array boolean[] f = new boolean[s]; int i; // initialize array to true. for (i = 0; i < s; i++) { f[i] = true; } // get rid of known non-primes. f[0] = f[1] = false; // sieve int j; for (i = 2; i < Math.sqrt(s) + 1; i++) { if (f[i]) { // if i is uncrossed, cross its multiples. for (j = 2 * i; j < s; j += i) f[j] = false; // multiple is not prime } } // how many primes are there? int count = 0; for (i = 0; i < s; i++) { if (f[i]) { count++; // bump count. } } int[] primes = new int[count]; // move the primes into the result. for (i = 0, j = 0; i < s; i++) { if (f[i]) // if prime www.codegym.vnfb.com/goupee.vn/ Page 05
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; { primes[j++] = i; } } return primes; // return the primes. } else // maxValue < 2 { return new int[0]; // return null array if bad input. } } } Then I wrote a unit test for Sau đó tôi viết một kiểm thử đơn vị GeneratePrimes. It is shown in Listing cho GeneratePrimes. Xem ở mã ở Mã 2. It uses the JUnit framework as Jerry dẫn 2. Ðoạn mã này dùng khung làm had instructed. It takes a statistical việc JUnit như Jerry đã hướng dẫn. approach; checking to see if the Nó tiếp cận kiểu thống kê; kiểm tra generator can generate primes up to xem cái “generator” có thể tạo ra các 0, 2, 3, and 100. số nguyên tới 0, 2, 3 và 100. In the first case there should be no Trong trường hợp thứ nhất hẳn primes. In the second there should be không có số nguyên nào cả. Trong one prime, and it should be 2. In the trường hợp thứ hai phải có một số third there should be two primes and nguyên và nó phải là số 2. Trường they should be 2 and 3. In the last hợp thứ ba có hai số nguyên và chúng case there should be 25 primes, the là số 2 và 3. Trường hợp cuối phải là last of which is 97. 25 số nguyên và số cuối phải là 97. If all these tests pass, then I assumed Nếu các kiểm thử đều đạt, thì tôi giả that the generator was working. I định là “generator” chạy. Tôi e rằng doubt this is foolproof, but I couldn’t khó có thể tin cậy tuyệt đối cách ở think of a reasonable scenario where trên, nhưng tôi không nghĩ ra được these tests would pass and yet the một kịch bản có thể xảy ra nào mà function would fail. một hàm sai nhưng các bước kiểm thử đúng. Mã dẫn 2 import junit.framework.*; import java.util.*; public class TestGeneratePrimes extends TestCase { public static void main(String args[]) { junit.swingui.TestRunner.main(new String[]{"TestGeneratePrimes"}); www.codegym.vnfb.com/goupee.vn/ Page 06
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; } public TestGeneratePrimes(String name) { super(name); } public void testPrimes() { int[] nullArray = GeneratePrimes.generatePrimes(0); assertEquals(nullArray.length, 0); int[] minArray = GeneratePrimes.generatePrimes(2); assertEquals(minArray.length, 1); assertEquals(minArray[0], 2); int[] threeArray = GeneratePrimes.generatePrimes(3); assertEquals(threeArray.length, 2); assertEquals(threeArray[0], 2); assertEquals(threeArray[1], 3); int[] centArray = GeneratePrimes.generatePrimes(100); assertEquals(centArray.length, 25); assertEquals(centArray[24], 97); } } I got all this to work in about an hour. Tôi làm việc này mất khoảng một giờ Jerry didn't want to see me until after đồng. Jerry không muốn gặp tôi trước lunch, so I spent the rest of my time bữa ăn trưa, bởi thế, tôi dành trọn bộ reading the Design Patterns book that thời gian còn lại đọc cuốn Design Jerry gave me. Patterns mà Jerry đưa cho. After lunch I stopped by Jerry’s office, Sau buổi ăn trưa, tôi ghé văn phòng and told him I was done with the của Jerry và cho gã biết tôi đã thực program. He looked up at me with a hiện xong chương trình. Gã nhìn tôi và funny grin on his face and said: cười, hắn nói: “Ðược lắm, hãy xem “Good, let's go check it out.” thử nó thế nào.” He took me out into the lab and sat me Sau bữa trưa, gã dẫn tôi vào phòng down in front of a workstation. He sat máy và cho tôi ngồi trước một máy. next to me. He asked me to bring up Gã ngồi bên cạnh tôi và yêu cầu tôi my program on this machine. So I đưa chương trình của tôi vào máy navigated to my laptop on the network này. Thế là tôi kết nối laptop với mạng and brought up the source files. và chuyển mã nguồn lên. www.codegym.vnfb.com/goupee.vn/ Page 07
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; Jerry looked at the two source files for Jerry xem xét hai mã nguồn chừng about five minutes. Then he shook năm phút rồi gã lắc đầu và bảo: “Mày his head and said: “You can’t show không thể đưa những cái này cho ông something like this to Mr. C! If I let him C xem được! Nếu tao để ông ấy xem see this, he’d probably fire both of us. mấy cái này, thì ông sẽ sa thải cả hai. He’s not a very patient man.” Ông ấy không phải là người kiên nhẫn đâu.” I was startled, but managed to keep Tôi đánh thót một cái nhưng cố giữ my cool enough to ask: “What’s bình tĩnh và hỏi gã: “Vậy nó sai chỗ wrong with it?” nào?” Jerry sighed. “Let's walk through this Jerry thở dài và nói: “Tụi mình sẽ together,” he said. “I’ll show you, point lược qua đống này. Tao sẽ hướng by point, how Mr. C wants things dẫn chi tiết cho mày cách ông C done.” muốn.” “It seems pretty clear,” he continued, “Khá là rõ ràng”, gã tiếp tục, “rằng “that the main function wants to be nên tách hàm main thành ba hàm three separate functions. The first riêng biệt. Hàm thứ nhất khởi tạo tất initializes all the variables and sets up cả các biến và thiết lập cái “sieve”. the sieve. The second actually Hàm thứ hai thực sự thi hành cái executes the sieve, the third loads “sieve” và hàm thứ ba tải kết quả của the sieved results into an integer “sieve” vào một dãy số nguyên.” array.” I could see what he meant. There Tôi nhận ra được ý gã. Có ba khái were three concepts which were niệm chôn trong cái hàm đó. Tuy vậy, buried in that function. Still, I didn’t tôi không biết gã muốn tôi phải làm gì. see what he wanted me to do about it. Gã nhìn tôi một lúc, rõ ràng là đang He looked at me for a while, clearly đợi xem tôi phản ứng sao. Nhưng rốt expecting me to do something. But cuộc gã thở dài, lắc đầu và…. finally he heaved a sigh, shook his head, and... Thợ lành nghề #2 - Chế độ ăn kiêng tăng cường and continued. “To expose these và tiếp tục. “Ðể diễn tả rõ hơn ba khái three concepts more clearly, I want niệm này, tao muốn mày tách chúng www.codegym.vnfb.com/goupee.vn/ Page 08
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; you to extract them into three ra thành ba hàm riêng biệt. Ðồng thời separate methods. Also get rid of all bỏ hết những chú thích không cần the unnecessary comments and pick thiết và tìm một cái tên khá hơn cho a better name for the class. When you lớp. Khi làm xong những thứ đó, mày are done with that, make sure all the phải bảo đảm là những cái kiểm thử tests still run.” vẫn chạy được.” You can see what I did in Listing 3. I’ve Các bạn có thể thấy những gì tôi đã marked my changes in bold, just like làm trong Mã dẫn 3. Tôi in đậm để Martin Fowler does in his Refactoring đánh dấu những thay đổi, tương tự book. I changed the name of the class như Martin Fowler trình bày trong to a noun, got rid of all the comments cuốn Tái cấu trúc. Tôi đổi tên lớp about Eratosthenes, and made three thành một danh từ, bỏ hết những chú methods out of the three concepts in thích về Eratosthenes và tạo ra ba the generatePrimes function. hàm tương ứng với ba khái niệm trong hàm generatePrimes. Extracting the three functions forced Việc tách thành ba hàm bắt tôi phải me to promote some of the variables đưa một số biến cục bộ của hàm of the function to static fields of the thành thuộc tính của lớp. Jerry nói class. Jerry said that this made it cách này thể hiện rõ hơn những biến much clearer which variables are nào là cục bộ và biến hàm nào có local and which have wider influence. ảnh hưởng rộng hơn. Mã dẫn 3. PrimeGenerator.java, phiên bản 2 PrimeGenerator.java, phiên bản 2 /** * This class Generates prime numbers up to a user specified maximum. The * algorithm used is the Sieve of Eratosthenes. Given an array of integers * starting at 2: Find the first uncrossed integer, and cross out all its * multiples. Repeat until the first uncrossed integer exceeds the square root * of the maximum value. */ import java.util.*; public class PrimeGenerator { private static int s; private static boolean[] f; private static int[] primes; www.codegym.vnfb.com/goupee.vn/ Page 09
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; public static int[] generatePrimes(int maxValue) { if (maxValue < 2) { return new int[0]; } else { initializeSieve(maxValue); sieve(); loadPrimes(); return primes; // return the primes } } private static void loadPrimes() { int i; int j; // how many primes are there? int count = 0; for (i = 0; i < s; i++) { if (f[i]) { count++; // bump count. } } primes = new int[count]; // move the primes into the result for (i = 0, j = 0; i < s; i++) { if (f[i]) // if prime { primes[j++] = i; } } } private static void sieve() { int i; int j; for (i = 2; i < Math.sqrt(s) + 1; i++) { www.codegym.vnfb.com/goupee.vn/ Page 10
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; if (f[i]) // if i is uncrossed, cross out its multiples. { for (j = 2 * i; j < s; j += i) { f[j] = false; // multiple is not prime } } } } private static void initializeSieve(int maxValue) { // declarations s = maxValue + 1; // size of array f = new boolean[s]; int i; // initialize array to true. for (i = 0; i < s; i++) { f[i] = true; } // get rid of known non-primes f[0] = f[1] = false; } } Jerry told me that this was a little Jerry bảo tôi mã nguồn này hơi lộn messy, so he took the keyboard and xộn, nên gã giành lấy bàn phím và chỉ showed me how to clean it up. cho tôi cách dọn dẹp. Listing 4 shows what he did. First he Mã dẫn 4 minh hoạ những gì gã đã got rid of the s variable in làm. Đầu tiên gã vứt đi biến cục bộ s initializeSieve and replaced it with trong initializeSieve và thay thế nó f.length. Then he changed the names bằng f.length. Sau đó gã đổi tên của of the three functions to something he ba hàm cho rõ nghĩa hơn. Cuối cùng said was a bit more expressive. gã sắp xếp lại cái “bộ lòng” Finally he rearranged the innards of initializeArrayOfIntegers (từ initializeArrayOfIntegers (née initializeSieve) để cho dễ đọc hơn một initializeSieve) to be a little nicer to chút. Các cái kiểm thử vẫn chạy tốt. read. The tests all still ran. www.codegym.vnfb.com/goupee.vn/ Page 11
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; PrimeGenerator.java, phiên bản 3 (một phần) public class PrimeGenerator { private static boolean[] f; private static int[] result; public static int[] generatePrimes(int maxValue) { if (maxValue < 2) { return new int[0]; } else { initializeArrayOfIntegers(maxValue); crossOutMultiples(); putUncrossedIntegersIntoResult(); return result; } } private static void initializeArrayOfIntegers(int maxValue) { f = new boolean[maxValue + 1]; f[0] = f[1] = false; //neither primes nor multiples. for (int i = 2; i < f.length; i++) { f[i] = true; } } I had to admit, this was a bit cleaner. Tôi phải công nhận là mã nguồn này I’d always thought it was a waste of rõ ràng hơn một chút. Trước giờ tôi time to give functions long descriptive nghĩ việc đặt tên dài có tính mô tả names, but his changes really did cho hàm là phung phí thời giờ, nhưng make the code more readable. những điều chỉnh của gã quả thật làm cho mã nguồn dễ đọc hơn. Next Jerry pointed at Tiếp theo Jerry trỏ vào crossOutMultiples. He said he thought crossOutMultiples và nói là gã nghĩ có the if(f[i] == true) statements could be thể làm những lệnh if(f[i] == true) dễ made more readable. I thought about đọc hơn nữa. Tôi nghĩ về điểm này it for a minute. The intent of those chừng một phút. Ý định của những statements was to check to see if i lệnh này là kiểm tra xem liệu i có chưa was uncrossed; so I changed the bị loại; thế là tôi đổi tên của f thành name of f to unCrossed. unCrossed. www.codegym.vnfb.com/goupee.vn/ Page 12
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; Jerry said that this was better, but still Jerry nói mã này được hơn nhưng gã wasn’t pleased with it because it led to vẫn chưa hài lòng vì nó dẫn đến khả double negatives like unCrossed[i] = năng phủ định kép như unCrossed[i] false. So he changed the name of the = false. Bởi thế gã đổi tên mảng thành array to isCrossed and changed the isCrossed và đổi ý nghĩa của mọi giá sense of all the booleans. Then he ran trị luận lý. Sau đó gã chạy mọi kiểm all the tests. thử. Jerry got rid of the initialization that Jerry xóa mã gán true cho set isCrossed[0] and isCrossed[1] to isCrossed[0] và isCrossed[1]. Gã nói true. He said it was good enough to điều này đủ tốt để đảm bảo không có just make sure that no part of the phần nào của hàm dùng mảng function used the isCrossed array for isCrossed với chỉ số nhỏ hơn 2. Mọi indexes less than 2. The tests all still kiểm thử vẫn chạy. ran. Jerry extracted the inner loop of the Jerry tách phần lặp bên trong của crossOutMultiples function and called hàm crossOutMultiples ra và đặt tên là it crossOutMultiplesOf. He said that crossOutMultipleOf. Gã bảo rằng các statements like if (isCrossed[i] == lệnh tương tự như if (isCrossed[i] == false) were confusing so he created a false) dễ gây nhầm lẫn, nên gã tạo function called notCrossed and hàm có tên notCrossed và thay cụm if changed the if statement to if thành if (notCrossed(i)). Kế tiếp gã (notCrossed(i)). Then he ran the tests. chạy lại mấy kiểm thử. Then Jerry asked me what that square Sau đó Jerry hỏi tôi ý nghĩa của căn root was all about. I spent a bit of time bậc hai tôi đã dùng. Tôi tốn ít thời giờ writing a comment that tried to explain viết chú thích cho lý do cần phải lặp why you only have to iterate up to the lại cho đến căn bậc hai của độ dài square root of the array size. mảng. I tried to emulate Jerry by extracting Tôi cố làm theo Jerry bằng cách tách the calculation into a function where I phần tính toán thành một hàm, tôi có could put the explanatory comment. thể viết chú thích trong hàm này. In writing the comment I realized that Trong khi viết chú thích tôi nhận ra the square root is the maximum prime rằng căn bậc hai là thừa số nguyên tố factor of any of the integers in the lớn nhất của bất kỳ số nào trong array. So I chose that name for the mảng. Sau đó tôi chọn tên cho các variables and functions that dealt with hàm và biến xử lý vấn đề này it. Finally, I made sure that the tests all Cuối cùng tôi bảo đảm các kiểm thử www.codegym.vnfb.com/goupee.vn/ Page 13
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; still ran. The result of all these vẫn chạy. Kết quả của các thay đổi changes are shown in Listing 5. trong Mã dẫn 5. PrimeGenerator.java phiên bản 4 (một phần) public class PrimeGenerator { private static boolean[] isCrossed; private static int[] result; public static int[] generatePrimes(int maxValue) { if (maxValue < 2) { return new int[0]; } else { initializeArrayOfIntegers(maxValue); crossOutMultiples(); putUncrossedIntegersIntoResult(); return result; } } private static void initializeArrayOfIntegers(int maxValue) { isCrossed = new boolean[maxValue + 1]; for (int i = 2; i < isCrossed.length; i++) { isCrossed[i] = false; } } private static void crossOutMultiples() { int maxPrimeFactor = calcMaxPrimeFactor(); for (int i = 2; i <= maxPrimeFactor; i++) { if (notCrossed(i)) { crossOutMultiplesOf(i); } } } www.codegym.vnfb.com/goupee.vn/ Page 14
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; private static int calcMaxPrimeFactor() { // We cross out all multiples of p, where p is prime. // Thus, all crossed out multiples have p and q for // factors. If p > sqrt of the size of the array, then // q will never be greater than 1. Thus p is the // largest prime factor in the array, and is also // the iteration limit. double maxPrimeFactor = Math.sqrt(isCrossed.length) + 1; return (int) maxPrimeFactor; } private static void crossOutMultiplesOf(int i) { for (int multiple = 2 * i; multiple < isCrossed.length; multiple += i) { isCrossed[multiple] = true; } } private static boolean notCrossed(int i) { return isCrossed[i] == false; } I was starting to get the hang of this Tôi bắt đầu nắm bắt được vấn đề nên so I took a look at the putUncrossed- liền xét hàm IntegersIntoResult method. I saw that putUncrossedIntegersIntoResult. Tôi this method had two parts. thấy hàm này có hai phần. The first counts the number of Phần thứ nhất đếm các số nguyên uncrossed integers in the array, and không bị loại trong mảng, và tạo nên creates the result array of that size. mảng kết quả (bằng chiều dài của The second moves the uncrossed mảng). Phần thứ hai dời các số integers into the result array. nguyên không bị loại vào dãy kết quả này. So, as you can see in Listing 6, I extracted the first part into its own Bởi thế, như bạn thấy trong Mã dẫn 6, function and did some miscellaneous tôi tách phần thứ nhất ra để hình cleanup. The tests all still ran. Jerry thành hàm cho chính nó và dọn dẹp www.codegym.vnfb.com/goupee.vn/ Page 15
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; was just barely nodding his head. Did lại một ít. Các kiểm thử vẫn chạy. he actually like what I did? Jerry chỉ thoáng gật đầu. Gã có thật sự khoái những điều tôi đã thực hiện không? Thợ lành nghề #3:Tính rõ ràng và cộng tác Next Jerry made pass over the whole Sau đó Jerry đọc toàn bộ chương program, reading it from beginning to trình, từ đầu đến cuối như thể đang end, rather like he was reading a đọc bài chứng minh hình học. Gã bảo geometric proof. He told me that this tôi đây là một bước hết sức quan was a really important step. “So far”, trọng. “Ðến bước này, tụi mình đã he said, “We’ve been refactoring thực hiện tái cấu trúc các phân fragments. Now we want to see if the mảnh của chương trình. Bây giờ tụi whole program hangs together as a mình xem liệu toàn bộ chương trình readable whole.” có gắn kết với nhau như một tổng thể đọc được.” I asked: “Jerry, do you do this with Tôi hỏi: “Jerry, anh cũng làm như thế your own code too?” với chính mã nguồn của mình sao?” Jerry scowled: “We work as a team Jerry quắc mắt lên và nói: “Ở đây tụi around here, so there is no code I call tao làm việc với nhau theo nhóm nên my own. Do you consider this code không có cái mã nào là của riêng tao yours now?” hết. Bộ mày cho rằng cái mã này của riêng mày hở?” “Not anymore.” I said, meekly. “You’ve Tôi trả lời nhỏ nhẹ: “Hết nghĩ như vậy had a big influence on it.” rồi, anh có ảnh hưởng rất lớn đến mã nguồn này.” “We both have.” he said, “And that’s Gã trả lời: “Cả hai thằng mình đều ảnh the way that Mr. C likes it. He doesn’t hưởng đến nó, và đây là cách ông C want any single person owning code. chuộng. Ông ấy không muốn riêng một ai làm chủ mã nguồn hết đâu. But to answer your question: Yes. We Câu trả lời cho câu hỏi của mày: all practice this kind of refactoring and “Ðúng vậy, ở đây tụi tao thực hành tái code clean up around here. It’s Mr. C’s cấu trúc và dọn rác. Đó là cách làm way.” của ông C.” www.codegym.vnfb.com/goupee.vn/ Page 16
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; During the read-through, Jerry Trong khi đọc lướt mã nguồn, Jerry realized that he didn’t like the name nhận thấy gã không thích cái tên initialize ArrayOfIntegers. initializeArrayOfIntegers. “What’s being initialized is not, in fact, Gã nói: “Cái được khởi tạo ở đây thực an array of integers;”, he said, “it’s an ra không phải là một mảng số nguyên, array of booleans. But mà là một mảng boolean. Nhưng initializeArrayOfBooleans is not an initializeArrayOfBooleans không phải improvement. là một cải tiến. What we are really doing in this Ðiều chúng ta thực sự muốn làm ở method is uncrossing all the relevant hàm này là liệt kê ra một danh sách integers so that we can then cross out các số nguyên phù hợp và để chúng the multiples.” lên một cái sàng, rồi sau đó lọc và loại ra các số không phải số nguyên tố (tức là loại ra những bội số)”. (Do đó, danh sách lúc đầu sẽ không bị gạch chéo, những số bị loại sẽ sẽ bị gạch chéo (crossed out)). “Of course!” I said. So I grabbed the Tôi trả lời: “Tất nhiên rồi!” Thế là tôi keyboard and changed the name to vớ lấy bàn phím và sửa tên của hàm uncross- IntegersUpTo. I also realized đó thành uncrossIntegersUpTo. Tôi that I didn’t like the name isCrossed cũng thấy không khoái cái tên for the array of booleans. So I isCrossed lại dùng cho một mảng changed it to crossedOut. The tests all boolean, nên tôi đổi nó thành still run. I was starting to enjoy this; but crossedOut. Các kiểm thử vẫn chạy. Jerry showed no sign of approval. Tôi bắt đầu thấy thích mấy cái trò này nhưng Jerry vẫn chẳng hề tỏ vẻ đồng tình. Then Jerry turned to me and asked Sau đó Jerry quay lại và hỏi tôi có phải me what I was smoking when I wrote tôi đã mơ màng theo khói thuốc khi all that maxPrimeFactor stuff. (See viết cái mớ maxPrimeFactor. (Xem Mã Listing 6.) At first I was taken aback. dẫn 6). Thoạt đầu tôi hết sức ngỡ But as I looked the code and ngàng nhưng khi xem lại đoạn mã và comments over I realized he had a các chú thích tôi nhận thấy gã có lý. point. Yikes, I felt stupid! The square Eo ôi, tôi thấy mình thật là ngu! Căn root of the size of the array is not bậc 2 của chiều dài một mảng số www.codegym.vnfb.com/goupee.vn/ Page 17
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; necessarily prime. That method did không hẳn là số nguyên. Hàm đó not calculate the maximum prime không tính thừa số nguyên tố lớn factor. The explanatory comment was nhất. Phần chú giải sai bét, hết sức just wrong. So I sheepishly rewrote ngượng ngùng tôi viết lại phần chú the comment to better explain the thích để giải thích rõ hơn cái căn bậc rationale behind the square root, and 2 này dùng để làm gì và đổi tên biến, renamed all the variables hàm cho thích hợp. Các kiểm thử vẫn appropriately. The tests all still ran. chạy. Mã dẫn 6. TestGeneratePrimes.java (một phần) public class TestGeneratePrimes { private static int calcMaxPrimeFactor() { // We cross out all multiples of p, where p is prime. // Thus, all crossed out multiples have p and q for factors. // If p > sqrt of the size of the array, then q will never // be greater than 1. Thus p is the largest prime factor // in the array, and is also the iteration limit. double maxPrimeFactor = Math.sqrt(isCrossed.length) + 1; return (int) maxPrimeFactor; } } “What the devil is that +1 doing in “dùng +1 ở đây làm quái gì vậy?” Jerry there?” Jerry barked at me. tru tréo lên. I gulped, looked at the code, and Tôi nuốt ực một cái, xem lại đoạn mã finally said: “I was afraid that a và cuối cùng tôi phát biểu: “Tôi ngại là fractional square root would convert khi chỉ lấy phần nguyên của căn bậc to an integer that was one too small to 2, thì phần thập phân của căn bậc 2 serve as the iteration limit.” đó bị mất đi, do đó vòng lặp có thể bị thiếu.” “So you’re going to litter the code with extra increments just because you Gã bèn hỏi: “Cho nên mày xả rác are paranoid?” he asked. “That’s trong đoạn mã với phần “+1” bởi vì silly, get rid of the increment and run mày bị hoảng? Như thế thì ngốc quá, www.codegym.vnfb.com/goupee.vn/ Page 18
goupee.vn goupee.com w h i l e ( ! ( s u c c e s s = t r y ( ) ) ) ; the tests.” dẹp ngay cái trò gia tăng “+1″ đó và chạy kiểm thử lại đi.” I did, and the tests all ran. I thought Tôi làm như thế và toàn bộ các kiểm about this for a minute, because it thử đều vẫn chạy tốt. Tôi nghĩ lại phần made me nervous. But I decided that này một lúc vì nó làm tôi lo lắng. Thế maybe the true iteration limit was the nhưng tôi quyết định có thể giới hạn largest prime less than or equal to the lặp lại thực sự chính là số “thừa số square root of the size of the array. nguyên tố lớn nhất” và “thừa số nguyên tố” đó nhỏ hơn hoặc bằng căn bậc 2 chiều dài của mảng. “That last change makes me pretty “Phần thay đổi vừa rồi làm tôi khá bối nervous.” I said to Jerry. “I understand rối”. Tôi nói với Jerry. “Tôi hiểu nguồn the rationale behind the square root, gốc đằng sau cái căn bậc 2, nhưng tôi but I’ve got a nagging feeling that cảm thấy không yên, biết đâu có there may be some corner cases that trường hợp “biên” nào đó chưa bao aren’t being covered.” quát hết.” “OK,” he grumbled. “So write another Gã lầm bầm “OK, vậy thì viết một cái test that checks that.” kiểm thử khác để kiểm tra chuyện đó đi.” “I suppose I could check that there are “Tôi nghĩ tôi có thể kiểm tra xem trong no multiples in any of the prime lists các danh sách số nguyên từ 2 đến between 2 and 500.” 500 không có trường hợp ở trên”. “OK, if it’ll make you feel better, try “OK, nếu nó làm cho mày cảm thấy dễ that,” he said. He was clearly chịu hơn, thì thử đi.” Gã nói. Rõ ràng becoming impatient. là gã bắt đầu trở nên mất kiên nhẫn. So I wrote the testExhaustive function Thế là tôi viết hàm testExhaustive như shown in Listing 8. The new test trong Mã dẫn 8. Phần kiểm thử mới passed, and my fears were allayed. này chạy đúng và nỗi lo sợ của tôi lắng xuống. Then Jerry relented a bit. “It’s always Jerry dịu xuống một chút. Gã nói: good to know why something works,” “Biết được lý do tại sao một cái gì đó said Jerry. “and it’s even better when chạy được luôn luôn là một điều tốt; you show you are right with a test.” và lại càng tốt hơn khi mà kiểm chứng www.codegym.vnfb.com/goupee.vn/ Page 19
Affichage des 20 premières pages. Téléchargez le document pour le voir en entier.
Aucun commentaire pour le moment. Soyez le premier !
Commentaires (0)
Aucun commentaire pour le moment. Soyez le premier !