JavaSE考试题库基础题123题

JavaSE考试题库123题

一、基础题(2分/题)

1. 用最有效的的方法算出2乘以8等于几?

2<<3。因为将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以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)有什么区别?

a==b:比较对象地址
a.equals(b):如果a对象没有重写过equals方法,效果和==相同,如果重写了就按照重写的规则比较。

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;是否正确,表达式15/2*2的值是多少

答案:不正确,float f = 3.4F;
答案:14

7. 编写代码实现两个变量值交换,int m = 3, n =5;

方法一:
int temp=m;
m=n;
n=temp;
缺点:需要一个临时变量。

方法二:
先将两个数加在一起
m=m+n;
n=m-n;
m=m-n;
缺点:当m和n较大时,有可能出现精度失准

方法三:
采用异或算法
m=m^n;
n=m^n;
m=m^n;
优点:没有上述两种方法的缺点。

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的基本数据类型有哪些?String是基本数据类型吗?

基本(8个):boolean(1bit),byte(1byte),short(2byte),char(2byte),int(4byte),long(8byte),float,double

String不是基本数据类型

9.数组有没有length()方法?String有没有length()方法?File有没有length()方法?ArrayList有没有length()方法?

数组没有length()方法,但是有length属性。
String和File有length()方法。
ArrayList没有length()方法,有size()方法获取有效元素个数。

10. String str = new String(“hello”);创建了哪些对象?

如果之前“hello”没出现过,2个,字符串常量池中有一个对象,堆中有一个字符串对象。
如果出现过,1个直接指向字符串常量池。

11.如何将String类型转化Number类型?举例说明String str = “123”;

		Integer num1 = new Integer(str);int num2 = Integer.parseInt(str);Integer num3 = Integer.valueOf(str);

下面的题目太SB了,编译器一运行的事儿,还拿出来显摆。

12. 以下代码的运行结果:

	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. 以下代码的执行结果

	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. 下面程序片段的输出结果是?

	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");
		}
	}

结果:报错
java: 不兼容的类型: int无法转换为boolean
if里面返回值应该是boolean型

15. 执行如下代码后,c的值是多少?

	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. 以下代码的运行结果?

	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:

        System.out.println(Integer.MIN_VALUE);
        System.out.println(1<<31);

17. 修正如下代码

下面是一段程序,目的是输出10个=,但是不小心代码写错了,现在需要修改代码,使得程序完成功能,但是只能“增加”或“修改”其中“一个”字符,很明显,将i–改为i++,可以完成功能,但是需要修改“两个”字符,所以并不是一个正确的答案?(脑筋急转弯?)

	public static void main(String[] args) {
		int n=10;
		for (int i = 0; i < n; i--) {
			System.out.println("=");
		}
	}

-i < n

18. 以下代码的运行结果是什么?

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. 以下代码的执行结果是什么

	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. 以下程序的运行结果:

	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. 以下代码的运行结果是:

	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);//自动拆箱,向下转型
        Integer i5 = 127;
        Integer i6 = 127;
        System.out.println(i5 == i6);//常量复用
	}
        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. 以下代码的运行结果:

	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. 以下代码的运行结果是?

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. 以下代码的运行结果是?

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. 以下程序的运行结果是:

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. 如下代码是否可以编译通过,如果可以,运行结果是什么?

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. 以下代码的运行结果是?

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
多态,在执行父类的构造方式时,调用者是this,this是Sub,调用的method是子类的method。

28. 以下代码的执行过程?

	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;
		}
	}

当你在一个方法中return一个基本类型的变量时,方法会创建一个新的变量,复制返回变量的值,然后把新变量传递给调用者。所以,返回变量的值也不会被改变。
result = x + y; -> return result;(要返回的result已经拷贝好了) -> result = x - y;(只是局部result是-2) -> return result;(返回的是拷贝的好的res)

29. 以下代码的运行结果?

	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的内部类,它只实现了List接口的部分方法,比如get和set,但没有实现add和remove等修改方法。所以,当你调用list.add(5)时,会抛出一个UnsupportedOperationException异常。如果你想要一个可以修改的List,你可以用new ArrayList<>(Arrays.asList(datas))来创建一个新的ArrayList对象,它会复制原来数组的元素,并支持所有的List方法。

30. 在{1}添加什么代码,可以保证如下代码输出100

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. 以下代码如何优化

