目录
switch语句能否作用在byte上,能否作用在string,能否作用在long上?
使用final修饰一个变量时,是引用不能变,还是引用的对象不能变?
是否可以从一个static方法内部发出对非static方法的调用?
线程间通信 wait notify notifyAll yeild() join()方法
start()和run()有什么区别?可以直接调用Thread类的run方法吗?
sleep(),yield(),join() 方法有什么区别?为什么sleep()和yield()方法是静态的?
Java的线程优先级如何控制,高优先级的Java线程一定先执行吗?
详细说说hashmap?
hashmap是一个散列表,存储内容是key-value映射, 整型的(Integer)key和字符串类型(String)的value
Hashmap实现了Map接口,根据键的hashcode值存储数据,最多允许一个键为null,
hashmap是线程不安全的。
hashmap是无序的,即插入数据的顺序不会有序
一个.java的源文件是否可以包含多个类(不是内部类)?
可以有多个类,只能有一个public类,并且public的类名必须和文件名一致
java中&和&&的区别
&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符的两边的表达式的
结构都为true时,整个运算结果才为true,否则只要有一方为false,则表达式为false
&&具有短路功能,如果一个表达式为false,则不会进行第二个表达式 ,例如
if(str != null && str.equals(''))表达式,当str为null时,后面的表达式不会执行,如果将&&改成&,则出现空指针异常
&可以作为位运算符,当&操作符的两边的表达式不是boolean类型时,&表示按位与操作,例如
0x31 & 0x0f 的结果是 0x01 获取改整数的最低4个bit位。
java中如何跳出当前的多重循环?
在java中,要想跳出多重循环,可以在外面的循环语句前加一个标号,然后在里循环的代码体中使用带有标号的break语句,即可跳出外层循环。
for(int i=0;i<10;i++) {
for(int j=0;j<10 j++)
system.out.println("i="+i+"j"+j);
if (j==5) break ok;
}
通常不使用这种方法,让外层的循环表达式的结果可以收到里层循环体代码的控制,例如在二维数组中查找出某个数
```
int arr[][]={{1,2,3},{4,5,6,7},{9}};
boolean found=false;
for(int i=0; i<arr.length && !found;i++){
for (int j=0; j<arr[i].length;j++){
System.out.println("i="+i+"j="+j);
if (arr[i][j]==5){
found=ture;
break;
}
}
}
switch语句能否作用在byte上,能否作用在string,能否作用在long上?
在switch(expr1) 中,expr1只能是整数表达式或者是枚举常量,整数表达式可以是int类型或者integer包装类型。
由于byte,char,short类型都可以隐含转换成int
所以byte,char,shor以及包装类型都是可以的,所以,long,string类型的就不可以,不符合switch语法。
char变量中能不能存贮一个中文汉字,为什么?
char型变量时用来存储unicode编码的字符,在unicode字符集中包含了汉字,所以char型变量中可以存储汉字。因为unicode编码占有两个字节,所以char型变量也占有两个字节。
最有效的方法计算2乘以8等于几?
2 >> 3
因为一个数左移n位,就相当于乘以了2的几次方,一个数乘以8只要左移三位即可,
cpu位运算直接支持,效率最高
使用final修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用finnal修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
修改方式如下:
final StringBuffer a = new StringBuffer("immutable");
a=new StringBuffer("");
a.append("broken");
将final修饰的变量内容改变了。
==和equals方法究竟有什么区别?
解答:==操作符用来比较两个变量的值是否相等
equals方法:用于比较两个独立的对象的内容是否相等。
如下代码:
String a = new String("foo");
String b = new String("foo");
因为a 和b是两个不同的对象,即a和b中存储的数值是不相同的。所以a==b 返回false
因为两个对象中的内容是一样的,所以a.equals(b) 返回true
equals方法继承与object类,字符串的比较基本上都使用equals方法比较
静态变量和实例变量的区别?
静态变量需要加static关键字,而实例变量不加
静态变量不属于某个实例对象,而是属于类,也称类变量 通过类.类变量
实例变量必须创建对象后才可以通过这个对象来使用。
是否可以从一个static方法内部发出对非static方法的调用?
不可以,因为非static方法要与对象关联在一起,必须创建该对象后,才可以在该对象上使用,
而static方法调用非static方法,可能这个非static方法的对象实例还没有创建。
Integer和int的区别?
解答:int是java中原始数据类型,int的默认值是0
integer是java为int提供的封装类,Integer默认值是null
说一说java多态?
多态就是同一个接口,使用不同的实例而执行不同的操作
在使用多态方法时,首先检查父类中是否有该方法,如果没有则编译出错,如果有,再去调用子类的同名方法
多态存在的三个必要条件:
继承,
重写,
父类调佣指向子类对象 Parent p = new Child();
比如接口为打印机。黑色打印机需要调用打印机接口,打印出黑色内容
彩色打印机需要调用打印机接口,打印出彩色内容。
反射
什么是反射机制?
在运行状态中,对任意一个类,能知道这个类的所有属性和方法。
对于任意一个对象,能调用它的任意一个方法和属性。
这种动态获取信息的方法成为Java的反射机制
Java获取反射的三种方法
通过new对象实现反射机制
通过路径实现反射机制
通过类名实现反射机制
public class Student{
private int id;
}
String
String 不可变但不代表引用不可以变
String 类是final类,不可以被继承
String和StringBuffer,StringBuilder的区别是什么?
String的对象是不可变,使用private final char value[] 修饰
StringBuilder和StringBuffer 对象是可变的,使用数组保存字符串
String中对象是不可变的,也可以理解为常量,线程安全
StringBuilder并没有对方法加同步锁,所有线程不安全
StringBuffer对方法加了同步锁或调用加了同步锁,因此线程安全
多线程操作字符串使用StringBuffer
单线程操作字符串使用StringBuilder
操作少量数据使用String
多线程
创建线程有哪些方式?
1 继承Thread类创建线程类
2 通过Runnable接口创建线程类
3 通过 Callable和Future创建线程
采用Runnable,Callable接口的方式创建多线程
优势:
非常适合多个线程来处理同一份资源的情况,可以将 CPU 代码和数据分开 清晰的编程模型
劣势:
编程稍微复杂,如果要访问当前线程,必须使用Thread.currentThread()方法
采用继承Thread类的方式创建多线程
优势:
编写简单,访问当前线程,直接使用this接口获得当前线程
劣势:
线程类已经继承Thread类,不能在继承其他父类
Runnable和Callable的区别?
Callable规定重写的方法是call(), Runnable规定重写的方法是run()
Callable的任务执行后可返回值,Runnable的任务不能返回值
Call方法可以抛出异常,run方法不可以
Java线程中的5种基本状态?
1 新建状态 New
2 就绪状态 Runnable. 当调用线程的start()方法,线程进入就绪状态,即将等待CPU调度执行 但还没有执行
3 运作状态 Running 真正执行,线程要进入执行状态 必须先处于就绪状态
4 阻塞状态 Blocked 如程序执行 sleep() 方法 join方法 进入阻塞状态 阻塞状态分为三种
1 等待阻塞 运行中的线程执行wait方法
2 同步阻塞 线程在获取synchronized同步锁失败(被其他线程占用) 会进入同步阻塞状态
3 其他阻塞 如线程的sleep() 或join 或I/O请求 超时等 线程重新转入就绪状态
5 死亡状态 线程异常退出或结束生命周期(执行完了)
线程间通信 wait notify notifyAll yeild() join()方法
wait 线程自动释放器占有的对象锁,并等待notify
notify 唤醒正在wait的线程,并让它拿到对象锁
notifyAll 唤醒所有正在等待的wait 线程,需要注意只能释放一把锁,其他没有得到锁的线程会继续保持等待状态
Thread.yield() 方法将一个线程的操作暂时让给其他线程执行
join()方法 让一个线程强制运行,线程强制运行期间,其他线程无法运行。
start()和run()有什么区别?可以直接调用Thread类的run方法吗?
run()方法是线程的执行体
start()方法会启动线程,然后jvm会让线程去执行run()方法
可以,可以直接调用Thread的run方法,如果直接调用就会和普通方法一样
为了在线程执行代码,必须使用Thread.start()方法
sleep(),yield(),join() 方法有什么区别?为什么sleep()和yield()方法是静态的?
yield()方法可以让当前执行的线程暂停,不会阻塞该线程,只是将线程的状态从运行态转换到就绪态
线程暂定以后,只有比当前线程优先级高的线程,才会获得执行的机会
sleep()方法,在指定时间内暂定执行,这时进程进入阻塞态
sleep()方法可以让同优先级的进程或高优先级的进程获得执行机会,低优先级的进程也可以获得执行机会
sleep()方法不会释放锁标志,如果有synchronized同步块,其他线程仍然不能访问共享数据。
join()方法:强制执行线程,当前线程进入阻塞状态Blocked。 等待调用join()方法的线程结束才能继续执行。
为什么sleep()和yield方法是静态的?
Thread类的sleep()方法和yield()方法 是处理Running运行态的线程,所有非Running运行态的线程执行这两个方法没有意义。只能在当前正在执行的线程中工作,避免程序员错误的认为可以在其他非运行线程调用这些方法,这就是为什么这些方法是静态的
Java的线程优先级如何控制,高优先级的Java线程一定先执行吗?
Java中线程优先级的范围是[1,10] 高优先级的线程具有优先权,通过thread.setPriority(Thread.MAX_PRIORITY)的方式设置,默认优先级为5
设置了高优先级的线程也不一定会先执行
原因:线程的优先级依赖操作系统,不同的操作系统线程的优先级并不相同。不能很好的和java中线程的优先级一一对应
结论:java线程的优先级控制并一定可靠
synchronized关键字的作用是什么?
synchronized关键字用来控制线程同步,在多线程环境下,synchronized控制的代码段不被多个线程同时执行
synchronized可以加在一段代码上,也可以加在方法上
volatile关键字的作用
volatile关键字来保证可见性
当一个共享变量被volatile修饰时,它会保证修改的值会立即更新到内存中,当其他线程读取时,内存中为新值。
线程池
什么是线程池,如何创建线程池?
线程池就是提前创建若干个线程,如果有任务需要处理,线程池中的线程就会处理任务,处理完之后并不会销毁,而是等待下一个任务,如果需要频繁的创建和销毁线程的来处理任务,可以考虑用线程池来提高系统性能。
java.util.concurrent.Executor接口的实现用于创建线程池。
四种线程池的创建?
1 newCachedThreadPool 创建一个可缓存线程池
2 newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数
3 newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行
4 newSingleThreadPool 创建一个单线程的线程池,只会用唯一的工作线程来执行任务。
线程池的优点?
1 重用存在的线程,减少对象的创建与销毁 的开销
2 有效控制最大并发线程数,提高系统资源的使用率,避免竞争 避免堵塞
3 提供定时执行,定期执行,单线程,并发数控制等功能