<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## Chapter 9. General Programming(通用程序設計) ### Item 59: Know and use the libraries(了解并使用庫) Suppose you want to generate random integers between zero and some upper bound. Faced with this common task, many programmers would write a little method that looks something like this: 假設你想要生成 0 到某個上界之間的隨機整數。面對這個常見任務,許多程序員會編寫一個類似這樣的小方法: ``` // Common but deeply flawed! static Random rnd = new Random(); static int random(int n) { return Math.abs(rnd.nextInt()) % n; } ``` This method may look good, but it has three flaws. The first is that if n is a small power of two, the sequence of random numbers will repeat itself after a fairly short period. The second flaw is that if n is not a power of two, some numbers will, on average, be returned more frequently than others. If n is large, this effect can be quite pronounced. This is powerfully demonstrated by the following program, which generates a million random numbers in a carefully chosen range and then prints out how many of the numbers fell in the lower half of the range: 這個方法看起來不錯,但它有三個缺點。首先,如果 n 是小的平方數,隨機數序列會在相當短的時間內重復。第二個缺陷是,如果 n 不是 2 的冪,那么平均而言,一些數字將比其他數字更頻繁地返回。如果 n 很大,這種效果會很明顯。下面的程序有力地證明了這一點,它在一個精心選擇的范圍內生成 100 萬個隨機數,然后打印出有多少個數字落在范圍的下半部分: ``` public static void main(String[] args) { int n = 2 * (Integer.MAX_VALUE / 3); int low = 0; for (int i = 0; i < 1000000; i++) if (random(n) < n/2) low++; System.out.println(low); } ``` If the random method worked properly, the program would print a number close to half a million, but if you run it, you’ll find that it prints a number close to 666,666. Two-thirds of the numbers generated by the random method fall in the lower half of its range! 如果 random 方法工作正常,程序將輸出一個接近 50 萬的數字,但是如果運行它,你將發現它輸出一個接近 666666 的數字。隨機方法生成的數字中有三分之二落在其范圍的下半部分! The third flaw in the random method is that it can, on rare occasions, fail catastrophically, returning a number outside the specified range. This is so because the method attempts to map the value returned by rnd.nextInt() to a non-negative int by calling Math.abs. If nextInt() returns Integer.MIN_VALUE, Math.abs will also return Integer.MIN_VALUE, and the remainder operator (%) will return a negative number, assuming n is not a power of two. This will almost certainly cause your program to fail, and the failure may be difficult to reproduce. random 方法的第三個缺陷是,在極少數情況下會返回超出指定范圍的數字,這是災難性的結果。這是因為該方法試圖通過調用 `Math.abs` 將 `rnd.nextInt()` 返回的值映射到非負整數。如果 `nextInt()` 返回整數。`Integer.MIN_VALUE`、`Math.abs` 也將返回整數。假設 n 不是 2 的冪,那么 `Integer.MIN_VALUE` 和求模運算符 `(%)` 將返回一個負數。幾乎肯定的是,這會導致你的程序失敗,并且這種失敗可能難以重現。 To write a version of the random method that corrects these flaws, you’d have to know a fair amount about pseudorandom number generators, number theory, and two’s complement arithmetic. Luckily, you don’t have to do this— it’s been done for you. It’s called Random.nextInt(int). You needn’t concern yourself with the details of how it does its job (although you can study the documentation or the source code if you’re curious). A senior engineer with a background in algorithms spent a good deal of time designing, implementing, and testing this method and then showed it to several experts in the field to make sure it was right. Then the library was beta tested, released, and used extensively by millions of programmers for almost two decades. No flaws have yet been found in the method, but if a flaw were to be discovered, it would be fixed in the next release. **By using a standard library, you take advantage of the knowledge of the experts who wrote it and the experience of those who used it before you.** 要編寫一個 random 方法來糾正這些缺陷,你必須對偽隨機數生成器、數論和 2 的補碼算法有一定的了解。幸運的是,你不必這樣做(這是為你而做的成果)。它被稱為 `Random.nextInt(int)`。你不必關心它如何工作的(盡管如果你感興趣,可以研究文檔或源代碼)。一位具有算法背景的高級工程師花了大量時間設計、實現和測試這種方法,然后將其展示給該領域的幾位專家,以確保它是正確的。然后,這個庫經過 beta 測試、發布,并被數百萬程序員廣泛使用了近 20 年。該方法還沒有發現任何缺陷,但是如果發現了缺陷,將在下一個版本中進行修復。**通過使用標準庫,你可以利用編寫它的專家的知識和以前使用它的人的經驗。** As of Java 7, you should no longer use Random. For most uses, **the random number generator of choice is now ThreadLocalRandom.** It produces higher quality random numbers, and it’s very fast. On my machine, it is 3.6 times faster than Random. For fork join pools and parallel streams, use SplittableRandom. 從 Java 7 開始,就不應該再使用 Random。在大多數情況下,**選擇的隨機數生成器現在是 ThreadLocalRandom。** 它能產生更高質量的隨機數,而且速度非常快。在我的機器上,它比 Random 快 3.6 倍。對于 fork 連接池和并行流,使用 SplittableRandom。 A second advantage of using the libraries is that you don’t have to waste your time writing ad hoc solutions to problems that are only marginally related to your work. If you are like most programmers, you’d rather spend your time working on your application than on the underlying plumbing. 使用這些庫的第二個好處是,你不必浪費時間為那些與你的工作無關的問題編寫專門的解決方案。如果你像大多數程序員一樣,那么你寧愿將時間花在應用程序上,而不是底層管道上。 A third advantage of using standard libraries is that their performance tends to improve over time, with no effort on your part. Because many people use them and because they’re used in industry-standard benchmarks, the organizations that supply these libraries have a strong incentive to make them run faster. Many of the Java platform libraries have been rewritten over the years, sometimes repeatedly, resulting in dramatic performance improvements. A fourth advantage of using libraries is that they tend to gain functionality over time. If a library is missing something, the developer community will make it known, and the missing functionality may get added in a subsequent release. 使用標準庫的第三個優點是,隨著時間的推移,它們的性能會不斷提高,而你無需付出任何努力。由于許多人使用它們,而且它們是在行業標準基準中使用的,所以提供這些庫的組織有很強的動機使它們運行得更快。多年來,許多 Java 平臺庫都被重新編寫過,有時甚至是反復編寫,從而帶來了顯著的性能改進。使用庫的第四個好處是,隨著時間的推移,它們往往會獲得新功能。如果一個庫丟失了一些東西,開發人員社區會將其公布于眾,并且丟失的功能可能會在后續版本中添加。 A final advantage of using the standard libraries is that you place your code in the mainstream. Such code is more easily readable, maintainable, and reusable by the multitude of developers. 使用標準庫的最后一個好處是,可以將代碼放在主干中。這樣的代碼更容易被開發人員閱讀、維護和復用。 Given all these advantages, it seems only logical to use library facilities in preference to ad hoc implementations, yet many programmers don’t. Why not? Perhaps they don’t know the library facilities exist. **Numerous features are added to the libraries in every major release, and it pays to keep abreast of these additions.** Each time there is a major release of the Java platform, a web page is published describing its new features. These pages are well worth reading [Java8-feat, Java9-feat]. To reinforce this point, suppose you wanted to write a program to print the contents of a URL specified on the command line (which is roughly what the Linux curl command does). Prior to Java 9, this code was a bit tedious, but in Java 9 the transferTo method was added to InputStream. Here is a complete program to perform this task using this new method: 考慮到所有這些優點,使用庫工具而不選擇專門的實現似乎是合乎邏輯的,但許多程序員并不這樣做。為什么不呢?也許他們不知道庫的存在。**在每個主要版本中,都會向庫中添加許多特性,了解這些新增特性是值得的。** 每次發布 Java 平臺的主要版本時,都會發布一個描述其新特性的 web 頁面。這些頁面非常值得一讀 [Java8-feat, Java9-feat]。為了強調這一點,假設你想編寫一個程序來打印命令行中指定的 URL 的內容(這大致是 Linux curl 命令所做的)。在 Java 9 之前,這段代碼有點乏味,但是在 Java 9 中,transferTo 方法被添加到 InputStream 中。這是一個使用這個新方法執行這項任務的完整程序: ``` // Printing the contents of a URL with transferTo, added in Java 9 public static void main(String[] args) throws IOException { try (InputStream in = new URL(args[0]).openStream()) { in.transferTo(System.out); } } ``` The libraries are too big to study all the documentation [Java9-api], but **every programmer should be familiar with the basics of java.lang, java.util, and java.io, and their subpackages.** Knowledge of other libraries can be acquired on an as-needed basis. It is beyond the scope of this item to summarize the facilities in the libraries, which have grown immense over the years. 庫太大,無法學習所有文檔 [Java9-api],但是 **每個程序員都應該熟悉 `java.lang`、`java.util` 和 `java.io` 的基礎知識及其子包。** 其他庫的知識可以根據需要獲得。概述庫中的工具超出了本項目的范圍,這些工具多年來已經發展得非常龐大。 Several libraries bear special mention. The collections framework and the streams library (Items 45–48) should be part of every programmer’s basic toolkit, as should parts of the concurrency utilities in java.util.concurrent. This package contains both high-level utilities to simplify the task of multithreaded programming and low-level primitives to allow experts to write their own higher-level concurrent abstractions. The highlevel parts of java.util.concurrent are discussed in Items 80 and 81. 有幾個圖書館值得一提。collections 框架和 streams 庫(可參看 Item 45-48)應該是每個程序員的基本工具包的一部分,`java.util.concurrent` 中的并發實用程序也應該是其中的一部分。這個包既包含高級的并發工具來簡化多線程的編程任務,還包含低級別的并發基本類型,允許專家們自己編寫更高級的并發抽象。`java.util.concurrent` 的高級部分,在 [Item-80](/Chapter-11/Chapter-11-Item-80-Prefer-executors,-tasks,-and-streams-to-threads.md) 和 [Item-81](/Chapter-11/Chapter-11-Item-81-Prefer-concurrency-utilities-to-wait-and-notify.md) 中討論。 Occasionally, a library facility can fail to meet your needs. The more specialized your needs, the more likely this is to happen. While your first impulse should be to use the libraries, if you’ve looked at what they have to offer in some area and it doesn’t meet your needs, then use an alternate implementation. There will always be holes in the functionality provided by any finite set of libraries. If you can’t find what you need in Java platform libraries, your next choice should be to look in high-quality third-party libraries, such as Google’s excellent, open source Guava library [Guava]. If you can’t find the functionality that you need in any appropriate library, you may have no choice but to implement it yourself. 有時,類庫工具可能無法滿足你的需求。你的需求越專門化,發生這種情況的可能性就越大。雖然你的第一個思路應該是使用這些庫,但是如果你已經了解了它們在某些領域提供的功能,而這些功能不能滿足你的需求,那么可以使用另一種實現。任何有限的庫集所提供的功能總是存在漏洞。如果你在 Java 平臺庫中找不到你需要的東西,你的下一個選擇應該是尋找高質量的第三方庫,比如谷歌的優秀的開源 Guava 庫 [Guava]。如果你無法在任何適當的庫中找到所需的功能,你可能別無選擇,只能自己實現它。 To summarize, don’t reinvent the wheel. If you need to do something that seems like it should be reasonably common, there may already be a facility in the libraries that does what you want. If there is, use it; if you don’t know, check. Generally speaking, library code is likely to be better than code that you’d write yourself and is likely to improve over time. This is no reflection on your abilities as a programmer. Economies of scale dictate that library code receives far more attention than most developers could afford to devote to the same functionality. 總而言之,不要白費力氣重新發明輪子。如果你需要做一些看起來相當常見的事情,那么庫中可能已經有一個工具可以做你想做的事情。如果有,使用它;如果你不知道,檢查一下。一般來說,庫代碼可能比你自己編寫的代碼更好,并且隨著時間的推移可能會得到改進。這并不反映你作為一個程序員的能力。規模經濟決定了庫代碼得到的關注要遠遠超過大多數開發人員所能承擔的相同功能。 --- **[Back to contents of the chapter(返回章節目錄)](/Chapter-9/Chapter-9-Introduction.md)** - **Previous Item(上一條目):[Item 58: Prefer for-each loops to traditional for loops(for-each 循環優于傳統的 for 循環)](/Chapter-9/Chapter-9-Item-58-Prefer-for-each-loops-to-traditional-for-loops.md)** - **Next Item(下一條目):[Item 60: Avoid float and double if exact answers are required(若需要精確答案就應避免使用 float 和 double 類型)](/Chapter-9/Chapter-9-Item-60-Avoid-float-and-double-if-exact-answers-are-required.md)**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看