if(username.equals(“admin”){
  ....
}

改成:

if("admin".equals(username)){
}

避免空指针

二、基础编程题(5分/题)

1、用循环控制语句打印输出:1+3+5+…+99=?的结果

	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、请写一个冒泡排序,实现{5,7,3,9,2}从小到大排序

		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、编写方法实现:求某年某月某日是这一年的第几天

提示:闰年(1)能被4整除不能被100整除(2)能被400整除

    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的整数,例如:f(5) = 5 + 4 + 3 + 2 + 1,f(10) = 10 + 9 + 8 + 7+ 6 + 5 + 4 + 3 + 2 + 1,请用非递归的方式完成方法long f( int n)的方法体。

	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!的和

	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)的方法体

        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、请编写代码使用把一个字符串反转,例如:hello1234,反转后:4321olleh。

        String str = "hello1234";
        StringBuilder sb = new StringBuilder(str);
        System.out.println(sb.reverse());

8、编写代码实现,从一个标准url里取出文件的扩展名,尽可能高效。

	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”,请写程序将字符串abc进行升序,可以使用JDK API中的现有的功能方法。

        String abc = "342567891";
        char[] chars = abc.toCharArray();
        Arrays.sort(chars);
        System.out.println(new String(chars));

10、编写一个懒汉式单例设计模式

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、请编写一个饿汉式单例设计模式

public enum  HungrySingleton {
    INSTANCE
}

12、补充如下枚举类型的代码,使得如下代码达到运行效果

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();//假设输入的是2
		Week w = Week.getByNumber(number);
		System.out.println("今天是:" + w);//今天是:TUESDAY(2,星期二)
	}

}
enum Week{1private int number;
	private String decription;
	
	private Week(int number, String decription) {
		this.number = number;
		this.decription = decription;
	}

答案:

答案:
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、写一段代码实现在遍历ArrayList时移除一个元素,例如:”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");

		                  补充代码                         
	}
}

答案:

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中,并遍历显示,请正确指定泛型

浙江省
	绍兴市
	温州市
	湖州市
	嘉兴市
	台州市
	金华市
	舟山市
	衢州市
	丽水市
海南省
	海口市
	三亚市
北京市
	北京市
        HashMap<String, List<String>> map = new HashMap<>();
        map.put("北京市", Arrays.asList("北京市"));
        map.put("海南省", Arrays.asList("海口市","三亚市"));
        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,以及所有信息现保存在一个Map中,现在要在map中,根据省份编号,查找这个省份下所有的城市。

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){
		            补充代码                     
	}
}

答案:

        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文件

		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的文本文件内容读取后存储到一个UTF-8的文本文件中。

        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、用实现Runnable接口的方式,启动一个线程完成在线程中打印1-100的数字

       new Thread(() -> {
           for (int i = 0; i < 100; i++) {
               System.out.println("i = " + i);
           }
       }).start();

三、基础简答题(5分/题)

1、break、continue、return的区别?

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:静态的,用它修改的方法,可以不用创建对象就可以调用
void:表示该方法没有返回值
main:Java的主方法名,JavaSE的程序入口
String[]:字符串数组,这是main方法的形参类型,可以通过命令行参数传值
args:这是main方法的形参名,如果要在main中使用命令行参数,可以遍历该args数组。

5、请解释Overload与Override的区别?

  • Overload是方法重载,指的是在同一个类中,方法名称相同,形参列表不同的两个或者多个方法,和返回值类型无关。
  • Override是方法的重写,重写必须遵守方法名和形参列表与父类的被重写的方法相同,而返回值类型可以小于等于父类被重写的方法(如果是基本数据类型和void必须相同),权限修饰符可以大于等于父类被重写的方法,抛出的异常列表可以小于等于父类被重写的方法。

6、final、finalize、finally的区别?

final: 常量const
finally:try catch finally
finalize:GC的方法

7、面向对象的基本特征有哪些?并作出解释

(1)封装:这样外界只能通过get/set方法来操作属性,行为变得可控。
(2)继承:代码的复用和扩展。
(3)多态:父类的变量指向子类的对象时,那么调用子类重写的方法时,运行的是子类重写过的代码,应用主要体现在多态参数和多态数组中。

8、请解释String、StringBuilder、StringBuffer的区别?

  • String是不可变的字符序列,因此字符串常量存储在常量池中,一旦拼接和修改就会产生新的String对象。
  • SringBuffer和StringBuilder是可变的字符序列,可以在原对象上进行append,insert,delete,replace等修改
  • StringBuilder是线程不安全的、StringBuffer是线程安全的。

