JavaSE考試題庫基礎(chǔ)題123題
# 一、基礎(chǔ)題(2分/題)
## 1. 用最有效的的方法算出2乘以8等于幾?
2<<3。因為將一個數(shù)左移n位,就相當(dāng)于乘以了2的n次方,那么,一個數(shù)乘以8只要將其左移3位即可,而位運算cpu直接支持的,效率最高,所以,2乘以8等於幾的最效率的方法是2 << 3。?
## 2. Math.round(11.5)和Math.round(-11.5)的值是多少
Math.round(11.5):12
Math.round(-11.5):-11
## 3. 兩個對象a和b,請問a==b和a.equals(b)有什么區(qū)別?
`a==b`:比較對象地址
a.equals(b):如果a對象沒有重寫過equals方法,效果和==相同,如果重寫了就按照重寫的規(guī)則比較。
## 4. switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?
可以,不可以,可以(1.7后)
switch支持的類型byte,short,int,char
JDK1.5之后支持枚舉,
JDK1.7之后支持String類型。?
## 5. char型變量中是否可以存儲一個漢字?
能,一個char=一個unicode 可以表示一個漢字。
## 6. float f=3.4;是否正確,表達(dá)式15/2*2的值是多少
答案:不正確,float f = 3.4F;
答案:14
## 7. 編寫代碼實現(xiàn)兩個變量值交換,int m = 3, n =5;
方法一:
int temp=m;
m=n;
n=temp;
缺點:需要一個臨時變量。
方法二:
先將兩個數(shù)加在一起
m=m+n;
n=m-n;
m=m-n;
缺點:當(dāng)m和n較大時,有可能出現(xiàn)精度失準(zhǔn)
方法三:
采用異或算法
m=m^n;
n=m^n;
m=m^n;
優(yōu)點:沒有上述兩種方法的缺點。
```java
class TestExer1{
? ? public static void main(String[] args){
? ? ? ? int m=12;
? ? ? ? int n=5;
? ? ? ? System.out.println("m="+m+"n="+n);
? ? ? ? //方法一
? ? ? ? int temp=m;
? ? ? ? m=n;
? ? ? ? n=temp;
? ? ? ? System.out.println("m="+m+"n="+n);
? ? ? ? //方法二
? ? ? ? m=m+n;//m=12+5
? ? ? ? n=m-n;//n=17-5
? ? ? ? m=m-n;//m=17-12
? ? ? ? //方法三
? ? ? ? m=m^n;
? ? ? ? n=m^n;//(m^n)^n==m
? ? ? ? m=m^n;//(m^n)^m==n
? ? }
}
```
## 8.Java的基本數(shù)據(jù)類型有哪些?String是基本數(shù)據(jù)類型嗎?
基本(8個):boolean(1bit),byte(1byte),short(2byte),char(2byte),int(4byte),long(8byte),float,double
String不是基本數(shù)據(jù)類型?
## 9.數(shù)組有沒有l(wèi)ength()方法?String有沒有l(wèi)ength()方法?File有沒有l(wèi)ength()方法?ArrayList有沒有l(wèi)ength()方法?
數(shù)組沒有l(wèi)ength()方法,但是有l(wèi)ength屬性。
String和File有l(wèi)ength()方法。
ArrayList沒有l(wèi)ength()方法,有size()方法獲取有效元素個數(shù)。
## 10. String str = new String(“hello”);創(chuàng)建了哪些對象?
如果之前“hello”沒出現(xiàn)過,2個,字符串常量池中有一個對象,堆中有一個字符串對象。
如果出現(xiàn)過,1個直接指向字符串常量池。
## 11.如何將String類型轉(zhuǎn)化Number類型?舉例說明String str = “123”;
```java
Integer num1 = new Integer(str);
或
int num2 = Integer.parseInt(str);
或
Integer num3 = Integer.valueOf(str);
```
**下面的題目太SB了,編譯器一運行的事兒,還拿出來顯擺。**
## 12. 以下代碼的運行結(jié)果:
```java
public static void main(String[] args) {
? ? ? ? char x = 'x';
? ? ? ? int i = 10;
? ? ? ? System.out.println(true ? x : i);
? ? ? ? System.out.println(true ? 'x' : 10);
? ? ? ? System.out.println(true ? i : x);
? ? ? ? System.out.println(true ? 10 : 'x');
}
```
答案:
120
x
10
無輸出(沒有asc=10的字符?)
## 13. 以下代碼的執(zhí)行結(jié)果
```java
public static void main(String[] args) {
int a = 8, b = 3;
System.out.println(a>>>b);
System.out.println(a>>>b | 2);
}
```
答案:
1
3
## 14. 下面程序片段的輸出結(jié)果是?
```java
public static void main(String[] args) {
int a = 3;
int b = 1;
if(a = b){
System.out.println("Equal");
}else{
System.out.println("Not Equal");
}
}
```
結(jié)果:報錯
java: 不兼容的類型: int無法轉(zhuǎn)換為boolean
if里面返回值應(yīng)該是boolean型
## 15. 執(zhí)行如下代碼后,c的值是多少?
```java
public static void main(String[] args) {
int a = 0;
int c = 0;
do {
--c;
a = a - 1;
} while (a >= 0);
System.out.println("c = " + c);
}
```
c =-1
## 16. 以下代碼的運行結(jié)果?
```java
public static void main(String[] args) {
int i=10;
while(i>0){
i = i +1;
if(i==10){
break;
}
}
System.out.println("i=" + i);
}
```
?-2^31
注,下面輸出都是int的最小值,-2^31:
```java
? ? ? ? System.out.println(Integer.MIN_VALUE);
? ? ? ? System.out.println(1<<31);
```
## 17. 修正如下代碼
下面是一段程序,目的是輸出10個=,但是不小心代碼寫錯了,現(xiàn)在需要修改代碼,使得程序完成功能,但是只能“增加”或“修改”其中“一個”字符,很明顯,將i--改為i++,可以完成功能,但是需要修改“兩個”字符,所以并不是一個正確的答案?(腦筋急轉(zhuǎn)彎?)
```java
public static void main(String[] args) {
int n=10;
for (int i = 0; i < n; i--) {
System.out.println("=");
}
}
```
-i < n
## 18. 以下代碼的運行結(jié)果是什么?
```java
public class Test {
public static boolean foo(char c) {
System.out.print(c);
return true;
}
public static void main(String[] args) {
int i = 0;
for (foo('A'); foo('B') && (i < 2); foo('C')) {
i++;// 1 2
foo('D');
}
}
}
```
ABDCBDCB
## 19. 以下代碼的執(zhí)行結(jié)果是什么
```java
public static void main(String[] args) {
int i = 0;
change(i);
i = i++;
System.out.println("i = " + i);
}
public static void change(int i){
i++;
}
```
i = 0
## 20. 以下程序的運行結(jié)果:
```java
public static void main(String[] args) {
String str = new String("world");
char[] ch = new char[]{'h','e','l','l','o'};
change(str,ch);
System.out.println(str);
System.out.println(String.valueOf(ch));
}
public static void change(String str, char[] arr){
str = "change";
arr[0] = 'a';
arr[1] = 'b';
arr[2] = 'c';
arr[3] = 'd';
arr[4] = 'e';
}
```
答案:
world
abcde
## 21. 以下代碼的運行結(jié)果是:
```java
public static void main(String[] args) {
? ? ? ? Integer i1 = 128;
? ? ? ? Integer i2 = 128;
? ? ? ? int i3 = 128;
? ? ? ? int i4 = 128;
? ? ? ? System.out.println(i1 == i2);//false,超過-128~127,會new出新對象,比較地址值
? ? ? ? System.out.println(i3 == i4);//true
? ? ? ? System.out.println(i1 == i3);//自動拆箱,向下轉(zhuǎn)型
? ? ? ? Integer i5 = 127;
? ? ? ? Integer i6 = 127;
? ? ? ? System.out.println(i5 == i6);//常量復(fù)用
}
```
```java
? ? ? ? Integer a = new Integer(123);
? ? ? ? Integer b = new Integer(123);
? ? ? ? Integer c = 123;
? ? ? ? int d = 123;
? ? ? ? Integer e = new Integer(345);
? ? ? ? int f = 345;
? ? ? ? System.out.println(a == b);//false,new就是會包一層
? ? ? ? System.out.println(b == c);//false,new就是會包一層
? ? ? ? System.out.println(c == d);//true
? ? ? ? System.out.println(e == f);//true
```
## 22. 以下代碼的運行結(jié)果:
```java
public static void main(String[] args) {
double a = 2.0;
double b = 2.0;
Double c = 2.0;
Double d = 2.0;
System.out.println(a == b);//true
System.out.println(c == d);//false
System.out.println(a == d);//true
}
```
## 23. 以下代碼的運行結(jié)果是?
```java
public class Test {
int a;
int b;
public void f(){
a = 0;
b = 0;
int[] c = {0};
g(b,c);
System.out.println(a + " " + b + " " + c[0]);
}
public void g(int b, int[] c){
a = 1;
b = 1;
c[0] = 1;
}
public static void main(String[] args) {
Test t = new Test();
t.f();
}
}
```
答案:1 0 1
## 24. 以下代碼的運行結(jié)果是?
```java
public class Test {
static int x, y, z;
static {
int x = 5;
x--;
}
static {
x--;
}
public static void main(String[] args) {
System.out.println("x=" + x);
z--;
method();
System.out.println("result:" + (z + y + ++z));
}
public static void method() {
y = z++ + ++z;
}
}
```
x=-1
result:3
## 25. 以下程序的運行結(jié)果是:
```java
public class Test {
public static void main(String[] args) {
new A(new B());
}
}
class A{
public A(){
System.out.println("A");
}
public A(B b){
this();
System.out.println("AB");
}
}
class B{
public B(){
System.out.println("B");
}
}
```
B
A
AB
注意有換行
## 26. 如下代碼是否可以編譯通過,如果可以,運行結(jié)果是什么?
```java
interface A{
int x = 0;
}
class B{
int x = 1;
}
class C extends B implements A{
public void printX(){
System.out.println(x);
}
public static void main(String[] args) {
new C().printX();
}
}
```
x is ambiguous.
## 27. 以下代碼的運行結(jié)果是?
```java
public class Test {
public static void main(String[] args) {
Base b1 = new Base();
Base b2 = new Sub();
}
}
class Base{
Base(){
method(100);
}
public void method(int i){
System.out.println("base : " + i);
}
}
class Sub extends Base{
Sub(){
super.method(70);
}
public void method(int j){
System.out.println("sub : " + j);
}
}
```
base:100
sub:100
base:70
多態(tài),在執(zhí)行父類的構(gòu)造方式時,調(diào)用者是this,this是Sub,調(diào)用的method是子類的method。
## 28. 以下代碼的執(zhí)行過程?
```java
public static void main(String[] args) {
int test = test(3,5);
System.out.println(test);
}
public static int test(int x, int y){
int result = x;
try{
if(x<0 || y<0){
return 0;
}
result = x + y;
return result;
}finally{
result = x - y;
}
}
```
當(dāng)你在一個方法中return一個基本類型的變量時,方法會創(chuàng)建一個新的變量,復(fù)制返回變量的值,然后把新變量傳遞給調(diào)用者。所以,返回變量的值也不會被改變。
result = x + y; -> return result;(要返回的result已經(jīng)拷貝好了) -> result = x - y;(只是局部result是-2) -> return result;(返回的是拷貝的好的res)
## 29. 以下代碼的運行結(jié)果?
```java
public static void main(String[] args) {
Integer[] datas = {1,2,3,4,5};
List<Integer> list = Arrays.asList(datas);
list.add(5);
System.out.println(list.size());
}
```
UnsupportedOperation
這是因為Arrays.asList方法返回的不是一個真正的List,而是一個Arrays的內(nèi)部類,它只實現(xiàn)了List接口的部分方法,比如get和set,但沒有實現(xiàn)add和remove等修改方法。所以,當(dāng)你調(diào)用list.add(5)時,會拋出一個UnsupportedOperationException異常。如果你想要一個可以修改的List,你可以用new ArrayList<>(Arrays.asList(datas))來創(chuàng)建一個新的ArrayList對象,它會復(fù)制原來數(shù)組的元素,并支持所有的List方法。
## 30. 在{1}添加什么代碼,可以保證如下代碼輸出100
```java
public class Test {
public static void main(String[] args) {
MyThread m = new MyThread();
Thread t = new Thread(m);
t.start();
? ? ? ? {1}? ? ? ? ? ? ??
int j = m.i;
System.out.println(j);
}
}
class MyThread implements Runnable{
int i;
public void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i=100;
}
}
```
t.join()?
## 31. 以下代碼如何優(yōu)化
```java
if(username.equals(“admin”){
? ....
}
```
改成:
```java
if("admin".equals(username)){
}
```
避免空指針
# 二、基礎(chǔ)編程題(5分/題)
## 1、用循環(huán)控制語句打印輸出:1+3+5+...+99=?的結(jié)果
```java
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 99; i+=2) {
sum += i;
}
System.out.println("sum = " + sum);
}
```
## 2、請寫一個冒泡排序,實現(xiàn){5,7,3,9,2}從小到大排序
```java
int[] arr = { 5, 7, 3, 9, 2 };
for (int i = 1; i < arr.length; i++) {
for (int j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
```
## 3、編寫方法實現(xiàn):求某年某月某日是這一年的第幾天
提示:閏年(1)能被4整除不能被100整除(2)能被400整除
```java
? ? public static int calDay(int year,int month,int day){
? ? ? ? int[] dayOfMonth = {31,28,31,30,31,30,31,31,30,31,30,31};
? ? ? ? int sum = 0;
? ? ? ? for(int i = 0;i < month - 1;i++){
? ? ? ? ? ? sum += dayOfMonth[i];
? ? ? ? }
? ? ? ? sum += day;
? ? ? ? if(month > 2 && year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
? ? ? ? ? ? sum++;
? ? ? ? }
? ? ? ? return sum;
? ? }
```
## 4、通項公式如下:f(n)=n + (n-1) + (n-2) + .... + 1,其中n是大于等于5并且小于10000的整數(shù),例如:f(5) = 5 + 4 + 3 + 2 + 1,f(10) = 10 + 9 + 8 + 7+ 6 + 5 + 4 + 3 + 2 + 1,請用非遞歸的方式完成方法long f( int n)的方法體。
```java
public static long f(int n) {
long sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
```
## 5、求1+2!+3!+...+20!的和
```java
public static void main(String[] args)? {
long sum = 0;
for (int i = 1; i <= 20; i++) {
long temp = 1;
for (int j = 1; j <=i; j++) {
temp *= j;
}
sum += temp;
}
System.out.println("sum = " + sum);
}
```
## 6、輸出一個如下圖形,一共有n行,第n行有2n-1個*,完成方法public void printStar(int n)的方法體
```java
? ? ? ? int n = 5;
? ? ? ? for (int i = 0; i < n; i++) {
? ? ? ? ? ? for (int j = 0; j < n - i; j++) {
? ? ? ? ? ? ? ? System.out.print(" ");
? ? ? ? ? ? }
? ? ? ? ? ? for(int j = 0; j < 2 * i + 1; j++){
? ? ? ? ? ? ? ? System.out.print("*");
? ? ? ? ? ? }
? ? ? ? ? ? System.out.println();
? ? ? ? }
```
## 7、請編寫代碼使用把一個字符串反轉(zhuǎn),例如:hello1234,反轉(zhuǎn)后:4321olleh。
```java
? ? ? ? String str = "hello1234";
? ? ? ? StringBuilder sb = new StringBuilder(str);
? ? ? ? System.out.println(sb.reverse());
```
## 8、編寫代碼實現(xiàn),從一個標(biāo)準(zhǔn)url里取出文件的擴展名,盡可能高效。
```java
public static void main(String[] args) {
String str = fileExtNameFromUrl("http://localhost:8080/testweb/index.html");
System.out.println(str);
}
public static String fileExtNameFromUrl(String url){
? ? ? ? ? ? ? ? ? ? 補充代碼? ? ? ? ? ? ? ? ??
}
答案:
? ? public static String fileExtNameFromUrl(String url) {
? ? ? ? return url.substring(url.lastIndexOf(".") + 1);
? ? }
```
## 9、有一個字符串String abc = “342567891”,請寫程序?qū)⒆址產(chǎn)bc進行升序,可以使用JDK API中的現(xiàn)有的功能方法。
```java
? ? ? ? String abc = "342567891";
? ? ? ? char[] chars = abc.toCharArray();
? ? ? ? Arrays.sort(chars);
? ? ? ? System.out.println(new String(chars));
```
## 10、編寫一個懶漢式單例設(shè)計模式
```java
public class Singleton {
? ? private static volatile Singleton instance;
? ? private Singleton() {}
? ??
? ? public static Singleton getInstance() {
? ? ? ? if (instance == null) {
? ? ? ? ? ? synchronized(Singleton.class) {
? ? ? ? ? ? ? ? if (instance == null)
? ? ? ? ? ? ? ? ? ? instance = new Singleton();
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return instance;
? ? }
}
```
## 11、請編寫一個餓漢式單例設(shè)計模式
```java
public enum? HungrySingleton {
? ? INSTANCE
}
```
## 12、補充如下枚舉類型的代碼,使得如下代碼達(dá)到運行效果
```java
import java.util.Scanner;
public class TestWeek {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("今天是星期幾(1-7):");
int number = input.nextInt();//假設(shè)輸入的是2
Week w = Week.getByNumber(number);
System.out.println("今天是:" + w);//今天是:TUESDAY(2,星期二)
}
}
enum Week{
? ? ? ? ? ? ? ? ? ? (1)? ? ? ? ? ? ? ? ? ? ??
private int number;
private String decription;
private Week(int number, String decription) {
this.number = number;
this.decription = decription;
}
```
答案:
```java
答案:
enum Week{
MONDAY(1,"星期一"),
TUESDAY(2,"星期二"),
WEDNESDAY(3,"星期三"),
THURSDAY(4,"星期四"),
FRIDAY(5,"星期五"),
SATURDAY(6,"星期六"),
SUNDAY(7,"星期日");
private int number;
private String decription;
private Week(int number, String decription) {
this.number = number;
this.decription = decription;
}
public static Week getByNumber(int number){
switch(number){
case 1:
return MONDAY;
case 2:
return TUESDAY;
case 3:
return WEDNESDAY;
case 4:
return THURSDAY;
case 5:
return FRIDAY;
case 6:
return SATURDAY;
case 7:
return SUNDAY;
default:
return null;
}
}
@Override
public String toString() {
return super.toString()+"(" + number + ","+ decription + ")";
}
}
```
## 13、寫一段代碼實現(xiàn)在遍歷ArrayList時移除一個元素,例如:”java”?
```java
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("hello");
list.add("java");
list.add("world");
? ? ? ? ? ? ? ? ? 補充代碼? ? ? ? ? ? ? ? ? ? ? ? ?
}
}
```
答案:
```java
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("hello");
list.add("java");
list.add("world");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
if ("java".equals(next)) {
iterator.remove();
}
}
}
}
```
## 14、把如下信息添加到Map中,并遍歷顯示,請正確指定泛型
```java
浙江省
紹興市
溫州市
湖州市
嘉興市
臺州市
金華市
舟山市
衢州市
麗水市
海南省
??谑?/p>
三亞市
北京市
北京市
```
```java
? ? ? ? HashMap<String, List<String>> map = new HashMap<>();
? ? ? ? map.put("北京市", Arrays.asList("北京市"));
? ? ? ? map.put("海南省", Arrays.asList("??谑?#34;,"三亞市"));
? ? ? ? map.put("浙江省", Arrays.asList("紹興市","溫州市","湖州市","嘉興市","臺州市","金華市","舟山市","衢州市","麗水市"));
? ? ? ? map.keySet().forEach(key->{
? ? ? ? ? ? System.out.print(key+":");
? ? ? ? ? ? map.get(key).forEach(System.out::print);
? ? ? ? ? ? System.out.println();
? ? ? ? });
```
## 15、完成在如下Map中查詢城市信息
已知有省份Provice類型,有屬性省份編號id和名稱name,有城市City類型,有屬性城市編號id和名稱name,所屬省份編號pid,以及所有信息現(xiàn)保存在一個Map中,現(xiàn)在要在map中,根據(jù)省份編號,查找這個省份下所有的城市。
```java
import java.util.HashSet;
import java.util.HashMap;
import java.util.Set;
public class AreaManager {
private HashMap<Province,HashSet<City>> map;
public AreaManager(){
map = new HashMap<Province,HashSet<City>>();
HashSet<City> bj = new HashSet<City>();
bj.add(new City(1,"北京市",1));
map.put(new Province(1,"北京市"), bj);
HashSet<City> hn = new HashSet<City>();
hn.add(new City(1,"海口市",2));
hn.add(new City(2,"三亞市",2));
map.put(new Province(2,"海南省"), hn);
HashSet<City> zj = new HashSet<City>();
zj.add(new City(1,"紹興市",3));
zj.add(new City(2,"溫州市",3));
zj.add(new City(3,"湖州市",3));
zj.add(new City(4,"嘉興市",3));
zj.add(new City(5,"臺州市",3));
zj.add(new City(6,"金華市",3));
zj.add(new City(7,"舟山市",3));
zj.add(new City(8,"衢州市",3));
zj.add(new City(9,"麗水市",3));
map.put(new Province(3,"浙江省"), zj);
}
public HashSet<City> findCity(int pid){
? ? ? ? ? ? 補充代碼? ? ? ? ? ? ? ? ? ? ?
}
}
```
答案:
```java
? ? ? ? final HashSet<City>[] cities = new HashSet[]{null};
? ? ? ? map.keySet().forEach(key->{
? ? ? ? ? ? if(key.id == pid){
? ? ? ? ? ? ? ? cities[0] = map.get(key);
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? return cities[0];
```
## 16、請編寫代碼讀取一個項目根目錄下info.properties文件
```java
Properties pro = new Properties();
//相對于bin
// pro.load(ClassLoader.getSystemResourceAsStream("info.properties"));
//相對于項目根目錄
pro.load(new FileInputStream("info.properties"));
String username = pro.getProperty("user");
System.out.println(username);
```
## 17、請編寫代碼把一個GBK的文本文件內(nèi)容讀取后存儲到一個UTF-8的文本文件中。
```java
? ? ? ? try (FileInputStream fis = new FileInputStream("input/gbk.txt");
? ? ? ? ? ? ?InputStreamReader isr = new InputStreamReader(fis, "GBK");
? ? ? ? ? ? ?FileOutputStream fos = new FileOutputStream("output/utf8.txt");
? ? ? ? ? ? ?OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8")) {
? ? ? ? ? ? int c;
? ? ? ? ? ? while ((c = isr.read()) != -1) {
? ? ? ? ? ? ? ? osw.write(c);
? ? ? ? ? ? }
? ? ? ? }
```
## 18、用實現(xiàn)Runnable接口的方式,啟動一個線程完成在線程中打印1-100的數(shù)字
```java
? ? ? ?new Thread(() -> {
? ? ? ? ? ?for (int i = 0; i < 100; i++) {
? ? ? ? ? ? ? ?System.out.println("i = " + i);
? ? ? ? ? ?}
? ? ? ?}).start();
```
# 三、基礎(chǔ)簡答題(5分/題)
## 1、break、continue、return的區(qū)別?
break is used for switch or while/for;
continue is used for while/for;
return is used in method.
## 2、請列出一些常用的類、接口、包,各至少5個
常用類:String,Math,,ArrayList,HashMap,System
常用接口:Comparable,Comparator,Runnable,Serializable,Collection
常用包:java.lang, java.util,java.io,java.net,java.text,java.lang.reflect
## 3、訪問修飾符的作用范圍由大到小,及各自的范圍是什么?可以修飾什么?
public->protected->缺省(default)->private

