Java面试考点(二)


一、线程

1.1如何保证线程安全?

(1)互斥同步是最常见的一种并发正确性保障手段。同步是指在多线程并发访问共享数据时,保证共享数据在同一时刻只被一个线程使用.(无论共享数据是否真的会出现竞争,它都要进行加锁)。
(2)非阻塞同步是先进行操作,如果没有其他线程争用共享数据,那操作就成功了;如果共享数据有争用,产生了冲突,那就再采用其他的补偿措施。(最常见的补偿错误就是不断地重试,直到成功为止。
(3) 要保证线程安全,并不是一定就要进行同步,两者没有因果关系。同步只是保证共享数据争用时的正确性的手段,如果一个方法本来就不涉及共享数据,那它自然就无需任何同步操作去保证正确性,因此会有一些代码天生就是线程安全的。

1.2什么是线程池?

线程池就是创建若干个可执行的线程放入一个池(容器)中,有任务需要处理时,会提交到线程池中的任务队列,处理完之后线程并不会被销毁,而是仍然在线程池中等待下一个任务。(需要调用操作系统内核的 API,操作系统要为线程分配一系列的资源,成本很高)

1.3介绍一下线程同步和线程调度的相关方法。

wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;
notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;
notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;
通过Lock接口提供了显式的锁机制(explicit lock),增强了灵活性以及对线程的协调。Lock接口中定义了加锁(lock())和解锁(unlock())的方法,同时还提供了newCondition()方法来产生用于线程之间通信的Condition对象;此外,Java 5还提供了信号量机制(semaphore),信号量可以用来限制对某个共享资源进行访问的线程的数量。在对资源进行访问之前,线程必须得到信号量的许可(调用Semaphore对象的acquire()方法);在完成对资源的访问后,线程必须向信号量归还许可(调用Semaphore对象的release()方法)

1.4当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的B方法?

不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法上的synchronized修饰符要求执行方法时要获得对象的锁,如果已经进入A方法说明对象锁已经被取走,那么试图进入B方法的线程就只能在等锁池(注意不是等待池哦)中等待对象的锁。

1.5说明一下多线程和同步有几种实现方法?

1,继承Thread类,重写run方法;
2,实现Runnable接口,重写run方法,但是比继承Thread类好用,实现接口还可以继承类,避免了单继承带来的局限性;
3,使用Executor框架创建线程池。Executor框架是juc里提供的线程池的实现。

1.6说明一下线程中的同步和异步有何异同?并且请举例说明在什么情况下会使用到同步和异步?

同步方法调用后必须等待方法返回才能执行后续行为;异步方法调用后可以立刻执行后续行为。
区别:一个需要等待,一个不需要等待,在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式。同步是用于确保资源一次只能被一个线程使用的过程,同步对于单线程程序没有任何好处。使用同步比非同步的性能差三到四倍。
线程都是独立的,而且异步执行,也就是说每个线程都包含了运行时所需要的数据或方法,而不需要外部的资源或方法,也不必关心其它线程的状态或行为。但是经常有一些同时运行的线程需要共享数据,此时就需考虑其他线程的状态和行为,否则就不能保证程序的运行结果的正确性。
需要做的是允许一个线程彻底完成其任务后,再允许下一个线程执行。必须保证一个共享的资源一次只能被一个线程使用。实现此目的的过程称为同步。

1.7说明一下sleep() 和 wait() 有什么区别?

sleep是Thread类的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时候会自动恢复。
调用sleep不会释放对象锁。
wait是Object类中的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify或notifyAll方法后本线程才会进入对象锁定池准备获得对象锁进入运行状态。
wait会释放锁。

1.8请你说明一下在监视器(Monitor)内部,是如何做到线程同步的?在程序又应该做哪种级别的同步呢?

在 java 虚拟机中, 每个对象( Object 和 class )通过某种逻辑关联监视器,每个监视器和一个对象引用相关联, 为了实现监视器的互斥功能, 每个对象都关联着一把锁.
一旦方法或者代码块被 synchronized 修饰, 那么这个部分就放入了监视器的监视区域, 确保一次只能有一个线程执行该部分的代码, 线程在获取锁之前不允许执行该部分的代码。

1.9同步方法默认用this或者当前类class对象作为锁。

同步代码可以选择以什么来加锁,比同步方法更细颗粒化,同步代码可以同步有同步问题的部分代码而不是整个方法。
同步方法用关键字synchronized修饰方法,同步代码主要修饰需要进行同步的代码块,用synchronized(object){代码内容}进行修饰。

1.10解释一下Java多线程回调是什么意思?

所谓回调,就是客户程序C调用服务程序S中的某个方法A,然后S又在某个时候反过来调用C中的某个方法B,对于C来说,这个B便叫做回调方法。

1.11说明一下线程池有什么优势?

第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能执行。
第三:提高线程的可管理性,线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。

2.2实现多线程同步的方法?

同步的实现方面有两种,分别是synchronized,wait与notify

二.反射

2.1说明一下JAVA中反射的实现过程和作用分别是什么?

JAVA语言编译之后会生成一个.class文件,反射就是通过字节码文件找到某一个类、类中的方法以及属性等。反射的实现主要借助以下四个类:Class:类的对象,Constructor:类的构造方法,Field:类中的属性对象,Method:类中的方法对象。
作用:反射机制指的是程序在运行时能够获取自身的信息。在JAVA中,只要给定类的名字,那么就可以通过反射机制来获取类的所有信息。

2.1创建对象的两种方法

Class 对象的 newInstance()使用 Class 对象的 newInstance()方法来创建该 Class 对象对应类的实例,但是这种方法要求该 Class 对象对应的类有默认的空构造器。
调用 Constructor 对象的 newInstance()先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance()方法来创建 Class 对象对应类的实例,通过这种方法可以选定构造方法创建实例。

三.垃圾回收器

3.1简单描述一下垃圾回收器的基本原理是什么

1、对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。
引用计数算法:判断对象的引用数量引用计数算法是通过判断对象的引用数量来决定对象是否可以被回收。任何引用计数为0的对象实例可以被当作垃圾收集。
可达性分析算法:判断对象的引用链是否可达可达性分析算法是通过判断对象的引用链是否可达来决定对象是否可以被回收。。当一个对象到GCRoots没有任何引用链相连(用图论的话来说就是从GCRoots到这个对象不可达)时,则证明此对象是不可用的。
2、可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行

3.2说明一下垃圾回收的优点以及原理。

Java 语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收****************************机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

3.3java中内存泄漏是什么意思?什么场景下会出现内存泄漏的情况?

在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值