9、如下关于String比较的代码的运行结果是什么

	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有什么区别?BigInteger和int、long有什么区别?

BigInteger和BigDecimal底层是字符串,理论上能够表示无线大的数,只能调用add等方法。
而float,double,int,long等是基本数据类型,可以直接用算术运算符,但是存储范围有限以及精度可能出错。

11、请对Java的基本数据类型与包装类做解释?

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有什么区别?

  • Comparable has abstract method: int compareTo(T obj),当this.val > obj.val return 1;
  • Comparators has abstract method:int compare(T t1, T t2),当t1>t2 return 1;
  • Arrays.sort(数组)或Collections.sort(Collection集合)方法时,TreeSet和TreeMap时元素默认按照Comparable比较规则排序。有Comparator则使用Comparator。

13、请解释Collection 和 Collections 的区别?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的区别?

  • ArrayList:数组,线程不安全,默认扩容1.5,插入第一个数据时开辟内存
  • Vector:数组,线程安全,默认扩容2,可以+扩容大小,声明时开辟内存
  • LinkedList:双向链表,增删快,随机访问慢。

15、Hashtable与HashMap的区别?如何解决那个线程不安全的问题?

  • hashtable 线程安全,数组+链表
  • hashmap线程不安全,数组+链表+红黑树
  • hashmap可以用Collections.synchronizedMap()同步增删

16、List、Map、Set 三个接口,存取元素时,各有什么特点?

list:有索引,可重复
map:K,V对,K不可重复
set:不可重复,hashset无序,treeset根据比较规则排序,linkedhashset根据插入顺序排序

17、ArrayList和LinkedList的底层实现(存储结构、扩容机制)

  • ArrayList:数组,add element,不够的时候: int newCapacity = oldCapacity + (oldCapacity >> 1);
  • LinkedList:双向链表

18、请列举一些常见的异常或错误类型(至少5个)

  • 运行时异常:
    ArrayIndexOutOfBoundsException
    ClassCastException
    ArithmeticException
    NullPointerException
  • 编译时异常:
    IOException
    FileNotFoundException
    EOFException
    ClassNotFoundException
    NoSuchMethodException

19、请解释Java异常处理的过程

(1)当程序运行到某一句代码,如果发生了异常(可能是JVM判定的异常,也可能是遇到throw的),程序都会停下来,然后把异常信息封装到异常的对象中,并且“抛”出
(2)如果有try…catch,如果有try…catch,就判断是否有catch可以捕获它,如果捕获了,程序就进入对应的catch块进行异常处理,处理后程序继续运行try…cath之后的代码。
(3)没有try…catch或者是有try…catch但是捕获不住,JVM都会把这个异常对象抛给上级。
(4)上级一旦接到异常对象,处理过程还是1,2,3
(5)如果一直抛,到main都没有处理,程序崩溃。

20、请解释Java异常处理机制相关的5个关键字

try:尝试执行可能发生异常的代码。
catch:尝试捕获try部分发生的异常。可以存在多个catch,如果多个catch的异常类型有继承关系,那么遵循子上父下。
finally:不管是否发生异常都要执行的代码放在finally块中。
throws:方法声明时显示抛出异常,指定该方法可能抛出的异常类型列表。
throw:手动抛出异常,可以抛出系统预定异常,也可以抛出用户自定异常,而且用户自定义异常必须用throw语句抛出,可以代替return语句结束方法运行。

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)将读取的字节储存在这个数组,返回的是实际读取的字节数。
Reader.read: return (int)char 0-65535
read(char[] data)将读取的字符存储在这个数组中,返回的是实际读取的字符数。
BufferedReader.readline()

23、Java反射机制的作用?

在运行时创建/获取/调用任意类型的对象,属性值,方法。

24、如何获取Class的对象?4种方式

Class.forName(“com…MyClass”)
MyObject.getClass()
MyClass.class
ClassLoader.loadClass(“com…MyClass”)

25、编写多线程程序有几种实现方式?

  • extends Thread
  • implements Runnable
  • implements Callable
  • ExecutorService

26、请阐述线程的生命周期?

在这里插入图片描述

27、Thread的start()和Runnable的run()有什么区别?

start():开始到就绪
run():线程方法体

