Java初學者的30個常見問題

2021-03-02 動力節點Java學院

官方微博:動力節點

文章來源:極思維 

本文回答了30個JAVA入門級初學者的常見問題。

1.2 基本數據類型


Q. 為什麼 -0/3 結果是 0,而  -0.0/3.0 結果是 -0.0?(注意後邊的結果0帶負號)

A. 在Java裡,整數是用補碼表示的。在補碼中0隻有一種表示方法。另一方面,浮點數則是用 IEEE 標準表示的, 對於0有兩種表示方法, 0 和 -0。

Q. 我可以用 % 除以一個小數嗎?

A. 當然可以。比如,如果 angle 是一個非負數,那麼 angle % (2 * Math.PI) 就會把 angle 轉換到 0 到  2 π 之間。

Q. 當 a b 都是基本類型變量時,a += b 和 a = a + b 的效果有區別嗎?

A. 當 a 和 b 的類型不同時,那兩條語句的效果就可能有區別。 a += b 等同於 a = (int) (a + b),這種情況下可以是 a是int型,b是float型。但是同等情況下 a = a + b 就會編譯報錯。

 1.3 條件語句和循環語句

Q. 為什麼判斷字符串相等不能使用 == ?

A. 這反映了基礎類型(int, double, boolean)和引用類型(String)的區別。

Q. 有沒有在什麼情況下,一條語句塊的花括號不能省略的?

A. 在下面的例子中,第一段代碼是合法的,第二段代碼會引發編譯錯誤。從技術角度說,那一條語句是一個變量聲明,而不是語句,所以會報錯。


Q. 在下面的兩段代碼裡,有沒有情況,它們的效果不一樣?

A. 有的。如果在循環塊裡使用 continue 語句。在for的代碼裡,計數器會加一;而在while的代碼裡,因為被continue略過了,計數器不加一。

 

1.4  數組


Q. 某些Java開發人員使用 int a[] 而不是 int[] a 去聲明一個數組。這兩者有什麼區別?

A. 在Java中這兩種用法都是合法的,他們的作用都是一樣的。前者是在C中的定義數組的方法。後者是JAVA推薦的方法,因為它的寫法 int[] 更能表明這是一個 int 的數組。

Q. 為什麼數組下標從0 開始 而不是從 1 開始?

A. 這種傳統起源於機器語言的編程方法。在機器語言中,數組下標被用來計算元素位置與第一個元素之間的偏移量。如果從1開始的話,計算偏移時還需要做一次減法運算,那是種浪費。

Q. 如果我用 負數 作為數組下標會發生什麼事?

A. 下標小於0 或者 大於等於數組長度,JAVA運行時會拋出 ArrayIndexOutOfBoundsException 異常,並且中止程序運行。

Q. 使用數組時還有其他需要注意的陷阱嗎?

A. 需要記住,JAVA在你創建一個數組時會去初始化它,所以聲明一個數組需要 O(N)的時間。

Q. 既然 a[] 是一個數組,為什麼 System.out.println(a) 會列印出一個16進位的數,就像 @f62373 這樣,而不是列印出數組的元素?

A. 好問題。這條語句列印出的是 數組在內存中的地址,不幸的是,在絕大多數情況下,這不是你需要的。

1.5 輸入輸出語句


Q. 我可以從標準input中重新讀一次數據嗎?

A. 不可以,你只能讀一次。

Q. 怎樣輸入 end-of-file (eof) 符號?

A. 作業系統自動包括它了。


Q. 使用 printf() 時還有哪些用法?

A. 對於整數來說,使用 o 輸出八進位,使用 x 輸出十六進位。對於浮點數來說,使用 e 或者 g 輸出科學計數法形式。


Q. 行結束的符號是什麼?

A. 不同的文件系統使用了不同的符號。在 Unix 系統上,新行的符號是 '\n' ;在 Windows 系統上,每一行都有兩個字符組成的字符串終結 "\r\n" ;在 Macs 系統上,終結符號是 "\n\r" 。如果要列印行號,可以使用 System.out.println() ,或者使用下面的語句得到當前作業系統下的行結束符:


Q. 下面兩種寫法,哪一種更有效率?

