JAVA技能点总结

JAVA技能点总结

  1. 基本

    static:被修饰的成员变量和成员方法独立于该类的任何对象,被类的所有实例共享;被修饰的方法可以直接通过类名调用;static静态代码块在初始化类时被调用,先调用父类、再调用子类。
    final:被修饰的属性和变量的值不能修改;类无法被继承;方法不能被重写。
    transient:被修饰的属性无法被序列化。
    foreach:对于数组,编译器采用的是添加goto指令,同for;对于实现了iterable的类,通过迭代器实现。
    volatile:所有线程每次读取的都是变量的最新值;防止指令重排序;对变量进行写操作时,处理器会添加lock指令,作用:1、将处理器缓存回写到内存;2、导致其它处理器的缓存无效。
    正则:^开始位置;$结束位置;

  2. 集合

  3. 设计模式

    项目中用到了哪些设计模式,如何使用
    常用设计模式的优缺点
    画出常用设计模式的UML图

  4. 多线程

    java.util.concurrent包:
    1)Queue类型
    LinkedBlockingQueue:基于链表,FIFO,容量默认为Integer.MAX_VALUE
    ArrayBlockingQueue:基于对象数组,FIFO,需指定初始容量,可指定并通过ReentrantLock来实现公平性
    PriorityBlockingQueue:按优先级的队列
    DelayQueue:延迟期满才能返回元素
    2)常用的线程池(使用Executors创建)
    newSingleThreadExecutor :单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
    newFixedThreadPool :定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    newCachedThreadPool:可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
    newScheduledThreadPool :定长线程池,支持定时及周期性任务执行。
    线程池使用方式:
    1)execute:参数为实现runnable或callable接口的类
    2)submit:参数为实现runnable或callable接口的类
    3)Future:submit的返回值
    4)Callable.call():可以有reutrn
    5)Future.get():获取运行状态 或 返回值
    线程池的实现原理:
    1)如果运行的线程数量小于corePoolSize,则创建新线程;
    2)如果运行的线程数量大于等于corePoolSize,则将任务加入阻塞队列;
    3)如果任务无法加入阻塞队列,则创建新线程;
    4)如果线程数量大于maxinumPoolSize,任务被拒绝,并调用RejectedExecutionHandler.rejectedExecution()
    线程池的拒绝策略:
    1)AbortPolicy(默认):直接抛出异常
    2)CallerRunsPolicy:只用调用者所在线程来运行任务
    3)DiscardOldestPolicy:丢弃最近的一个任务,并执行当前任务
    4)DiscardPolicy:不处理,丢弃掉
    线程池的关闭策略:
    1)shutdown:将线程池状态设置为SHUTDOWN,循环调用空闲线程的interrupt方法
    2)shutdownnow:将线程池状态设置为STOP,循环调用所有线程的interrupt方法
    线程池的配置:cpu密集型,线程数量为Num CPU+1;io密集型,线程数量为2*Num CPU;通过Runtime.getRuntime().availableProcessors()获取cpu数量。

    synchronized和ReentrantLock(默认非公平锁)的区别:
    1)任何对象都有一个moniter与之关联,代码块同步使用moniterenter和moniterexit指令实现;当一个moniter被持有后,将处于锁定状态;synchronized获取对象锁时是排它的,隐式支持重进入;
    2)其它线程通过synchronized尝试获取对象锁时,将被阻塞;而ReentrantLock可以选择中断和尝试获取锁的时间;
    3)ReentrantLock在调用lock后,必须在finally中进行unlock,即必须一一配对;
    4)ReentrantLock有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放;

    synchronized的具体表现形式:
    1)对于普通同步方法,锁是当前实例对象;
    2)对于静态同步方法,锁是当前类的class对象
    3)对于同步方法块,锁是括号里配置的对象;

    读写锁ReadWriteLock:允许多个线程在同一时间对某特定资源进行读取,但同一时间内只能有一个线程对其进行写入;实现类ReentrantReadWriteLock;使用读锁和写锁;

    死锁的原理及排查方法

  5. IO

    同步:发出请求后,若关联方没有响应,该请求就不返回
    异步:发出请求后就返回
    阻塞:调用者在结果返回前,会一直等待,无法处理其它事情,一直等待响应
    非阻塞:调用者无需一直等待响应
    BIO(同步阻塞):调用者每发起一个请求,响应方就创建一个线程处理;调用者在请求响应前会一直等待。
    NIO(同步非阻塞):调用者发起请求后,响应方将请求注册到多路复用器上,当有IO请求时才启线程处理;调用者发起请求后就返回,后续不间断地主动获取响应结果。
    AIO(异步非阻塞):响应方处理完毕后,主动通知调用者。
    java NIO的三大组成:
    1)Channels and Buffers(通道和缓冲区):数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中
    2)Asynchronous IO(异步IO):当线程从通道读取数据到缓冲区时,线程可以做其他事情
    3)Selectors(选择器):用于监听多个通道的事件(比如:连接打开,数据到达),单个线程可以监听多个数据通道
    java NIO与IO的区别:
    1)IO是面向流,NIO是面向缓冲区。
    2)IO的各种流是阻塞的,当一个线程调用read() 或 write()时,线程被阻塞,直到结束读取或写入;NIO是非阻塞的,仅从缓冲区中读取数据,如果没有可用数据,则线程可以处理其它channel。
    NIO:
    1)buffer:存放数据的缓冲区,分为CharBuffer和ByteBuffer,底层都是数组;ByteBuffer.allocate()或CharBuffer.allocate()获取buffer;capacity容量,limit可以读写的最后位置,position可以读写的开始位置;flip()重置position,将limit设置为原position的位置,为读做准备;clear()重置下标,不清除数据;compact()将未读数据挪至起始位置,可以读剩余未读数据;hasRemaining()是否还有可读数据;
    2)channel:数据流的通道;可以从io流中通过getChannel()获取;read(Buffer)将数据流读入缓冲区;
    3)selector:能够检测channel

  6. JDK源码

    String.hashCode():((1ascii)*31+2ascii)*31+3ascii…
    ReentrantLock的源代码,参见:(http://www.cnblogs.com/xrq730/p/4979021.html)
    1)非公平锁和公平锁:公平锁,按加锁顺序来获取锁,先请求先获取锁,线程上下文切换多,可能导致效率低下;非公平锁,抢占式获取锁,性能较高;默认非公平锁。
    2)lock()
    2.1)通过cas尝试修改state,如果成功,则获取锁;若失败,则再次尝试获取锁

        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

