面试题答案整理

反射的用途和实现?
java中的反射机制是指对于任意一个类都能知道这个类的所有属性和方法,对于任意一个对象都能知道他的方法,反射的主要用途是各个框架的实现
实现:1.获取实例对象(三种实现)
1.类.class
2.对象.getclass
3.Class.forName(“完整路径”)

public static void main(String[] args) {
		//Foo的实例对象如何表示
		Foo foo1 = new Foo();//foo1就表示出来了.
		//Foo这个类 也是一个实例对象,Class类的实例对象,如何表示呢
		//任何一个类都是Class的实例对象,这个实例对象有三种表示方式
		
		//第一种表示方式--->实际在告诉我们任何一个类都有一个隐含的静态成员变量class
		Class c1 = Foo.class;
		
		//第二中表达方式  已经知道该类的对象通过getClass方法
		Class c2 = foo1.getClass();
		
		/*官网 c1 ,c2 表示了Foo类的类类型(class type)
		 * 万事万物皆对象,
		 * 类也是对象,是Class类的实例对象
		 * 这个对象我们称为该类的类类型
		 * 
		 */
		
		//不管c1  or c2都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象
		System.out.println(c1 == c2);
		
		//第三种表达方式
		Class c3 = null;
		try {
			c3 = Class.forName("com.imooc.reflect.Foo");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(c2==c3);

动态加载
new一个对象是静态加载,缺点是一旦启动就要把所有的类都加载,耗费时间和空间,使用动态加载就可以避免这些问题。
具体使用来说:就是创建实例.newInstance()
获得方法和成员变量信息(主要就是getMethod方法)

public class ClassUtil {
	/**
	 * 打印类的信息,包括类的成员函数、成员变量(只获取成员函数)
	 * @param obj 该对象所属类的信息
	 */
	public static void printClassMethodMessage(Object obj){
		//要获取类的信息  首先要获取类的类类型
		Class c = obj.getClass();//传递的是哪个子类的对象  c就是该子类的类类型
		//获取类的名称
		System.out.println("类的名称是:"+c.getName());
		/*
		 * Method类,方法对象
		 * 一个成员方法就是一个Method对象
		 * getMethods()方法获取的是所有的public的函数,包括父类继承而来的
		 * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
		 */
		Method[] ms = c.getMethods();//c.getDeclaredMethods()
		for(int i = 0; i < ms.length;i++){
			//得到方法的返回值类型的类类型
			Class returnType = ms[i].getReturnType();
			System.out.print(returnType.getName()+" ");
			//得到方法的名称
			System.out.print(ms[i].getName()+"(");
			//获取参数类型--->得到的是参数列表的类型的类类型
			Class[] paramTypes = ms[i].getParameterTypes();
			for (Class class1 : paramTypes) {
				System.out.print(class1.getName()+",");
			}
			System.out.println(")");
		}
	}
    /**
     * 获取成员变量的信息
     * @param obj
     */
	public static void printFieldMessage(Object obj) {
		Class c = obj.getClass();
		/*
		 * 成员变量也是对象
		 * java.lang.reflect.Field
		 * Field类封装了关于成员变量的操作
		 * getFields()方法获取的是所有的public的成员变量的信息
		 * getDeclaredFields获取的是该类自己声明的成员变量的信息
		 */
		//Field[] fs = c.getFields();
		Field[] fs = c.getDeclaredFields();
		for (Field field : fs) {
			//得到成员变量的类型的类类型
			Class fieldType = field.getType();
			String typeName = fieldType.getName();
			//得到成员变量的名称
			String fieldName = field.getName();
			System.out.println(typeName+" "+fieldName);
		}
	}
	/**
	 * 打印对象的构造函数的信息
	 * @param obj
	 */
	public static void printConMessage(Object obj){
		Class c = obj.getClass();
		/*
		 * 构造函数也是对象
		 * java.lang. Constructor中封装了构造函数的信息
		 * getConstructors获取所有的public的构造函数
		 * getDeclaredConstructors得到所有的构造函数
		 */
		//Constructor[] cs = c.getConstructors();
		Constructor[] cs = c.getDeclaredConstructors();
		for (Constructor constructor : cs) {
			System.out.print(constructor.getName()+"(");
			//获取构造函数的参数列表--->得到的是参数列表的类类型
			Class[] paramTypes = constructor.getParameterTypes();
			for (Class class1 : paramTypes) {
				System.out.print(class1.getName()+",");
			}
			System.out.println(")");
		}
	}
}
方法的反射:调用之前的获得的方法.invoke()

get和post的区别:
post 相对 get 请求是 “安全” 的
get 请求发送数据更小
get 能被缓存,post 不能被缓存

session和cookie的区别
1.cookie放在浏览器上,session放在服务器上
2.session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
3. cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session
JDBC流程:
1.注册驱动
2.建立链接
3.创建sql语句
4运行语句
5.处理结果
6.释放资源
MVC设计思想:
M:model主要处理数据
v:主要功能是展示页面
c:作为m和v的桥梁,协调V和M

HashMap 和 ConcurrentHashMap 的区别
ConcurrentHashMap对整个桶数组进行了分割分段(Segment),然后在每一个分段上都用lock锁进行保护,相对于HashTable的syn关键字锁的粒度更精细了一些,并发性能更好,而HashMap没有锁机制,不是线程安全的。
HashMap的键值对允许有null,但是ConCurrentHashMap都不允许

锁的种类?correntHashMap底层实现原理?

sleep()、join()、wait()、yield的区别
sleep使当前线程回到阻塞状态,不释放对象锁
join方法的意思在线程执行完前不执行该线程
wait方法导致该线程等待,但会释放对象锁,给其他线程机会
yield方法只是暂停当前线程重新回到可运行状态,

CountDownLatch
标签:并发编程
什么是CountDownLatch?
他能够让一个线程等待其他线程完成各自的工作后再执行
应用场景:主程序启动
原理:通过一个计数器实现,计数器初始化值为线程数量,每当一个线程完成工作后减1,当计数器为0时,闭锁的线程恢复执行任务
重要方法:await():调用await方法的线程会被挂起,等待知道count值为0继续执行
countdown:将count值减一

CyclicBarrier
标签:并发编程
什么是CyclicBarrier?
通过它可以实现让一组线程等待至某个状态之后再全部同时执行
原理:在CyclicBarrier的内部定义了一个Lock对象,每当一个线程调用await方法时,将拦截的线程数减1,然后判断剩余拦截数是否为初始值,如果不是进入Lock对象的条件队列等待,如果是,执行barrierAction对象的Runnable方法,然后将锁的条件队列中的所有线程放入锁等待队列中,这些线程会依次的获取锁、释放锁
CountDownLatch和CyclicBarrier的比较:
1.前者时线程组之间的等待,后者是一个线程组内的等待
2.前者是减计数方式,后者是加计数方式
3.前者计数为0无法重置,而后者计数达到初始值,则可以重置
4.前者不可以复用,后者可以复用

Semaphore用法
1.什么是Semaphore?
Semaphore可以控制同时访问的线程个数,通过acquire()方法获得许可,如果没有就等待,而release()释放一个许可。
2.重要方法:acquire()、release()方法
Exchager原理
1.什么是Exchager?
线程之间交互数据,且在并发时候使用,两两交换,交换中不会因为线程多而混乱,发送出去没接收到会一直等,由交互器完成交互过程。
实现原理:
Exchanger的基本原理是维持一个槽(Slot),这个Slot中存储一个Node的引用,这个Node中保存了一个用来交换的Item和一个用来获取对象的洞Hole。如果一个来“占有”的线程看见Slot为null,则调用CAS方法(CAS方法在前面的文章中已经详细介绍了https://zhuanlan.zhihu.com/p/27338395)使一个Node对象占据这个Slot,并等待另一个线程前来交换。如果第二个来“填充”的线程看见Slot不为null,则调用CAS方法将其设置为null,同时使用CAS与Hole交换Item,然后唤醒等待的线程。注意所有的CAS操作都有可能失败,因此CAS必须是循环调用的。
说说ThreadLocal原理:
1.什么是ThreadLocal?
线程本地变量,ThreadLocal为每个变量在线程中创建了一个副本
2.重要方法:
get():获取ThreadLocal在当前线程中保存的变量副本
set():设置变量副本
remove():移除线程副本
initiaValue():protected方法写的,用于重写,延迟加载
get方法的实质:使用ThreadLocals用来存放副本,键值为当前ThreadLocal变量
初始化时,threadLocals为空,当通过ThreadLocal调用get方法时对threadLocals变量进行初始化,并以当前ThreadLocal变量为键值
应用场景:数据库连接,session管理
讲讲线程池的实现原理
预先启动一些线程线程无限循环从任务队列中获取一个任务进行执行,直到线程池关闭,如果某个异常线程因为执行某个任务而发生终止,那么重写创建一个新的线程,就这样反复循环
几种方式:newCachedThreadPoll(可缓存)
newFixedThreadPool(定长线程池, 指定并发数 newScheduledThreadPool(定时周期任务执行)
newSingleThreadExecutor(唯一线程执行任务)
线程生命周期:https://www.cnblogs.com/sunddenly/p/4106562.html

猜你喜欢

转载自blog.csdn.net/wang_ze_ma/article/details/83218108