28、sleep() 和 wait() 有什么区别?

  • 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、简要的写出进程和线程的区别(简单的写)?

  • 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虚拟机中内存分为哪些区域?每个区域的作用?哪些区域是线程共享的?

在这里插入图片描述
方法区:class,final ,static, 常量池
堆:实例对象
栈:局部变量表,方法出口
线程共享:方法区,堆

2. 请解释抽象类与接口的区别

共同点:不能直接被实例化
不同点:
1. 抽象类只能单继承,接口可以多继承
2. 抽象类有自己的构造器,任意权限的属性,方法,方法的默认实现;接口只有 public static 和 private static属性,public abstract method,default method,static method。

3. Object类中equals方法的实现是什么?重写一个equals方法有什么注意事项?(谁会背这个?)

Object类中的equals方法,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
在重写equals方法时,要注意满足离散数学上的特性
(1)自反性:对任意引用值x,x.equals(x)的返回值一定为true.
(2)对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
(3)传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true
(4)一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
(5)非空性:任何非空的引用值x,x.equals(null)的返回值一定为false

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明:
(1)相等对象必须具有相等的哈希码,
(2)两个对象的哈希码不相等,那么equals一定不相等。
两个对象的哈希码相等,那么equals结果可能相等也可能不相等

4. 比特(Bit),字节(Byte),字符(char/word),各有什么区别,通常说存储容量为KB,MB,GB,TB又是什么意思?通常说传输速率有bps和Bps有什么区别?

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的底层实现及扩容机制?

1)数组.size > threshold(length*load_factor)
length << 1
2) 哈希冲突尾插链表长度>8 && 数组.length < 64
length << 1

7.HashMap的相关常量

DEFAULT_LOAD_FACTOR:默认加载因子,值为0.75
TREEIFY_THRESHOLD:链表树化阈值,值为8
MIN_TREEIFY_CAPACITY:最小树化容量,值为64
UNTREEIFY_THRESHOLD:反树化阈值,值为6

8.如何实现序列化,有什么意义

如何实现序列化(5分):
(1)实现Serializable接口
(2)如果某个对象的属性也是引用数据类型,那么该数据类型也要实现Serializable接口
(3)如果要序列化,则使用一个输出流来构造一个对象输出流ObjectOutputStream并通过writeObject(Object obj)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流ObjectInputStream,然后通过readObject方法从流中读取对象。
(4)如果某些属性不参与序列化,如果是实现Serializable接口的,直接在属性前面加transient修饰

意义(3分):
方便网络传输
持久化

9.synchronized关键字的用法?

synchronized关键字是解决线程安全问题的方式之一。共有两种用法:
1、同步代码块
语法格式:
synchronized(锁对象){
需要加锁的代码
}
注意锁:
(1)任意类型的对象都可以当做锁
(2)多个线程之间共用同一个锁对象
(3)同步代码块的范围:不能太大,太小

2、同步方法
语法结构:
synchronized 【修饰符】 返回值类型 方法名(【形参列表】)【抛出异常列表】

同步方法的锁对象:
静态方法:当前类的Class对象,即当前类名.class
非静态方法:当前对象this(需要谨慎,确保是同一个this)

10.请列出你所知道的设计模式?

Factory,Singleton,Observer,Adapter

11.Object中有哪些方法

