Heim >Java >javaLernprogramm >Zusammenfassung häufig gestellter Fragen für Java-Anfänger (Sammlung)

Zusammenfassung häufig gestellter Fragen für Java-Anfänger (Sammlung)

黄舟
黄舟Original
2017-03-29 10:13:091512Durchsuche

In diesem Artikel werden einige häufig von Java-Anfängern gestellte Fragen vorgestellt. Viele Freunde interessieren sich dafür, ob % durch eine Dezimalzahl geteilt werden kann. Gibt es einen Unterschied in den Auswirkungen von a += b und a = a + b? Warum dauert die Deklaration eines Arrays viel Zeit? Warum verwendet die Java-Bibliothek keine zufällige Pivot-Schnellsortierung? Wenn Sie Zweifel an einer Reihe von Fragen haben, möchte ich Ihnen in diesem Artikel eine detaillierte Einführung geben.

In diesem Artikel werden einige Fragen vorgestellt, die häufig von Java-Anfängern gestellt werden. Kann % durch eine Dezimalzahl geteilt werden? Gibt es einen Unterschied in den Auswirkungen von a += b und a = a + b? Warum dauert die Deklaration eines Arrays so lange? Warum verwendet die Java-Bibliothek keine zufällige Pivot-Schnellsortierung?

GrundlegendeDatentypen

F. Warum -0/3 zu 0 führt, während -0,0/3,0 ergibt in Ist es -0,0? (Beachten Sie, dass das folgende Ergebnis 0 ein negatives Vorzeichen hat)

A In Java wird die Ganzzahl durch den Zweierkomplementcode dargestellt. Es gibt nur eine Möglichkeit, 0 im Zweierkomplement darzustellen. Gleitkommazahlen hingegen werden nach dem IEEE-Standard dargestellt und es gibt zwei Möglichkeiten, 0, 0 und -0 darzustellen.

F. Kann ich % durch eine Dezimalzahl dividieren?

A. Natürlich. Wenn der Winkel beispielsweise eine nichtnegative Zahl ist, konvertiert Winkel % (2 * Math.PI) den Winkel in einen Wert zwischen 0 und 2 π.

F. Wenn a und b beide Basistyp-Variablen sind, gibt es dann einen Unterschied in den Auswirkungen von a += b und a = a + b?

A. Wenn a und b unterschiedlicher Art sind, können die Auswirkungen der beiden Aussagen unterschiedlich sein. a += b entspricht a = (int) (a + b). In diesem Fall kann a vom Typ int und b vom Typ float sein. Aber unter den gleichen Umständen wird a = a + b kompiliert und einen Fehler melden.

bedingte Anweisung und Schleife Anweisung

F. Warum beurteilen Zeichenfolge ? Nicht == für Gleichheit verwenden?

A. Dies spiegelt den Unterschied zwischen Basistypen (int, double, boolean) und Referenztypen (String) wider.

F. Gibt es Umstände, unter denen die geschweiften Klammern eines Anweisungsblocks nicht weggelassen werden können?

A. Im folgenden Beispiel ist der erste Codeabschnitt zulässig, aber der zweite Codeabschnitt verursacht einen Kompilierungsfehler. Aus technischer Sicht handelt es sich bei dieser Anweisung um eine Variablendeklaration und nicht um eine Anweisung, sodass ein Fehler gemeldet wird.

// legal 
for (int i = 0; i <= N; i++) { 
 int x = 5; 
} 
// illegal 
for (int i = 0; i <= N; i++) 
 int x = 5;

F. Gibt es in den folgenden beiden Codeteilen Situationen, in denen ihre Auswirkungen unterschiedlich sind?

for (<init stmnt> <boolean expr>; <incr stmnt>) { 
 <body statements> 
} 
<init stmnt>; 
while (<boolean expr>) { 
 <body statements> 
 <incr stmnt> 
}

Ja. Wenn Sie die Anweisung continue in einem Schleifenblock verwenden. Im for-Code erhöht sich der Zähler um eins; im while-Code erhöht sich der Zähler nicht um eins, da er von continue übersprungen wird.

Array

F. Einige Java-Entwickler verwenden int a[] anstelle von int[] a, um ein Array zu deklarieren. Was ist der Unterschied zwischen den beiden?

A. Beide Verwendungen sind in Java zulässig und ihre Funktionen sind die gleichen. Ersteres ist die Möglichkeit, ein Array in C zu definieren. Letzteres ist die von JAVA empfohlene Methode, da die Schreibmethode int[] besser anzeigt, dass es sich um ein Array von int handelt.

F. Warum beginnen Array-Indizes bei 0 statt bei 1?

A. Diese Tradition hat ihren Ursprung in der Programmiermethode der Maschinensprache. In der Maschinensprache werden Array-Indizes verwendet, um den Versatz zwischen der Position eines Elements und dem ersten Element zu berechnen. Wenn Sie bei 1 beginnen, müssen Sie bei der Berechnung des Versatzes eine Subtraktionsoperation durchführen, was eine Verschwendung darstellt.

F. Was passiert, wenn ich eine negative Zahl als Array-Index verwende?

A. Wenn der Index kleiner als 0 oder größer oder gleich der Array-Länge ist, löst JAVA beim Ausführen eine ArrayIndexOutOfBoundsException-Ausnahme aus und beendet das Programm.

F. Gibt es weitere Fallstricke, die bei der Verwendung von Arrays beachtet werden müssen?

A. Sie müssen bedenken, dass JAVA ein Array initialisiert, wenn Sie es erstellen. Daher dauert die Deklaration eines Arrays O(N).

