java知识点

1. == 和 equals 的区别
 1. 是比较运算符,而equals是object类的一个方法
 2. 当比较的是数值时,
和 equals 之间简单的比较两个变量是否相等
 3. 当比较的是对象时,equals 之间简单的比较两个变量是否相等,而==则是比较的是两者的内存是否相等

		String a = new String("java");
        String b = new String("java");
        String c = "122";
        String d = "122";

        System.out.println(a==b); // false
        System.out.println(a.equals(b));// true
        System.out.println(c.equals(d));// true
        System.out.println(c==d);// true

2. &和&&的区别
 1. &是按位运算符, &&是逻辑运算符
 2. 如(1+2=4&1+3=4)就算知道第一个条件是false,依然会执行下1+3,而&&则不会

3. final有哪些用法
 1. 被final修饰的类不可以被继承
 2. 被final修饰的方法不可以被重写
 3. 被final修饰的变量不可以被改变,如果修是引用,那么表示引用不可变,引用指向的内容可变
 4. 被final修饰的方法,JVM会尝试将其内联,以提高运行效率
 5. 被final修饰的常量,在编译阶段会存入常量池中

4. int和Integer的区别
 1. Integer是int的保证类型,在拆箱和装箱中,二者自动转换,int是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象
 2. Integer对象会占用更多的内存,Integer是一个对象,需要存储对象的的元数据,但是int是一个原始类型的数据,所以占用的空间更少

5. String,StringBuffer和StringBuilder的区别
 1. String是字符串常量,StringBuffer字符串变量(线程安全),StringBuilder字符串变量(线程不安全)
 2. String是不可变对象,每次对String类型进行操作都等同于产生了一个新的String对象,然后指向新的String对象,所以尽量不在对String进行大量的拼接操作,否则会产生很多临时对象,导致GC开始工作,影响系统性能
 3. StingBuffer是对对象本身操作,而不是产生新的对象,因此再有大量拼接操作时,建议使用StingBuffer
 4. StringBuffer是线程安全的可变字符串,因为StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,而StringBuilder的方法则没有该关键字,所以不能保证线程安全(一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞)
 5. 运行速度:StringBuilder > StringBuffer > String
 6. 适用场景:
   String:适用于少量字符串操作的情况
   StingBuilder:适用于单线程下字符串缓冲区进行大量操作的情况
   StringBuffer:适用于多线程下在字符串缓冲区进行大量操作的情况

6. java中int char long各占多少个字节
在这里插入图片描述
7. java中使用什么类型表示价格比较好
  如果不是特别关心内存和性能的话,使用BigDecimal,否则使用预定义精度的double类型

8. 什么是多线程上下文切换
  多线程的上下文切换是指cpu控制权由一个已经正在运行的线程切换到另一个就绪并等待获取cpu执行权的过程

9. 如何判断一个对象是否应该被回收
  这就是所谓的对象存活性判断,常用的方法有两种:
    1. 引用计数法(python用的就是各种)
    2. 对象可达性分析(由于引用计数法存在互相引用导致无法进行GC的问题,所以目前JVM虚拟机多使用对象可达性分析算法)

10. 创建线程的方式都有哪些,有什么区别
  通过实现java.lang.Runnable或者通过扩展java.lang.Thread类,Runnable可能会更优:
    1. Java不支持多继承,因此扩展Thread类就代表这个子类不能扩展其他类,而实现Runnable接口的类还可以扩展另一个类
    2. 类可能只要求可执行即可,因此继承整个Thread类的开销过大

11. Thread类中的start()和run()方法有什么区别
  start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样,当你调用run()方法的时候,只是会在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程

12. 怎么检测一个线程是否持有对象监视器
  Thread类提供了一个holdsLock(Object obj)方法,当且仅当对象obj的监视器被一条线程持有的时候才会返回true,注意这是一个static方法,这意味着"这条线程"指的是当前线程

13. Runnable与Callable区别

  1. 相同点:都是接口,都可以编写多线程程序,都采用Thread.start()启动线程
  2. 不同点:
    1. Runnable没有返回值;Callable可以返回执行结果,是个泛型,和Future、FutureTask配合可以用来获取异步执行的结果

    2. Callable接口的call()方法允许抛出异常;Runnable的run()方法异常只能在内部消化,不能往上继续抛

    3. Callalble接口支持返回执行结果,需要调用FutureTask.get()得到,此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞。

14. 什么方法(指令)可以让线程堵塞
在这里插入图片描述