A. 從效率角度說,兩者沒有區別。 但是第二種寫法更好,因為它限制了變量的作用域。

 

2.1 函數調用


Q. 當把數組當作函數調用時的參數時,我常常感到疑惑?

A. 是的。你需要牢記傳值參數(參數是基本變量類型)和傳引用參數(比如數組)之間的區別。

Q. 那為什麼不把所有的參數都使用傳值的方式,包括對待數組?

A. 但數組很大時,複製數組需要大量的性能開銷。因為這個原因,絕大多數變成語言支持把數組傳入函數但不複製一個副本——MATLAB語言除外。

 

2.3 遞歸調用

Q. 有沒有只能用循環而不能用遞歸的情況?

A. 不可能,所有的循環都可以用遞歸替代,雖然大多數情況下,遞歸需要額外的內存。

Q. 有沒有只能用遞歸而不能用循環的情況?

A. 不肯能,所有的遞歸調用都可以用循環來表示。比如你可以用while的方式來實現棧。

Q. 那我應該選擇哪個,遞歸的方式 還是 循環的方式?

A. 根據代碼的可讀性和效率性之間做權衡。

Q. 我擔心使用遞歸代碼時的空間開銷和重複計算(例如用遞歸解Fibonacci)的問題。有沒有其他需要擔心的?

A. 在遞歸代碼中創建大數據類型(比如數組)時需要額外注意,隨著遞歸的推進,內存使用將會迅速增加,由於內存使用增加,作業系統管理內存的時間開銷也會增加。

 

4.2 排序與查找

Q. 為什麼我們要花大篇幅來證明一個程序是正確的?

A. 為了防止錯誤的結果。二分查找就是一個例子。現在,你懂得了二分查找的原理,你就能把遞歸形式的二分查找改寫成循環形式的二分查找。Knuth 教授在 1946年就發表了二分查找的論文,但是第一個正確的二分查找的程序在 1962年在出現。


Q. 在JAVA內建庫中有沒有排序和查找的函數?

A. 有的。在 java.util.Arrays 中包含了 Arrays.sort() 和 Arrays.binarySearch() 方法。對於Comparable 類型它使用了 歸併排序,對於基本數據類型,它使用了快速排序。因為基本類型是值傳遞,快速排序比歸併排序更快而且不需要額外的空間。 


Q. 為什麼JAVA庫不用 隨機pivot方式的快速排序?

A. 好問題。 因為某些程式設計師在調試代碼時,可能需要確定性的代碼實現。使用隨機pivot違背了這個原則。

 

4.3 棧和隊列

Q. 在Java庫中有對stacks 和 queues 的實現嗎?

A. Java庫中內建 java.util.Stack,但是你應該避免使用它如果你需要一個真正的棧的話。因為它是實現了額外的功能,比如訪問第N個元素。另外,它也支持從棧底部插入元素,所以它看上去更像是一個隊列。儘管實現了這些額外的功能對編程人員是一個加分,可是我們使用數據結構並不只是想使用所有功能,而是需要我們正好需要的那種結構。JAVA對於棧的實現就是一個典型的寬接口的例子。

Q. 我想使用數組來表示一個包含泛型的棧,但是以下代碼編譯報錯。為什麼?

A. 不錯的嘗試。不幸的是,創建一個泛型數組在 Java 1.5裡不支持。你可以使用cast,比如下面的寫法:

根本的原因是JAVA中的數組是「協變的(covariant)」,但是泛型並不是。比如, String[] 是 Object[]的一種子類型,但是 Stack<String>並不是 Stack<Object> 的一種子類型。 許多程式設計師認為「協變的」數組是JAVA在數據類型方面的一個缺點。但是,如果我們不考慮泛型,「協變的」數組是有用的,比如實現 Arrays.sort(Comparable[]) 方法,然後當參數是 String[]時它也可以被正常調用。

Q. 可不可以在數組上使用 foreach 方式?

A. 可以的(雖然 數組並沒有實現 Iterator 接口)。請參考下面的代碼:

Q. 在 linked list 上使用 iterator 是不是比循環或者遞歸更有效率?

A. 編譯器在翻譯時,可能把那種「尾遞歸」形式翻譯成等價的循環形式。所以可能並沒有可以被觀測到的性能提升。

