常见面试问题总结
【Java】
1. 容器
1)队列(queue): 若Blocking:阻塞put/take offer/peek poll 异常element/remove
a. PriorityQueue:comparator 堆排序
b. Deque:双向队列 linkedList addFirst()
c. DelayQueue:类似timeTask,延迟期满才能提取元素
d. ConcurrentLinkedQueue:线程安全
2)数组(Array):注意左右边界校验,如arr!=null&&arr.length>1;
3)List:有序可重复,可接受null,索引方便,.subList()视图。
a. LinkedList, ArrayList
b. CopyOnWriteArrayList:读写分离,写时复制加锁。开辟新空间,内存消耗多
4)Set:去重,必须实现equals方法。
a.hashSet,LinkedHashSet:快速查找,后者则是为了保证次序
b.SortedSet:如treeSet,底层实现的红黑树,保证有序
c. Collections.newSetFromMap:实现线程安全
5)Map:hashCode 数组 + equals linkedList put get
a. HashMap,LinkedHashMap:后者是为了保证次序
b.sortedMap:如treeMap,key保持排序状态
c. ConcurrentHashMap:锁分段技术,读写分析,写的时候,Segment加锁保护其名下的HashEntry,读的时候不加锁。
6)遍历:Iterator:指向第一个元素前一个,故要next。Foreach,实现Iterator即可用,单不可增删,会引起modCount变化,抛异常。
Comparablet内比较器 comparator 外比较器 策略模式
2. 并发
1)线程实现方法:Thread runnable接口 callable接口
2)线程池:减少损耗(一开始就创建好),好管理
类别:newSiggleThreadPool(),newFixedThreadPool(workQueue长度不可控),newCachedThreadPool(线程数不可控),newScheduledThreadPool(),
内部:ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue(直接/有界/无界),ThreadFactory(worker线程),handler(DiscardPolicy/CallerRunPolicy))
方法:execute/submit Future.get FutureTask shutdown/shutdownNow
3)常见类:ThreadLocal,内部ThradLocalMap,CountDownLatch, CyclicBarrier, Semaphore
4)Synchronized和Lock的区别
Lock:AQS AbstractQueuedSynchronized jdk类,可冲入,不可中断,非公平
Synchronized: object final 1. jvm关键字 可冲入,可判断锁状态,可公平,大量同步,finally要释放锁。在不断优化,锁消除,锁粗化,monitorenter,monitorexist映射在内核上,影响开销
5)性能调优:
Atomic原子类,免锁容器,ConcurrentHashMap在java8使用CAS无锁算法,ReentrantReadWriteLock读写锁, CAS,冲突检测,数据更新
3. IO
1. 字节流:OutputStream/InputStream,直接IO, 字符流:Writer/Reader,间接IO,需flush 字符字节转换,需要指定编码格式
2. 基本概念:while((read=inputStream.read(byteArr))>0) 硬盘-(阻塞)-> 内核 -(同步)-> 用户
3. FileLock Charset
4. IO和NIO的区别:观察者模式--> 事件机制 --> reactor设计模式 --> nio --> netty对nio进行了简单封装 jetty或tomcat
面向缓冲:ByteBuffer等,稍后处理,可移动,灵活 mark position limit capacity
非阻塞:FileChannel(阻塞)无法和Selcetor使用;ServerSocketChannel中设置,可配合Selcetor。Reactor模式
选择器 Selector selector = Selector.open(), register(selector, SelectionKey.OP_ACCPECT)
5. 实现案例:Netty EventLoopGroup ServerBootstrap group channel childHandler
4. 内存管理&JVM
1)GC内存模型:堆(新生代/老年代) 调整-Xms 方法区:永久代 j8用元空间代替; 栈:JVM栈(引用类型) Native栈
2)JVM内存模型:volatile 不能保证原子性,可以保证可见性,有序性 主内存,工作内存
3)清理:引用计数法,GCRoot:标记-清除 标记-复制 标记-整理
4)性能:JDK工具jconsole Jps Jstack Jmap; 内存泄露:jmeter+jps+MAT CPU冲高:ps -ef | grep jstack pid top-Hp pid
5. 反射
1)反射:getClass .class Class.forName,getFields(); 提高性能,反射+缓存
2)双亲委派模型:BootStrap lib Extension lib\ext Application \lib 自定义
3)类加载器:classLoader findClass defineClass loadClass 代理增强
Apache tomcat OSGI javaAgent探针,main之前拦截 Java字节码 热部署等
6. Java8
1)lamada闭包:
匿名函数捕获一个外部变量(自由变量),那么它就是一个closure。
闭包是自带运行环境的函数final,当一个函数在定义它的作用域意外的地方被调用时,他访问的依然是定义它时的作用域。这种现象称之为闭包
2)Stream API:
Java8中的Stream是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作(bulk data operation)
借助于lamada表达式 java.util.stream,函数式语言+多核时代
.stream().parallelStream().map().readuce(),对stream的使用就是实现一个filter-map-reduce过程,产生一个最终结果
Stream.of("one","two","three","for"),filter(e->e.length()>3).peek(e->System.out.println("Filtered value:"+e)).map(String::toUpperCase).peek(e->System.out.pringtln("Mapped value:"+e)).collect(Collectors.toList());
【设计模式】
1. 代理模式
真实类在代理类里注册,代理类根据注册new一个真实类Object并运转
2. 观察者模式
当对象间存在一对多关系时,使用观察者模式。比如,当一个对象呗修改,则会自动通知它的依赖对象。行为型模式
client->Subjec(被观察者state容器注册,notifyUpdate)->Observer abstract ->o1,o2,o3(update方法)
3. 适配器模式
4. 装饰器模式
【框架】
1. Spring
IOC:主业务,自动注入而非自己维护 DI和DL(JNDI)
动态工厂Bean/静态工厂bean Bean的作用域 单例,原型 Bean后处理器(采用动态代理,对bean增强)。
2. Spring的IOC和DI
1)bean的装配:动态工厂:factory-bean="someFactory" factory-method="getSomeService" 静态工厂:class="" factory-method="getSomeService"
2)bean的作用域:singleton prototype
3)bean后处理器:对bean创建的前后对bean进行增强
4)bean的生命周期 构造方法-> set值 -> BeanNameAware -> beanFactoryAware -> 执行后护理器前 -> InitializingBean-afterPropertiesSet -> initPost --> 执行后处理器后 -> 执行方法 --> DisposableBean-destroy -> destroy
5)xml方式
property/constructor-arg name value/ref
array/list/set/map/props
autowire
parent
6)注解方式
<context:compont-sacn base-package="com.huawei.ztj.di01">
@Compont
@Scope
@Value @Resource
MyJavaConfig @Configuration @Bean 构造器
AOP:系统业务,织入而非混入
1. Proxy代理 java.lang.reflect.Proxy 使用:ISomeService target = new SomeServiceImpl(); ISomeService proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHander(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throwable {
..; Object result = method.invoke(target, args); ..;
}
});
2. 代理设计模式 : 代理类和目标类实现同一接口,代理类是对目标类的增强(仍包含目标类的逻辑)。好处:控制目标对象的访问,增强目标对象的功能。区别于:适配器模式(改变),装饰器模式(增强,方式不一样)。
3. AOP
1. 通知Advice 增强的系统功能 MethodBeforeAdvice AfterReturningAdvice MethodInterceptor(aopalliance中的包) ThrowsAdvice CGLIB 无实现InvocationHandler
2. 顾问Advisor 切入点
<bean id="afterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> NameMatchMethodPointcutAdvisor
<property name="advice" ref="beforeAdvice"/>
<property name="patterns" value=".*Sec.*/.*T.*"> mappedName
</bean>
3.配置
<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean class="org.springframework.aop.framework.autoproxy.advisorAutoProxyCreator"/>
<property name="target" ref="someService"/>
<property name="interfaces" value="com.huawei.ztj.di01.ISomeService"/>
<property name="interceptorNames" value="beforeAdvice"/>
</bean>
4. AspectJ
注解:"execution(" * *..ISomeService.doSome(..)")" 通知+顾问
XML:<aop:config>
<aop:pointcut expression="execution(* *..ISomeService.doSome(..))" id="doSomePointcut"/>
<aop:aspect ref="myAspect">
<aop:before method="myBefore" pointcut-ref="doSomePointcut"/>
</aop:aspect>
</aop:aspect>
</aop:config>
1. spring-aop包源码解读
外层: Advice各个接口
support包: Advisor 切入点,如NameMatchMethodPointcutAdvisor、RegexpMethodPointcutAdvisor
framework包: 拦截器
1)autoproxy:DefaultAdvisorAutoProxyCreator、BeanNameAutoProxyCreator
2)ProxyFactoryBean
3)JdkDynamicAopProxy、CglibAopProxyFactory 重点
下一步计划:core beans context aspectJ aop:config aop:pointcut aop:aspect aop:before pointcut-ref <aop:pointcut expression="execution(* *..ISomeService.doSome(..))" id="doSomePointcut"/>
2. SpringMVC
DispatcherServlet--> 映射处理器 处理适配器ModelAndView 视图解析(view) 视图渲染(Model)
1、DispatcherServlet前端控制器接收发过来的请求,交给HandlerMapping处理器映射器
2、HandlerMapping处理器映射器,根据请求路径找到相应的HandlerAdapter处理器适配器(处理器适配器就是那些拦截器或Controller)
3、HandlerAdapter处理器适配器,处理一些功能请求,返回一个ModelAndView对象(包括模型数据、逻辑视图名)
4、ViewResolver视图解析器,先根据ModelAndView中设置的View解析具体视图
5、然后再将Model模型中的数据渲染到View上
3. MyBatis
4. OSGI
5. SOA架构
1. RMI:https://www.cnblogs.com/ygj0930/p/6542811.html 学习参考:http://www.blogjava.net/zhenyu33154/articles/320245.html
RMI:stub skeleton 接口Remote 注册:java.rmi.Naming.rebind("rmi://10.74.226.146:11099/demoService", demoService); rmic生成桩和框架 JVM rmiregistry注册程序运行
调用:IHello hello = (IHello) Naming.lookup("rmi://localhost:1099/hello");
RPC:系统网络服务,客户端和服务端句柄。
JNDI:Java Naming and Directory Interface 是一个应用程序设计的API
采用java的序列化 头疼的防火墙渗透
2. Spring HttpInvoker 它基于HTTP之上提供RPC,同时又使用了Java的对象序列化机制。
学习参考:https://www.cnblogs.com/lpc-xx/p/8556827.html
3. Hessian:Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能 二进制
web.xml注册 <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
调用:HessianProxyFactory factory = new HessianProxyFactory(); HessianService hs = (HessianService)factory.create(HessianService.class, url);
私有的序列化机制 解决防火墙问题
4. Burlap:https://www.cnblogs.com/javalouvre/p/3730597.html 集中远程服务的区别 https://www.cnblogs.com/maybo/p/5190012.html
私有的序列化机制 解决防火墙问题
5. Http服务和RFC服务的区别:https://blog.csdn.net/wangyunpeng0319/article/details/78651998 看下客户端请求是否有http打头
6. 使用和发布web服务: https://blog.csdn.net/gray_li/article/details/78460213
7. 使用Spring MVC创建Rest API:
1) 【Spring集成】-SpringMVC创建REST API https://blog.csdn.net/fxkcsdn/article/details/80932349 n
【MySQL】
1)参考:https://blog.csdn.net/zhugewendu/article/details/73550414
2)
SQL和索引优化
优化数据库对象
优化InnoDB
磁盘优化
【TCP/IP】
【消息通知】
ActiveMQ:java, java系统配合默契 基于STOMP协议 Simple Text Orientated Message Protocol
RabbitMQ:Erlang 性能更强 基于AMQP(Advanced Message Queue Protocol) 而“语言中立”则意味着只要遵循 AMQP 的协议,任何一种语言都可以开发消息组件乃至中间件本身
基于Erlang,支持多种协议的消息Broker,通过插件支持STOMP协议 admin/Changeme_123 jms
HornetQ:基于JBoss
1. 整体架构
private int getCalledTimes(long minTime) {
int i = 0;
List<Long> removeList = new ArrayList<Long>();
for (int k = callTimes.size() - 1; k > 0; k--)
{
Long time = callTimes.get(k);
if (time > minTime)
{
i++;
}
else
{
removeList.add(time);
}
}
callTimes.removeAll(removeList);
return i;
}
【途径】
1. 书:Java编程思想,Java并发编程实战,effective java, Spring实战,
2. 网络: MOOC课程,Java技术栈, ImportNew