外部類只能使用public或缺省。
如果是修飾類的成員,四種都可以。
## 4、請對public static void main(String[] args)的每一個單詞做解釋?
public:公共的,用它修改的類或成員在任意位置可見
static:靜態(tài)的,用它修改的方法,可以不用創(chuàng)建對象就可以調(diào)用
void:表示該方法沒有返回值
main:Java的主方法名,JavaSE的程序入口
String[]:字符串?dāng)?shù)組,這是main方法的形參類型,可以通過命令行參數(shù)傳值
args:這是main方法的形參名,如果要在main中使用命令行參數(shù),可以遍歷該args數(shù)組。
## 5、請解釋Overload與Override的區(qū)別?
* Overload是方法重載,指的是在同一個類中,方法名稱相同,形參列表不同的兩個或者多個方法,和返回值類型無關(guān)。
* Override是方法的重寫,重寫必須遵守方法名和形參列表與父類的被重寫的方法相同,而返回值類型可以小于等于父類被重寫的方法(如果是基本數(shù)據(jù)類型和void必須相同),權(quán)限修飾符可以大于等于父類被重寫的方法,拋出的異常列表可以小于等于父類被重寫的方法。
## 6、final、finalize、finally的區(qū)別?
final: 常量const
finally:try catch finally
finalize:GC的方法
## 7、面向?qū)ο蟮幕咎卣饔心男坎⒆鞒鼋忉?/p>
(1)封裝:這樣外界只能通過get/set方法來操作屬性,行為變得可控。
(2)繼承:代碼的復(fù)用和擴展。
(3)多態(tài):父類的變量指向子類的對象時,那么調(diào)用子類重寫的方法時,運行的是子類重寫過的代碼,應(yīng)用主要體現(xiàn)在多態(tài)參數(shù)和多態(tài)數(shù)組中。
## 8、請解釋String、StringBuilder、StringBuffer的區(qū)別?
* String是不可變的字符序列,因此字符串常量存儲在常量池中,一旦拼接和修改就會產(chǎn)生新的String對象。
* SringBuffer和StringBuilder是可變的字符序列,可以在原對象上進行append,insert,delete,replace等修改
* StringBuilder是線程不安全的、StringBuffer是線程安全的。
## 9、如下關(guān)于String比較的代碼的運行結(jié)果是什么
```java
public static void main(String[] args) {
String str1 = "1";
String str2 = "2";
String str3 = new String("1");
final String str4 = "2";
final String str5 = new String("2");
String str6 = "12";
String str7 = "1" + "2";
String str8 = str1 + "2";
String str9 = str1 + str2;
String str10 = str3 + str4;
String str11 = "1" + str4;
String str12 = "1" + str5;
String str13 = (str1 + str2).intern();
System.out.println("(1)"+ (str1 == str3)); //false
System.out.println("(2)"+ (str2 == str4)); //true
System.out.println("(3)"+ (str4 == str5)); //false
System.out.println("(4)"+ (str6 == str7)); //true
System.out.println("(5)"+ (str6 == str8)); //false
System.out.println("(6)"+ (str6 == str9)); //false
System.out.println("(7)"+ (str6 == str10)); //false
System.out.println("(8)"+ (str6 == str11)); //true
System.out.println("(9)"+ (str6 == str12)); //false
System.out.println("(10)"+ (str6 == str13)); //true
}
```
## 10、BigDecimal和float、double有什么區(qū)別?BigInteger和int、long有什么區(qū)別?
BigInteger和BigDecimal底層是字符串,理論上能夠表示無線大的數(shù),只能調(diào)用add等方法。
而float,double,int,long等是基本數(shù)據(jù)類型,可以直接用算術(shù)運算符,但是存儲范圍有限以及精度可能出錯。
## 11、請對Java的基本數(shù)據(jù)類型與包裝類做解釋?
boolean -> Boolean
byte -> Byte
short -> Short
char -> Character
int -> Integer
long -> Long
float -> Float
double -> Double
JDK1.5之后支持自動裝箱與自動拆箱。
## 12、java.lang.Comparable與java.util.Comparator有什么區(qū)別?
* Comparable has abstract method: int compareTo(T obj),當(dāng)this.val > obj.val return 1;
* Comparators has abstract method:int compare(T t1, T t2),當(dāng)t1>t2 return 1;
* Arrays.sort(數(shù)組)或Collections.sort(Collection集合)方法時,TreeSet和TreeMap時元素默認(rèn)按照Comparable比較規(guī)則排序。有Comparator則使用Comparator。
## 13、請解釋Collection 和 Collections 的區(qū)別?List、Set、Map是否繼承Collection?
Collection is top interface
Collections is tool utils
List and set extend from Collection, but map does not. map is lile Map<K,V>
## 14、請解釋Arraylist、Linkedlist和Vector的區(qū)別?
* ArrayList:數(shù)組,線程不安全,默認(rèn)擴容1.5,插入第一個數(shù)據(jù)時開辟內(nèi)存
* Vector:數(shù)組,線程安全,默認(rèn)擴容2,可以+擴容大小,聲明時開辟內(nèi)存
* LinkedList:雙向鏈表,增刪快,隨機訪問慢。
## 15、Hashtable與HashMap的區(qū)別?如何解決那個線程不安全的問題?
* hashtable 線程安全,數(shù)組+鏈表
* hashmap線程不安全,數(shù)組+鏈表+紅黑樹
* hashmap可以用Collections.synchronizedMap()同步增刪
## 16、List、Map、Set 三個接口,存取元素時,各有什么特點?
list:有索引,可重復(fù)
map:K,V對,K不可重復(fù)
set:不可重復(fù),hashset無序,treeset根據(jù)比較規(guī)則排序,linkedhashset根據(jù)插入順序排序
## 17、ArrayList和LinkedList的底層實現(xiàn)(存儲結(jié)構(gòu)、擴容機制)
* ArrayList:數(shù)組,add element,不夠的時候: int newCapacity = oldCapacity + (oldCapacity >> 1);
* LinkedList:雙向鏈表
## 18、請列舉一些常見的異常或錯誤類型(至少5個)
* 運行時異常:
ArrayIndexOutOfBoundsException
ClassCastException
ArithmeticException
NullPointerException
* 編譯時異常:
IOException
FileNotFoundException
EOFException
ClassNotFoundException
NoSuchMethodException
## 19、請解釋Java異常處理的過程
(1)當(dāng)程序運行到某一句代碼,如果發(fā)生了異常(可能是JVM判定的異常,也可能是遇到throw的),程序都會停下來,然后把異常信息封裝到異常的對象中,并且“拋”出
(2)如果有try...catch,如果有try...catch,就判斷是否有catch可以捕獲它,如果捕獲了,程序就進入對應(yīng)的catch塊進行異常處理,處理后程序繼續(xù)運行try..cath之后的代碼。
(3)沒有try...catch或者是有try...catch但是捕獲不住,JVM都會把這個異常對象拋給上級。
(4)上級一旦接到異常對象,處理過程還是1,2,3
(5)如果一直拋,到main都沒有處理,程序崩潰。
## 20、請解釋Java異常處理機制相關(guān)的5個關(guān)鍵字
try:嘗試執(zhí)行可能發(fā)生異常的代碼。
catch:嘗試捕獲try部分發(fā)生的異常??梢源嬖诙鄠€catch,如果多個catch的異常類型有繼承關(guān)系,那么遵循子上父下。
finally:不管是否發(fā)生異常都要執(zhí)行的代碼放在finally塊中。
throws:方法聲明時顯示拋出異常,指定該方法可能拋出的異常類型列表。
throw:手動拋出異常,可以拋出系統(tǒng)預(yù)定異常,也可以拋出用戶自定異常,而且用戶自定義異常必須用throw語句拋出,可以代替return語句結(jié)束方法運行。
## 21、Java中的IO流的四大基類是什么(2分),請列出常用的IO流類型(至少5個)(3分)
* Byte Stream: InputStream,OutputStream
* Char Stream:Reader,Writer
PrintStream/StreamWriter,ObjectInput/OutputStream,BufferedInput/OutputStream,BufferedReader/Writer。InputStreamReader/OutputStreamWriter
##? 22、InputStream里的read()返回的是什么值,read(byte[] data)是什么意思,返回的是什么值。Reader里的read()返回的是什么值,read(char[] data)是什么意思,返回的是什么值。如果想要一次讀取一行怎么辦?
InputStream.read: return (int)byte 0-255
read(byte[] data)將讀取的字節(jié)儲存在這個數(shù)組,返回的是實際讀取的字節(jié)數(shù)。
Reader.read: return (int)char 0-65535
read(char[] data)將讀取的字符存儲在這個數(shù)組中,返回的是實際讀取的字符數(shù)。
BufferedReader.readline()?
## 23、Java反射機制的作用?
在運行時創(chuàng)建/獲取/調(diào)用任意類型的對象,屬性值,方法。
## 24、如何獲取Class的對象?4種方式
Class.forName(“com....MyClass”)
MyObject.getClass()
MyClass.class
ClassLoader.loadClass("com...MyClass")
## 25、編寫多線程程序有幾種實現(xiàn)方式?
* extends Thread
* implements Runnable
* implements Callable
* ExecutorService?
## 26、請闡述線程的生命周期?