尾部遞歸是一種編程技巧。如果在遞歸函數中,遞歸調用返回的結果總被直接返回,則稱為尾部遞歸。尾遞歸是極其重要的,不用尾遞歸,函數的堆棧耗用難以估量,需要保存很多中間函數的堆棧。比如f(n, sum) = f(n-1) + value(n) + sum; 會保存n個函數調用堆棧,而使用尾遞歸f(n, sum) = f(n-1, sum+value(n)); 這樣則只保留後一個函數堆棧即可,之前的可優化刪去。


Q. 自動裝箱機制會怎麼處理下面的情況?

A. 它將返回一個運行時錯誤。基礎類型不允許它對應的裝箱類型裡的值是null。

Q. 為什麼第一組列印的是 true,但是後面兩組列印的是 false?

A. 第二組代碼列印 false 是因為 b1 和 b2 指向不同的 Integer 對象引用。第一組和第三組依賴於自動裝箱機制。 令人意外的第一組列印了 true 是因為在 -128 和 127 之間的值會自動轉換成同樣的immutable型的Integer 對象。對於超出那個範圍的數,Java會對於每一個數創建一個新的Integer對象。

補充能量,回顧閱讀:

以面試的角度來詮釋Java工程師

Java提高篇----equals()方法總結

2017你不應該錯過的Java庫包

要換工作? 來看看面試題吧

震驚!從未見過如此簡單粗暴的Hibernate教程