1protected Object clone()--->创建并返回此对象的一个副本。 
(2boolean equals(Object obj)--->指示某个其他对象是否与此对象“相等”。 
(3protected void finalize()--->当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。 
(4Class<? extendsObject> getClass()--->返回一个对象的运行时类型。 
(5int hashCode()--->返回该对象的哈希码值。 
(6void notify()--->唤醒在此对象监视器上等待的单个线程。 
(7void notifyAll()--->唤醒在此对象监视器上等待的所有线程。 
(8String toString()--->返回该对象的字符串表示。 
(9void wait()--->导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。 
	void wait(long timeout)--->导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll()方法,或者超过指定的时间量。 
	void wait(long timeout, int nanos)--->导致当前的线程等待,直到其他线程调用此对象的 notify()

12.请描述一下JVM加载class的过程和原理?

* load
* link
	** link:validation,preparation,analysis
* init

13、请阐述类加载器的类型

  • Bootstrap Classloader: 核心库
  • Platform Classloader: 扩展库
  • Application Classloader
  • Custom Classloader

五、较难编程题(8分/题)(就这?鉴定为弱智题)

1. 判断101-200之间有多少个素数,并输出所有素数

素数:除了1和它本身之外没有其他因子的自然数

	public static void main(String[] args) {
		System.out.println("101-200之间的素数有:");
		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次落地时,共经过多少米?第10次反弹多高?

        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 + "次落地时,经过了:" + distance + "米");
        System.out.println("第" + count + "次反弹的高度是:" + height + "米");

3. 用100元钱买100支笔,其中钢笔3元/支,圆珠笔2元/支,铅笔0.5元/支,问钢笔、圆珠笔和铅笔可以各买多少支?请写main方法打印需要买的数目。

        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的整数,例如:f(5) = 5 + 4 + 3 + 2 + 1,f(10) = 10 + 9 + 8 + 7+ 6 + 5 + 4 + 3 + 2 + 1,请用递归的方式完成方法long f( int n)的方法体。

    public static long f(int n){
        if(n==1)
            return 1;
        else
            return n+f(n-1);
    }

5. 求1+2!+3!+…+20!的和

        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个人多大?

    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步,共有多少种走法?

    public static int climbStairs(int n){
        if(n <= 2)
            return n;
        else
            return climbStairs(n-1)+climbStairs(n-2);
    }

8. 输入整型数98765,输出是56789

        int m = 0;
        while(n > 0) {
            m = m * 10 + n % 10;
            n /= 10;
        }
        return m;

9. 有一个字符串,其中包含中文字符、英文字符和数字字符,请统计和打印出各个字符的字数。

        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. 斐波纳契数列(Fibonacci Sequence),又称黄金分割数列。

11. 请使用二分查找算法查找字符数组{“a”,”b”,”c”,”d”,”e”,”f”,”g”,”h”}中”g”元素的位置?

    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. 消除下面集合中重复元素?

        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()方法编写一个生产者消费者设计模式程序?

        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”); 结果:aadccdd
注意:不能使用String及StringBuffer等类的replace等现成的替换API方法。

    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中的多个字符,字符也可能重复,例如:String data =

“aabcexmkduyruieiopxzkkkkasdfjxjdsds”;写一个程序,对于给定一个这样的字符串求出字符串出现次数最多的那个字母以及出现的次数(若次数最多的字母有多个,则全部求出)(有并列可能)

    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.假设日期段用两个6位长度的正整数表示,例如:(201401,201406)用来表示2014年1月到2014年6月,求两个日期段的重叠月份数。例如:输入:201401和201406,201403和201409,输出:4,解释:重叠月份:3,4,5,6月共4个月

    public static int overlap(int a1, int a2, int b1, int b2) {
        //如果两个日期段没有重叠,返回0
        if (a2 < b1 || b2 < a1) {
            return 0;
        }
        //否则,找出重叠部分的起始月份和结束月份
        int start = Math.max(a1, b1); //取较大的起始月份
        int end = Math.min(a2, b2); //取较小的结束月份
        //计算重叠月份数
        int yearDiff = end / 100 - start / 100; //计算年份差
        int monthDiff = end % 100 - start % 100; //计算月份差
        int overlap = yearDiff * 12 + monthDiff + 1; //计算总的重叠月份数,加1是因为包含起始月份和结束月份
        return overlap;
    }

4.入参为一个整型数组(Integer[] input),要求对入参(input)按奇偶数分成两个数组,要求启动两个线程,分别将入参(input)中的奇数和偶数输出到一个文件中,需要偶数线程每打印10个偶数以后,就将奇数线程打印10个奇数,如此交替进行。同时需要记录输出进度,每完成1000个数就在控制台中打印当前完成数量,并在所有线程结束后,在控制台打印“Done”

5.编程实现单向链表,并实现单向链表的反转。比如一个链表是这样的:1->2->3->4->5,通过反转后成为5->4->3->2->1,注:即实现单向链表类,在该类中提供一个单向链表的反转方法reverse,请写出完整代码

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.找出数组中一个值,使其左侧值的加和等于右侧值的加和,例如:1,2,5,3,2,4,2,结果为:第4个值

        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.编程实现:线程A向队列Q中不停写入数据,线程B从队列Q中不停读取数据(只要Q中有数据)

    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随机数字,进行排序,要求效率(例如:冒泡、选择、快排…等)

public class SortTest {
    //写一个排序算法1-100随机数字,进行排序,要求效率(例如:冒泡、选择、快排.....等)
    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];
            }
        }
    }

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值