## 27、Thread的start()和Runnable的run()有什么區(qū)別?
start():開始到就緒
run():線程方法體
## 28、sleep() 和 wait() 有什么區(qū)別??
* wait() release lock but sleep() does not.
* wait() is a method of Object, only in sychronized code and must be called by a block object. sleep() is a static method of Thread.?
* wait()waits until notifyed, sleep() block until timer expires.
## 29、請闡述什么是線程安全問題,如何解決?
multithread,shared resources,read and write simultaneously
* synchonized: method or code block
* implements block interface
* volatile?
## 30、簡要的寫出進程和線程的區(qū)別(簡單的寫)?
* A process is a program in execution, while a thread is a basic unit of cpu scheduling whithin a progress.
*? Processes hava their own address space, thus isolated from each other.Threads can communicate with each other with shared memory more easily.
# 四、較難簡答題(8分/題)
## 1. Java虛擬機中內(nèi)存分為哪些區(qū)域?每個區(qū)域的作用?哪些區(qū)域是線程共享的?

方法區(qū):class,final ,static, 常量池
堆:實例對象
棧:局部變量表,方法出口
線程共享:方法區(qū),堆
## 2. 請解釋抽象類與接口的區(qū)別
共同點:不能直接被實例化
不同點:
1. 抽象類只能單繼承,接口可以多繼承
2. 抽象類有自己的構(gòu)造器,任意權(quán)限的屬性,方法,方法的默認(rèn)實現(xiàn);接口只有 public static 和 private static屬性,public abstract method,default method,static method。
## 3. Object類中equals方法的實現(xiàn)是什么?重寫一個equals方法有什么注意事項?(誰會背這個?)
Object類中的equals方法,對于任何非空引用值 x 和 y,當(dāng)且僅當(dāng) x 和 y 引用同一個對象時,此方法才返回 true(x == y 具有值 true)。?
在重寫equals方法時,要注意滿足離散數(shù)學(xué)上的特性
(1)自反性:對任意引用值x,x.equals(x)的返回值一定為true.
(2)對稱性:對于任何引用值x,y,當(dāng)且僅當(dāng)y.equals(x)返回值為true時,x.equals(y)的返回值一定為true;
(3)傳遞性:如果x.equals(y)=true, y.equals(z)=true,則x.equals(z)=true
(4)一致性:如果參與比較的對象沒任何改變,則對象比較的結(jié)果也不應(yīng)該有任何改變
(5)非空性:任何非空的引用值x,x.equals(null)的返回值一定為false
注意:當(dāng)此方法被重寫時,通常有必要重寫 hashCode 方法,以維護 hashCode 方法的常規(guī)協(xié)定,該協(xié)定聲明:
(1)相等對象必須具有相等的哈希碼,
(2)兩個對象的哈希碼不相等,那么equals一定不相等。
兩個對象的哈希碼相等,那么equals結(jié)果可能相等也可能不相等
## 4. 比特(Bit),字節(jié)(Byte),字符(char/word),各有什么區(qū)別,通常說存儲容量為KB,MB,GB,TB又是什么意思?通常說傳輸速率有bps和Bps有什么區(qū)別?
1 byte = 8 bit
1 char = 2 byte (java)
1KB = 1024Byte,1MB = 1024KB,1GB = 1024MB,1TB = 1024GB
1Mbps 大約等同 128 KBps
## 5. 運行時異常與編譯時異常有何異同?請列舉一些運行時異常和編譯時異常的類型。
運行時異常編譯器無法檢測,因此也不會強制要求程序員處理。
編譯時異常編譯器檢測到代碼拋出編譯時異常時,會要求程序員必須對該異常做處理(throws或try...catch)否則,編譯不通過。
* 運行時異常:
ArrayIndexOutOfBoundsException
ClassCastException
ArithmeticException
NullPointerException
* 編譯時異常:
IOException
FileNotFoundException
EOFException
ClassNotFoundException
NoSuchMethodException
## 6. HashMap的底層實現(xiàn)及擴容機制?
1)數(shù)組.size > threshold(length*load_factor)
length << 1
2)? 哈希沖突尾插鏈表長度>8 && 數(shù)組.length < 64
length << 1
## 7.HashMap的相關(guān)常量
DEFAULT_LOAD_FACTOR:默認(rèn)加載因子,值為0.75
TREEIFY_THRESHOLD:鏈表樹化閾值,值為8
MIN_TREEIFY_CAPACITY:最小樹化容量,值為64
UNTREEIFY_THRESHOLD:反樹化閾值,值為6
## 8.如何實現(xiàn)序列化,有什么意義
如何實現(xiàn)序列化(5分):
(1)實現(xiàn)Serializable接口
(2)如果某個對象的屬性也是引用數(shù)據(jù)類型,那么該數(shù)據(jù)類型也要實現(xiàn)Serializable接口
(3)如果要序列化,則使用一個輸出流來構(gòu)造一個對象輸出流ObjectOutputStream并通過writeObject(Object obj)方法就可以將實現(xiàn)對象寫出(即保存其狀態(tài));如果需要反序列化則可以用一個輸入流建立對象輸入流ObjectInputStream,然后通過readObject方法從流中讀取對象。
(4)如果某些屬性不參與序列化,如果是實現(xiàn)Serializable接口的,直接在屬性前面加transient修飾
意義(3分):
方便網(wǎng)絡(luò)傳輸
持久化
## 9.synchronized關(guān)鍵字的用法?
synchronized關(guān)鍵字是解決線程安全問題的方式之一。共有兩種用法:
1、同步代碼塊
語法格式:
synchronized(鎖對象){
需要加鎖的代碼
}
注意鎖:
(1)任意類型的對象都可以當(dāng)做鎖
(2)多個線程之間共用同一個鎖對象
(3)同步代碼塊的范圍:不能太大,太小
2、同步方法
語法結(jié)構(gòu):
synchronized 【修飾符】? 返回值類型? 方法名(【形參列表】)【拋出異常列表】
同步方法的鎖對象:
靜態(tài)方法:當(dāng)前類的Class對象,即當(dāng)前類名.class
非靜態(tài)方法:當(dāng)前對象this(需要謹(jǐn)慎,確保是同一個this)
## 10.請列出你所知道的設(shè)計模式?
Factory,Singleton,Observer,Adapter
## 11.Object中有哪些方法
```java
(1)protected Object clone()--->創(chuàng)建并返回此對象的一個副本。?
(2)boolean equals(Object obj)--->指示某個其他對象是否與此對象“相等”。?
(3)protected void finalize()--->當(dāng)垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調(diào)用此方法。?
(4)Class<? extendsObject> getClass()--->返回一個對象的運行時類型。?
(5)int hashCode()--->返回該對象的哈希碼值。?
(6)void notify()--->喚醒在此對象監(jiān)視器上等待的單個線程。?
(7)void notifyAll()--->喚醒在此對象監(jiān)視器上等待的所有線程。?
(8)String toString()--->返回該對象的字符串表示。?
(9)void wait()--->導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll() 方法。?
void wait(long timeout)--->導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll()方法,或者超過指定的時間量。?
void wait(long timeout, int nanos)--->導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對象的 notify()
```
## 12.請描述一下JVM加載class的過程和原理?
```java
* load
* link
** link:validation,preparation,analysis
* init
```
## 13、請闡述類加載器的類型
* Bootstrap Classloader: 核心庫
* Platform Classloader: 擴展庫
* Application Classloader
* Custom Classloader
# 五、較難編程題(8分/題)(就這?鑒定為弱智題)
## 1. 判斷101-200之間有多少個素數(shù),并輸出所有素數(shù)
素數(shù):除了1和它本身之外沒有其他因子的自然數(shù)
```java
public static void main(String[] args) {
System.out.println("101-200之間的素數(shù)有:");
for (int i = 101; i <= 200; i++) {
boolean flag = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
flag = false;
break;
}
}
if (flag) {
System.out.println(i);
}
}
}
```
## 2. 一個球從100米高度自由落下,每次落地后反跳回原高度的一半,再落下,求它在第10次落地時,共經(jīng)過多少米?第10次反彈多高?
```java
? ? ? ? double height = 100;
? ? ? ? double distance = height;
? ? ? ? int count = 10;
? ? ? ? for (int i = 0; i < count; i++) {
? ? ? ? ? ? height = height / 2;// 彈起的高度 第i次彈起的高度
? ? ? ? ? ? distance += height*2;// 加落下的距離
? ? ? ? }
? ? ? ? distance -= height;
? ? ? ? System.out.println("第" + count + "次落地時,經(jīng)過了:" + distance + "米");
? ? ? ? System.out.println("第" + count + "次反彈的高度是:" + height + "米");
```
## 3. 用100元錢買100支筆,其中鋼筆3元/支,圓珠筆2元/支,鉛筆0.5元/支,問鋼筆、圓珠筆和鉛筆可以各買多少支?請寫main方法打印需要買的數(shù)目。
```java
? ? ? ? int money = 100;
? ? ? ? int count = 100;
? ? ? ? int pen = 3;
? ? ? ? int ballPen = 2;
? ? ? ? double pencil = 0.5;
? ? ? ? for (int i = 0; i < money / pen; i++) {
? ? ? ? ? ? for (int j = 0; j < money / ballPen; j++) {
? ? ? ? ? ? ? ? for (int k = 0; k < money / pencil; k++) {
? ? ? ? ? ? ? ? ? ? if (i + j + k == count && i * pen + j * ballPen + k * pencil == money) {
? ? ? ? ? ? ? ? ? ? ? ? System.out.println("鋼筆:" + i + "支,圓珠筆:" + j + "支,鉛筆:" + k + "支");
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
```
## 4. 通項公式如下:f(n)=n + (n-1) + (n-2) + .... + 1,其中n是大于等于5并且小于10000的整數(shù),例如:f(5) = 5 + 4 + 3 + 2 + 1,f(10) = 10 + 9 + 8 + 7+ 6 + 5 + 4 + 3 + 2 + 1,請用遞歸的方式完成方法long f( int n)的方法體。
```java
? ? public static long f(int n){
? ? ? ? if(n==1)
? ? ? ? ? ? return 1;
? ? ? ? else
? ? ? ? ? ? return n+f(n-1);
? ? }
```
## 5. 求1+2!+3!+...+20!的和
```java
? ? ? ? long mul;
? ? ? ? long sum = 0;
? ? ? ? for (int j = 1; j <= 20; j++) {
? ? ? ? ? ? mul = 1;
? ? ? ? ? ? for (int i = 1; i <= j; i++) {
? ? ? ? ? ? ? ? mul *= i;
? ? ? ? ? ? }
? ? ? ? ? ? sum += mul;
? ? ? ? }
? ? ? ? System.out.println("sum = " + sum);
```
## 6. 第一個人10歲,第2個比第1個人大2歲,以此類推,請用遞歸方式計算出第8個人多大?
```java
? ? public static int getAge(int n) {
? ? ? ? if (n == 1)
? ? ? ? ? ? return 10;
? ? ? ? else
? ? ? ? ? ? return 2 + getAge(n - 1);
? ? }
? ??
? ? public static void main(String[] args) {
? ? ? ? System.out.println("getAge(8) = " + getAge(8));
? ? }
```
## 7. 有n步臺階,一次只能上1步或2步,共有多少種走法?
```java
? ? public static int climbStairs(int n){
? ? ? ? if(n <= 2)
? ? ? ? ? ? return n;
? ? ? ? else
? ? ? ? ? ? return climbStairs(n-1)+climbStairs(n-2);
? ? }
```
## 8. 輸入整型數(shù)98765,輸出是56789
```java
? ? ? ? int m = 0;
? ? ? ? while(n > 0) {
? ? ? ? ? ? m = m * 10 + n % 10;
? ? ? ? ? ? n /= 10;
? ? ? ? }
? ? ? ? return m;
```
## 9. 有一個字符串,其中包含中文字符、英文字符和數(shù)字字符,請統(tǒng)計和打印出各個字符的字?jǐn)?shù)。
```java
? ? ? ? String content = "中中國55kkfff";
? ? ? ? HashMap<Character,Integer> map = new HashMap<>();
? ? ? ? char[] chars = content.toCharArray();
? ? ? ? for (char aChar : chars) {
? ? ? ? ? ? if(map.containsKey(aChar)){
? ? ? ? ? ? ? ? map.put(aChar,map.get(aChar)+1);
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? map.put(aChar,1);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? map.keySet().forEach(key-> System.out.println(key+"="+map.get(key)));
```
## 10. 斐波納契數(shù)列(Fibonacci Sequence),又稱黃金分割數(shù)列。
## 11. 請使用二分查找算法查找字符數(shù)組{“a”,”b”,”c”,”d”,”e”,”f”,”g”,”h”}中”g”元素的位置?
```java
? ? public static void main(String[] args) {
? ? ? ? char[] arr = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
? ? ? ? System.out.println(BinarySearch(arr, 'i'));
? ? }
? ? public static int BinarySearch(char[] arr, char c) {
? ? ? ? int start = 0;
? ? ? ? int end = arr.length - 1;
? ? ? ? int mid = start + (end + 1 - start) / 2;
? ? ? ? while (start < end) {
? ? ? ? ? ? if (arr[mid] == c)
? ? ? ? ? ? ? ? return mid;
? ? ? ? ? ? else if (arr[mid] > c)
? ? ? ? ? ? ? ? end = mid;
? ? ? ? ? ? else
? ? ? ? ? ? ? ? start = mid;
? ? ? ? ? ? mid = start + (end + 1 - start) / 2;
? ? ? ? }
? ? ? ? return -1;
? ? }
```
## 12. 消除下面集合中重復(fù)元素?
```java
? ? ? ? List list = Arrays.asList(1,2,3,3,4,4,5,5,6,1,9,3,25,4);
? ? ? ? list.stream().distinct().forEach(System.out::println);
```
## 13. 請用wait()和notify()方法編寫一個生產(chǎn)者消費者設(shè)計模式程序??
```java
? ? ? ? Queue<Integer> queue = new ArrayBlockingQueue(10);
? ? ? ? new Thread(
? ? ? ? ? ? ? ? () -> {
? ? ? ? ? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? ? ? ? ? if (queue.size() < 10) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? queue.add(new Random().nextInt(100));
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("put");
? ? ? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? synchronized (queue) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? queue.wait();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? throw new RuntimeException(e);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ).start();
? ? ? ? new Thread(
? ? ? ? ? ? ? ? () -> {
? ? ? ? ? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? ? ? ? ? if (!queue.isEmpty())
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(queue.poll());
? ? ? ? ? ? ? ? ? ? ? ? else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? synchronized (queue) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? queue.notify();
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ).start();
```
# 六、附加題(10分)
## 1.編寫代碼完成如下功能
public static String replace(String text, String target, String replace){
....
}
示例:replace(“aabbccbb”, “bb”, “dd”);? 結(jié)果:aadccdd
注意:不能使用String及StringBuffer等類的replace等現(xiàn)成的替換API方法。
```java
? ? static boolean isMatch(String str, String target) {
? ? ? ? for (int i = 0; i < target.length(); i++) {
? ? ? ? ? ? if (str.charAt(i) != target.charAt(i)) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return true;
? ? }
? ? public static String replace(String text, String target, String replace) {
? ? ? ? int i = 0;
? ? ? ? while (i + target.length() < text.length()){
? ? ? ? ? ? if (isMatch(text.substring(i, i + target.length()), target)) {
? ? ? ? ? ? ? ? text = text.substring(0, i) + replace + text.substring(i + target.length());
? ? ? ? ? ? ? ? i += replace.length();
? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? i++;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return text;
? ? }
```
## 2. 一個字符串中可能包含a-z中的多個字符,字符也可能重復(fù),例如:String data =?
“aabcexmkduyruieiopxzkkkkasdfjxjdsds”;寫一個程序,對于給定一個這樣的字符串求出字符串出現(xiàn)次數(shù)最多的那個字母以及出現(xiàn)的次數(shù)(若次數(shù)最多的字母有多個,則全部求出)(有并列可能)
```java
? ? public static void main(String[] args) {
? ? ? ? String data = "aabcexmkduyruieiopxzkkkkasdfjxjdsds";
? ? ? ? HashMap<Character, Integer> map = new HashMap<>();
? ? ? ? for (char c : data.toCharArray()) {
? ? ? ? ? ? if (map.containsKey(c)) map.put(c, map.get(c) + 1);
? ? ? ? ? ? else map.put(c, 1);
? ? ? ? }
? ? ? ? //求出最大的value
? ? ? ? int maxval = Collections.max(map.values());
? ? ? ? for (Map.Entry<Character, Integer> e : map.entrySet()) {
? ? ? ? ? ? if (e.getValue() == maxval)
? ? ? ? ? ? ? ? System.out.println(e.getKey() + "=" + e.getValue());
? ? ? ? }
? ? }
```
## 3.假設(shè)日期段用兩個6位長度的正整數(shù)表示,例如:(201401,201406)用來表示2014年1月到2014年6月,求兩個日期段的重疊月份數(shù)。例如:輸入:201401和201406,201403和201409,輸出:4,解釋:重疊月份:3,4,5,6月共4個月
```java
? ? public static int overlap(int a1, int a2, int b1, int b2) {
? ? ? ? //如果兩個日期段沒有重疊,返回0
? ? ? ? if (a2 < b1 || b2 < a1) {
? ? ? ? ? ? return 0;
? ? ? ? }
? ? ? ? //否則,找出重疊部分的起始月份和結(jié)束月份
? ? ? ? int start = Math.max(a1, b1); //取較大的起始月份
? ? ? ? int end = Math.min(a2, b2); //取較小的結(jié)束月份
? ? ? ? //計算重疊月份數(shù)
? ? ? ? int yearDiff = end / 100 - start / 100; //計算年份差
? ? ? ? int monthDiff = end % 100 - start % 100; //計算月份差
? ? ? ? int overlap = yearDiff * 12 + monthDiff + 1; //計算總的重疊月份數(shù),加1是因為包含起始月份和結(jié)束月份
? ? ? ? return overlap;
? ? }
```
## 4.入?yún)橐粋€整型數(shù)組(Integer[] input),要求對入?yún)?input)按奇偶數(shù)分成兩個數(shù)組,要求啟動兩個線程,分別將入?yún)?input)中的奇數(shù)和偶數(shù)輸出到一個文件中,需要偶數(shù)線程每打印10個偶數(shù)以后,就將奇數(shù)線程打印10個奇數(shù),如此交替進行。同時需要記錄輸出進度,每完成1000個數(shù)就在控制臺中打印當(dāng)前完成數(shù)量,并在所有線程結(jié)束后,在控制臺打印“Done”
## 5.編程實現(xiàn)單向鏈表,并實現(xiàn)單向鏈表的反轉(zhuǎn)。比如一個鏈表是這樣的:1->2->3->4->5,通過反轉(zhuǎn)后成為5->4->3->2->1,注:即實現(xiàn)單向鏈表類,在該類中提供一個單向鏈表的反轉(zhuǎn)方法reverse,請寫出完整代碼
```java
class Node {
? ? int data;
? ? Node next;
? ? public Node(int data) {
? ? ? ? this.data = data;
? ? }
}
public class LinkReverseTest {
? ? public static void main(String[] args) {
? ? ? ? Node head = new Node(0);
? ? ? ? Node cur = head;
? ? ? ? for (int i = 1; i < 9; i++) {
? ? ? ? ? ? cur.next = new Node(i);
? ? ? ? ? ? cur = cur.next;
? ? ? ? }
? ? ? ? print(head);
? ? ? ? head = reverse(head);
? ? ? ? print(head);
? ? }
? ? public static Node reverse(Node head) {
? ? ? ? if (head == null || head.next == null)
? ? ? ? ? ? return null;
? ? ? ? Node pre = head;
? ? ? ? Node cur = head.next;
? ? ? ? Node aft;
? ? ? ? head.next = null;
? ? ? ? while (cur != null) {
? ? ? ? ? ? aft = cur.next;
? ? ? ? ? ? cur.next = pre;
? ? ? ? ? ? pre = cur;
? ? ? ? ? ? cur = aft;
? ? ? ? }
? ? ? ? return pre;
? ? }
? ? public static void print(Node head) {
? ? ? ? Node cur = head;
? ? ? ? while (cur != null) {
? ? ? ? ? ? System.out.println(cur.data);
? ? ? ? ? ? cur = cur.next;
? ? ? ? }
? ? }
}
```
## 6.找出數(shù)組中一個值,使其左側(cè)值的加和等于右側(cè)值的加和,例如:1,2,5,3,2,4,2,結(jié)果為:第4個值
```java
? ? ? ? int[] arr = {1, 2, 5, 3, 2, 4, 2};
? ? ? ? int totalSum = Arrays.stream(arr).sum();
? ? ? ? int curSum = 0;
? ? ? ? for (int i = 0; i < arr.length; i++) {
? ? ? ? ? ? if (curSum * 2 + arr[i] == totalSum)
? ? ? ? ? ? ? ? System.out.println("No." + (i + 1));
? ? ? ? ? ? curSum += arr[i];
? ? ? ? }
```
## 7.編程實現(xiàn):線程A向隊列Q中不停寫入數(shù)據(jù),線程B從隊列Q中不停讀取數(shù)據(jù)(只要Q中有數(shù)據(jù))
```java
? ? public static void main(String[] args) {
? ? ? ? Queue<Double> queue = new ArrayBlockingQueue<>(10);
? ? ? ? new Thread(
? ? ? ? ? ? ? ? () -> {
? ? ? ? ? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? ? ? queue.add(Math.random());
? ? ? ? ? ? ? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ).start();
? ? ? ? new Thread(
? ? ? ? ? ? ? ? () -> {
? ? ? ? ? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? ? ? ? ? if(!queue.isEmpty())
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(queue.poll());
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ).start();
? ? }
```
## 8.寫一個排序算法1-100隨機數(shù)字,進行排序,要求效率(例如:冒泡、選擇、快排.....等)
```java
public class SortTest {
? ? //寫一個排序算法1-100隨機數(shù)字,進行排序,要求效率(例如:冒泡、選擇、快排.....等)
? ? public static void main(String[] args) {
? ? ? ? int[] arr = new int[100];
? ? ? ? for (int i = 0; i < 100; i++)
? ? ? ? ? ? arr[i] = new Random().nextInt(100);
? ? ? ? Arrays.stream(arr).mapToObj(i -> i + ",").forEach(System.out::print);
? ? ? ? System.out.println();
? ? ? ? int[] copy = Arrays.copyOf(arr, arr.length);
? ? ? ? bubbleSort(copy);
? ? ? ? Arrays.stream(copy).mapToObj(i -> i + ",").forEach(System.out::print);
? ? ? ? System.out.println();
? ? ? ? int[] copy1 = Arrays.copyOf(arr, arr.length);
? ? ? ? quickSort(copy1);
? ? ? ? Arrays.stream(copy1).mapToObj(i -> i + ",").forEach(System.out::print);
? ? ? ? System.out.println();
? ? ? ? int[] copy2 = Arrays.copyOf(arr, arr.length);
? ? ? ? selectSort(copy2);
? ? ? ? Arrays.stream(copy2).mapToObj(i -> i + ",").forEach(System.out::print);
? ? ? ? System.out.println();
? ? }
? ? public static void bubbleSort(int[] arr) {
? ? ? ? for (int i = 0; i < arr.length; i++) {
? ? ? ? ? ? for (int j = 1; j < arr.length - i; j++) {
? ? ? ? ? ? ? ? if (arr[j] < arr[j - 1]) {
? ? ? ? ? ? ? ? ? ? arr[j] = arr[j] ^ arr[j - 1];
? ? ? ? ? ? ? ? ? ? arr[j - 1] = arr[j] ^ arr[j - 1];
? ? ? ? ? ? ? ? ? ? arr[j] = arr[j] ^ arr[j - 1];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? public static void quickSort(int[] arr) {
? ? ? ? qs(arr, 0, arr.length - 1);
? ? }
? ? public static void qs(int[] arr, int low, int high) {
? ? ? ? if (low >= high)
? ? ? ? ? ? return;
? ? ? ? int pivot = partition(arr, low, high);
? ? ? ? qs(arr, low, pivot - 1);
? ? ? ? qs(arr, pivot + 1, high);
? ? }
? ? public static int partition(int[] arr, int low, int high) {
? ? ? ? int pivot = arr[low];
? ? ? ? while (low < high) {
? ? ? ? ? ? while (low < high && arr[high] >= pivot)
? ? ? ? ? ? ? ? high--;
? ? ? ? ? ? arr[low] = arr[high];
? ? ? ? ? ? while (low < high && arr[low] <= pivot)
? ? ? ? ? ? ? ? low++;
? ? ? ? ? ? arr[high] = arr[low];
? ? ? ? }
? ? ? ? arr[low] = pivot;
? ? ? ? return low;
? ? }
? ? public static void selectSort(int[] arr) {
? ? ? ? //選擇排序
? ? ? ? for (int i = 0; i < arr.length-1; i++) {
? ? ? ? ? ? int minIdx = i;
? ? ? ? ? ? for (int j = i + 1; j < arr.length; j++) {
? ? ? ? ? ? ? ? if (arr[j] < arr[minIdx])
? ? ? ? ? ? ? ? ? ? minIdx = j;
? ? ? ? ? ? }
? ? ? ? ? ? if (minIdx != i) {
? ? ? ? ? ? ? ? arr[i] = arr[i] ^ arr[minIdx];
? ? ? ? ? ? ? ? arr[minIdx] = arr[i] ^ arr[minIdx];
? ? ? ? ? ? ? ? arr[i] = arr[i] ^ arr[minIdx];
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
```