相關焦點

  • Java初學者入門指南,值得收藏~
    很多Java編程初學者在剛接觸Java語言程序的時候,不知道該學習掌握哪些必要的基礎知識。小編總結了零基礎學習Java程式語言的幾個基礎知識要點。希望能夠對剛入門的Java新手有幫助。初學者先弄清這些Java的基本概念也是必不可少的,死記硬背肯定是不行的,重在理解,理解它們之間的區別與聯繫,分別有哪些應用。想想這些代碼中用到了哪些知識點。
  • 手把手教你定位常見Java性能問題
    概述性能優化一向是後端服務優化的重點,但是線上性能故障問題不是經常出現,或者受限於業務產品,根本就沒辦法出現性能問題,包括筆者自己遇到的性能問題也不多,所以為了提前儲備知識,當出現問題的時候不會手忙腳亂,我們本篇文章來模擬下常見的幾個Java性能故障,來學習怎麼去分析和定位。
  • 50 個 Java 開發常見錯誤及規避技巧 (Part 1)
    我們列舉了 50 個最常見的 Java 軟體錯誤,其中包含代碼示例和教程,以幫助您解決常見的編碼問題。如果您正在使用 .NET,您還應該查看我們的 50 個最常見的 .NET 軟體錯誤指南,以及如何避免這些錯誤。 如果您當前的挑戰與 Java 相關,請繼續閱讀以了解最常見的問題及其解決方法。
  • Java學習心得--給初學者的一些建議
    java是跨平臺的,那又為何不試試在Linux下開發呢?這就是一種,逼迫自己的心態了。為了以後能夠順利的學習java的最新知識,或者是獲得其他技術的最新信息,我又開始逼迫自己做第二件事情,那便是閱讀英文原書。
  • 吉他入門:初學者常見的十個問題
    學習吉他可能是令人生畏的——作為一個初學者,有很多問題和擔憂也是正常的,但是小編在這裡幫助你從正確的方向開始學習吉他。下面是初學者在學習吉他時常見問題。一、我太老了,不能學吉他了嗎?不存在的!可以直接的告訴你,但你想學吉他的時候,你不可能會拿不起吉他或者按不動琴弦。
  • java 初學者 第一階段作業編程總結及心得體會
    0.前言 第一階段java作業分為
  • 核桃乾貨 | 最常見的10種Java異常問題!
    LocalTime time = LocalTime.now();        System.out.println("獲取當前的時間,不含有日期:"+time);    }}通過增加小時、分、秒來計算將來的時間很常見。
  • 初學者的玩具——Java經典小程序,問題源碼詳解
    準備了一些java初級的小程序,關於java的知識點都被程序概括,選取最經典的一些介紹給大家。1、編寫程序,判斷給定的某個年份是否是閏年。2、利用for循環列印 9*9 表小程序問題與代碼一共是100個,因為篇幅的原因也就只能給大家分享幾個了,需要全部小程序問題和源碼的在文末會有提示。3、輸出所有的水仙花數,把謂水仙花數是指一個數3位數,其各各位數字立方和等於其本身。
  • 新手轉行學java難嗎?新手學java需要注意的6個方面!
    新手轉行學java難嗎?新手學java需要注意的6個方面!
  • Java認證:java運行時常見異常
    總結了幾個JAVA中常見的RuntimeException:  NullPointerException:空指針異常類  示例:  package com.darkmi.basic;  public class Test {  public static void
  • Java中如何高效的讀取大文件
    在java編程中, 我想大部分小夥伴都在使用BufferReader,那麼是否有更高效的讀取方式呢?
  • 最常見的10種Java異常問題!
    前言本文總結了有關Java異常的十大常見問題。目錄檢查型異常(checked) vs. 非檢查型異常(Unchecked)為什麼在try代碼塊中聲明的變量不能在catch或者finally中被引用?為什麼 Double.parseDouble(null) 和 Integer.parseInt(null) 拋出的異常不一樣呢?
  • 搞懂這3個問題,Java新手即可升級!
    任何一個java初學者如果認為自己已經能夠脫離初學者的範疇,那麼都可以用以下的幾個問題對自己進行考量。如果你還不能夠弄懂這些問題,那麼請將自己重新歸入初學者的隊伍中。String s = "Hello world!";許多人都做過這樣的事情,但是,我們到底聲明了什麼?回答通常是:一個String,內容是「Hello world!」。
  • 50個常見的 Java 錯誤及避免方法(第二部分)
    「Non-Static Method … Cannot Be Referenced From a Static Context」此問題發生在Java代碼嘗試在非靜態類中調用非靜態方法的情況下。「StringIndexOutOfBoundsException」當代碼嘗試訪問不在字符串範圍內的字符串的一部分時,就會發生這種問題。通常,這發生在代碼嘗試創建字符串的子字符串,且長度與參數設置不符之時。
  • 50個常見的 Java 錯誤及避免方法(第三部分)
    「class file contains wrong class」當Java代碼嘗試在錯誤的目錄中尋找類文件時,就會出現「class file contains wrong class」的問題,導致類似於以下內容的錯誤消息:MyTest.java:10: cannot access MyStruct bad class file: D:JavatestMyStruct.java
  • 如何學習Java,哪裡開始學Java比較好?
    推薦初學者看《Java入門到精通》《Head first Java》《java核心技術卷》《Java編程思想》  程式設計師必備:程式設計師必備 Java 核心知識點整理  Java學習書籍整理、Web前後端、各種框架、資料庫及IT行業等類型電子書  掌握面一門語言,首先得掌握它的思想,思想決定高度。
  • Java 最常見面試題
    4.final 在 java 中有什麼作用?5.java 中的 Math.round(-1.5) 等於多少?6.String 屬於基礎的數據類型嗎?7.java 中操作字符串都有哪些類?它們之間有什麼區別?8.String str="i"與 String str=new String(「i」)一樣嗎?
  • Java 最常見的 200+ 面試題:面試必備
    可能對於初學者不需要看後面的框架和 JVM 模塊的知識,讀者朋友們可根據自己的情況,選擇對應的模塊進行閱讀。適宜閱讀人群需要面試的初/中/高級 java 程式設計師想要查漏補缺的人想要不斷完善和擴充自己 java 技術棧的人java
  • 阿里螞蟻金服Java程式設計師面試的11個問題,你會幾個呢?
    比如阿里巴巴java面經、小米java面經、網易java面經等,吸引了大多數的程式設計師們的圍觀。面向對象的特徵:抽象、繼承、封裝、多態常見算法的應用,包括算法基礎和Java編程實現。總結一般是進行分類總結,善於抓重點,以便抓住面試官痛點。
  • Java基礎學習心得筆記
    對於很多只會C語言的初學者而言,面對java基礎語法學習,反而感覺很難,其實其中最大的問題不是語法難,而是一種編程思想的轉變。