15. wait(),notify()和suspend(),resume()和yield()之间的区别
  1. wait()方法和notify()方法的区别:
     这两个方法都是属于Object类中的,也是配套使用的,当调用这两个方法阻塞时要释放占用的锁,而锁是任何对象都具有的,调用任意对象的wait()方法导致线程阻塞,并且该对象上的锁被释放;
     而调用任意对象的notify()方法则导致从调用该对象的wait()方法而阻塞的线程中随机选择一个解除阻塞
  2. suspend()方法和resume()方法区别:
    这两个方法配套使用,suspend方法使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume方法被调用,才能使得线程重新进入可执行状态。
  3. yield方法:使当前线程放弃当前已经分得的CPU时间,但不使当前线程阻塞,即线程仍处于可执行状态,随时可能再次分的CPU时间。调用yield方法的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程

16. 产生死锁的条件
1. 互斥条件:一个资源每次只能被一个进程使用
2. 请求与保持条件:一个进程因请求资源而堵塞时,对已获得的资源保持不放
3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

17. wait()方法和notify/notifyAll()方法在放弃对象监视器时有什么区别
  wait()方法和notify()/notifyAll()在放弃对象监视器的区别在于:wait()方法立即释放对象监视器,notify()/notifyAll方法则会等待线程剩余代码执行完毕才会放弃对象监视器

18. wait()与sleep()的区别
  1. sleep()来自Thread类,wait来自Object类,调用sleep()方法的过程中,线程不会释放对象锁,而调用wait方法线程会释放对象锁
  2. sleep()睡眠后不出让系统资源,wait让其他线程可以占用cpu
  3. sleep()需要指定一个睡眠时间,时间一到会自动唤醒,而wait需要配合notify()或者notifyAll()使用

19. synchronized和ReentrantLock的区别
  synchronized是和if else for whole一样的关键字,ReentranLock是类,这是二者的本质区别,既然ReentranLock是类,那么它就提供了比synchronized更多更灵活的特性,可以被继承,可以有方法,可以有各种各样的类变量,ReentrantLock比synchronized的扩展性提现在几点上:
  1. ReentrantLock可以对获取锁的等待时间设置,这样就避免了死锁
  2. ReentrantLock可以获取各种锁的信息
  3. ReentrantLock可以灵活实现多路通知
  4. ReentrantLock底层调用的是unsafe的park方法加锁,synchronized操作的应该是对象头中mark word

20. FutureTask是什么
  FutrueTask表示一个异步运算的任务,FutrueTask里面可以传入一个Callable的具体实现类,可以对这个异步运算的结果进行等待获取,判断是否已经完成 取消任务等操作,由于FutrueTask也是Runnable接口的实现类,所以FutureTake也可以放入线程池中

21. 对象的监视器是什么东西
可以把监视器理解成一个建筑,有一个特别的房间(对象),房间里面有一些数据,而且在同一时间只能被一个线程占据,一个线程从进入这个房间到离开它之前,他可以独占这个房间的全部数据,
  1. 进入这个建筑叫做"进入监视器"
  2. 进入那个特别的房间叫做"获得监视器"
  3. 占据这个房间叫做"持有监视器"
  4. 离开这个房间叫做"释放监视器"
  5. 离开这个建筑叫做"退出监视器"

22. 一个线程如果出现了运行时异常怎么办?
  当一个线程运行时出错,会出现两个情况
    1. 如果该异常被捕获或者抛出,则程序继续进行
    2. 如果异常没有被捕获改线程将会停止执行
    3. Thread.UncaughtExceptionHandler是用于处理未捕获异常造成线程突然中断情况的一个内嵌接口。当一个未捕获异常将造成线程中断的时候JVM会使用Thread.getUncaughtExceptionHandler()来查询线程的UncaughtExceptionHandler,并将线程和异常作为参数传递给handler的uncaughtException()方法进行处理
    4. 如果这个线程持有某个对象的监视器,那么这个对象监视器会被立即释放

23. 如何在两个线程间共享数据
  通过在线程间共享数据就可以了,然后通过wait/notify/notifyall await/signal/signlall进行唤起和等待,比如说阻塞队列BlockingQueue就是为了线程之间共享数据而设计的

24. 什么是线程局部变量ThreadLocal
  1. 线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享,java提供ThreadLocal类来支持局部变量,是一种线程安全的方式
  2. 但是任何线程局部变量一旦在工作完成后没有释放,java应用就存在内存泄漏的风险
  3. ThreadLocad就是一种以空间换时间的做法在每个Thread里面维护了一个ThreadLocal.ThreadLocalMap把数据进行隔离,数据不共享,自然就没有线程安全方面的问题

25. 生产者消费者模型的作用是什么
  1. 通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这个生产者消费者模型最重要的作用
  2. 解耦,这是生产者消费者模型附带的作用,解耦意味着生产者和消费者之间的联系少,联系少就可以独自发展而不需要受到相互的制约

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值