2.2)再次尝试获取锁
如果尝试失败且添加至阻塞队列失败,则中断自己。

    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

2.3)尝试获取锁
如果成功,则获取锁,且修改state,同一线程多次获取锁,则state一直增加,直到调用unlock()

        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

AtomicInteger:可实现原子操作;compareAndSet首先判断当前值是否等于current,如果相等,表明AtomicInteger没有被其它线程修改,则直接修改;如果不等,继续循环并尝试修改。

    public final int getAndIncrement() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
    private static final Unsafe unsafe = Unsafe.getUnsafe();

Object类中的方法以及每个方法的作用
7. 框架

项目中使用的框架
MyBatis中\$和#的区别:#将参数解析为字符串,\$ 将参数原样输出;#可以防止SQL注入;$一般传入数据库对象,如表名  
JDK动态代理和CG LIB的区别:
代理:当一个对象不直接引用另一个对象(目标对象),可以应用代理模式在这两者之间构建一个桥梁--代理对象。
1、JDK动态代理:只能针对实现了接口的类
2、CG LIB:针对实现类进行代理,生成目标类的子类,并重写其中的方法

8. 数据库

union和union all的区别、left join、几种索引及其区别
9. 数据结构和算法分析

数组、链表、平衡树、AVL树、红黑树
10. Java虚拟机

Java虚拟机的内存布局:
1)程序计数器:线程私有,字节码解释器通过改变其值来获取下一条指令。
2)虚拟机栈(局部变量表):线程私有,存放基本类型、对象引用。
3)本地方法栈:线程私有,为虚拟机所使用到的native方法服务。
4)堆(GC堆)):线程共享,存放对象实例和数组。
5)方法区:线程共享,存放类信息、常量、静态变量等。
5.1)运行时常量池:存放字面量和符号引用,具备动态性,常用的是String.intern()。

判断对象是否存活的方式
1、引用计数法:给对象添加引用计数器,每有一个引用就+1,引用失效则-1,若引用为0,则表明对象不可用;很难解决对象间循环引用的问题。
2、可达性分析法:以GC Roots对象为起点,向下搜索,走过的路径是“引用链”,当一个对象到GC Roots没有任何引用链,则表明对象不可用。

可作为GC Roots的对象:
1)虚拟机栈中引用的对象
2)方法区中静态属性引用的对象
3)方法区中常量引用的对象
4)本地方法栈中JNI(native方法)引用的对象

GC算法:
1)标记-清除:效率低;内存碎片多。
2)复制算法:将存活对象复制到另一半内存空间,简单高效,但压缩了内存空间。
3)标记-整理:标记后,将存活对象向一端移动,再清理。

几种垃圾收集器
1)串行
2)并行
类加载机制,也就是双亲委派模型
Java内存模型
happens-before规则:即先行发生规则;如果操作A先行发生于操作B,在发生操作B之前,操作A产生的影响都能被操作B观察到;详见:http://blog.csdn.net/ns_code/article/details/17348313
volatile关键字使用规则
11. Web

分布式Session的几种实现方式:
    1)Session Replication(session复制):将一台机器的session数据广播复制到其它机器。
    2)Session Sticky(粘性session):固定用户请求到某一台机器。
    3)缓存集中式管理:将session存入分布式缓存集群中的机器,用户访问时先从缓存中获取session。

Session和Cookie的区别和联系以及Session的实现原理
一致性Hash算法
web.xml:Filter、Servlet、Listener
get/post的区别
1)get:获取数据,将参数附在url后面(中文使用base64编码),可传输数据量较少
2)post:提交/修改数据,将参数附在http请求体里,可传输数据量多
请求转发(forward)/重定向(redirect)的区别:forward是服务器获取目标地址的数据,并返回给客户端,客户端不知道数据来源发生了变化;redirect是服务器让客户端重新发送请求去获取数据。
HTTPS的实现原理
SOA和RPC

12.大型网站架构

1)前端:浏览器优化(合并http请求,页面压缩,页面缓存),CDN,动静分离、静态资源独立部署(将http请求分离),反向代理(页面缓存),DNS(负载均衡)
2)应用层:集群(负载均衡),session管理(session复制、session粘性、集中式缓存),动态页面静态化,业务拆分(解耦)
3)服务层:分布式消息,分布式服务(微服务),分布式缓存和配置
4)存储层:分布式数据库,数据同步,主从(读写分离)

13.java调优
http://blog.csdn.net/zhengchao1991/article/details/53188629

总结自:http://geek.csdn.net/news/detail/202427?ref=myread

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值