F. Da a[] ein Array ist, warum gibt System.out.println(a) eine Hexadezimalzahl aus, genau wie @f62373, anstatt das Array-Element auszugeben?

A. Gute Frage. Diese Anweisung gibt die Adresse des Arrays im Speicher aus. Das System ruft automatisch die toString()-Methode des Arrays auf. Für dieses Problem können Sie sich den Quellcode der toString()-Methode ansehen.

FunktionAufruf

F. Bei Verwendung eines Arrays als Parameter beim Aufrufen einer Funktion, I Oft verwirrt?

A. Sie müssen sich den Unterschied zwischen Wertübergabe-Parametern (Parameter sind grundlegende Variablentypen) und Referenzübergabeparametern (z. B. Arrays) merken.

Q. 那为什么不把所有的参数都使用传值的方式,包括对待数组?

A. 但数组很大时,复制数组需要大量的性能开销。因为这个原因,绝大多数变成语言支持把数组传入函数但不复制一个副本——MATLAB语言除外。

递归调用

Q. 有没有只能用循环而不能用递归的情况?

A. 不可能,所有的循环都可以用递归替代,虽然大多数情况下,递归需要额外的内存。

Q. 有没有只能用递归而不能用循环的情况?

A. 不可能,所有的递归调用都可以用循环来表示。比如你可以用while的方式来实现栈。

Q. 那我应该选择哪个,递归的方式 还是 循环的方式?

A. 根据代码的可读性和效率性之间做权衡。

Q. 我担心使用递归代码时的空间开销和重复计算(例如用递归解Fibonacci)的问题。有没有其他需要担心的?
A. 在递归代码中创建大数据类型(比如数组)时需要额外注意,随着递归的推进,内存使用将会迅速增加,由于内存使用增加,操作系统管理内存的时间开销也会增加。

排序与查找

Q. 为什么我们要花大篇幅来证明一个程序是正确的?

A. 为了防止错误的结果。二分查找就是一个例子。现在,你懂得了二分查找的原理,你就能把递归形式的二分查找改写成循环形式的二分查找。Knuth 教授在 1946年就发表了二分查找的论文,但是第一个正确的二分查找的程序在 1962年在出现。

Q. 在JAVA内建库中有没有排序和查找的函数?

A. 有的。在 java.util.Arrays 中包含了 Arrays.sort() 和 Arrays.binarySearch() 方法。对于Comparable 类型它使用了 归并排序,对于基本数据类型,它使用了快速排序。因为基本类型是值传递,快速排序比归并排序更快而且不需要额外的空间。

Q. 为什么JAVA库不用 随机pivot方式的快速排序?

A. 好问题。 因为某些程序员在调试代码时,可能需要确定性的代码实现。使用随机pivot违背了这个原则。

栈和队列

Q. 在Java库中有对stacks 和 queues 的实现吗?

A. Java库中内建 java.util.Stack,但是你应该避免使用它如果你需要一个真正的栈的话。因为它是实现了额外的功能,比如访问第N个元素。另外,它也支持从栈底部插入元素,所以它看上去更像是一个队列。尽管实现了这些额外的功能对编程人员是一个加分,可是我们使用数据结构并不只是想使用所有功能,而是需要我们正好需要的那种结构。JAVA对于栈的实现就是一个典型的宽接口的例子。

Q. 我想使用数组来表示一个包含泛型的栈,但是以下代码编译报错。为什么?

private Item[] a = new Item[max]; 
oldfirst = first;

A. 不错的尝试。不幸的是,创建一个泛型数组在 Java 1.5里不支持。你可以使用cast,比如下面的写法:

private Item[] a = (Item[]) new Object[max]; 
oldfirst = first;

根本的原因是JAVA中的数组是“协变的(covariant)”,但是泛型并不是。比如, String[] 是 Object[]的一种子类型,但是 Stackf7e83be87db5cd2d9a8a0b8117b38cd4并不是 Stacka87fdacec66f0909fc0757c19f2d2b1d 的一种子类型。 许多程序员认为“协变的”数组是JAVA在数据类型方面的一个缺点。但是,如果我们不考虑泛型,“协变的”数组是有用的,比如实现 Arrays.sort(Comparable[]) 方法,然后当参数是 String[]时它也可以被正常调用。

Q. 可不可以在数组上使用 foreach 方式?

A. 可以的(虽然 数组并没有实现 Iterator 接口)。请参考下面的代码:

public static void main(String[] args) { 
  for (String s : args) 
  StdOut.println(s); 
}

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. 自动装箱机制会怎么处理下面的情况?

Integer a = null; 
int b = a;

A.它将返回一个运行时错误。基础类型不允许它对应的装箱类型里的值是null。 

Q. 为什么第一组打印的是 true,但是后面两组打印的是 false?

Integer a1 = 100; 
Integer a2 = 100; 
System.out.println(a1 == a2);  // true 
Integer b1 = new Integer(100); 
Integer b2 = new Integer(100); 
System.out.println(b1 == b2);  // false 
Integer c1 = 150; 
Integer c2 = 150; 
System.out.println(c1 == c2);  // false

A. 第二组代码打印 false 是因为 b1 和 b2 指向不同的 Integer 对象引用。第一组和第三组依赖于自动装箱机制。 令人意外的第一组打印了 true 是因为在 -128 和 127 之间的值会自动转换成同样的immutable型的Integer 对象。对于超出那个范围的数,Java会对于每一个数创建一个新的Integer对象。

Das obige ist der detaillierte Inhalt vonZusammenfassung häufig gestellter Fragen für Java-Anfänger (Sammlung). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn