2016知识点总结

来源:互联网 发布:java完全自学手册 pdf 编辑:程序博客网 时间:2024/05/29 18:46
1:mysql总结
 11:EXPLAIN select_type:提供了各种表示table列引用的使用方式的类型,最常见的值包括SIMPLE、PRIMARY、DERIVED和UNION。其他可能的:值还有UNION RESULT、DEPENDENT SUBQUERY、
DEPENDENT UNION、UNCACHEABLE UNION以及UNCACHEABLE QUERY。体现sql的复杂程度。
type:显示了连接使用了哪种类别,有无使用索引,从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL。
2: 复合索引:取相关的字段共同做索引。
3:覆盖索引:第一次通过索引取相关记录的id,第二次在通过id查询目标记录。(目的查询尽可能走索引)
4:范式对业务简单,规范小表合适,不适合大表。


sql定义事务:BEGIN tran + sql + COMMIT  tran 
隔离级别:
 未提交读,在未提交读级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读(Dirty Read)。
 提交读:一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的(不重复读)。
 可重复读: (默认事务隔离级别)指的是当某个事务在读取某个范围内的记录时,另外一个事务中又在该范围插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。(行级别锁)
 可串行化:读取的每一行数据上都加上锁,效率低。


 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写操作。如果你是写锁,则其它进程则读也不允许
 行级,仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作。
 页级,表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。




2:线程总结  新建-就绪-堵塞-运行-死亡
 00:多线程源于cpu多核,
 11:线程同步 ①ThreadLocal ②synchronized() ③wait()与notify() ④volatile(指令排序) 
 22:线程同步 synchronized 与 ReentrantLock 区别  1:性能?jdk版本有关系  2:可中断锁  3:锁种类,公平非公平锁 4:灵活ConcurrentHashMap就是一个案例。
 33:ReentrantLock获取锁定与三种方式:
     a) lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
     b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
     c)tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
     d) lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断
 44:Thread 与 Runnable 与 Atomic 区别。Thread 是Runnable 的接口实现,容易实现逻辑与数据分离,摆脱继承局限性。
 45:注意线程逃逸(多线程环境,构造方法无法及时初始化)
 46:CyclicBarrier  CountDownLatch  多线程在某个零界点并发执行。
 47:sleep是thread方法,wait是object方法,sleep定时到,自动唤醒,wait需要notify通知。
 48:join 线程加入:join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。
 49:yield 把执行机会让给相同或者更高优先级的线程和sleep区别,sleep是停止,yield是暂停。
 50:setPriority 设置线程优先级


3: CopyOnWriteArrayList 1、适合场景读多写少 2、不能保证读取数据一定是正确的,因为get时是不加锁的 3、add、remove会加锁再来操作.
   CopyOnWriteArraySet  2、原理场景和CopyOnWriteArrayList一样,只不过是不能有重复的元素放入.






3:线程池
1:ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);  创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
2:ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
3:ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); scheduledThreadPool.schedule(runnable, 3, TimeUnit.SECONDS) 创建一个定长线程池,支持定时及周期性任务执行。
4: ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。




4:线程组
1:用户创建的所有线程都属于指定线程组,如果没有显示指定属于哪个线程组,那么该线程就属于默认线程组(即main线程组)。
2:只有在创建线程时才能指定其所在的线程组,线程运行中途不能改变它所属的线程组,也就是说线程一旦指定所在的线程组,就直到该线程结束。




5:String.hashcode  算法 a*31^4+b*31^3+c*31^2+d*31^1+e*31^0  幂运算




6:设计模式
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。




工厂方法模式:建立一个工厂类,对实现了同一接口的一些类进行实例的创建。
抽象工厂模式:通过继承接口,实现工厂模式的功能。
    单例模式:单例对象能保证在一个JVM中,降低gc压力。(cpu指令优化)
  建造者模式:创建批量创建多个实例,而工厂模式是创建一个。
    原型模式:类继承Prototype,调用clone克隆自身对象。(深复制,浅复制)
  适配器模式:目的是消除由于接口不匹配所造成的类的兼容性问题,通过继承类,接口去扩展别的类的功能。
    代理模式:1、修改原有的方法来适应。这样违反了“对扩展开放,对修改关闭”的原则。
              2、就是采用一个代理类调用原有的方法,且对产生的结果进行控制。这种方法就是代理模式。使用代理模式,可以将功能划分的更加清晰,有助于后期维护!
  观察者模式:观察者模式很好理解,类似于邮件订阅和RSS订阅,主类变化,通知依赖对象的改变。






7:nio
 IO的四种模式,分为阻塞IO,多路IO,非阻塞IO和异步IO。
 1、阻塞IO(recvfrom系统调用)是在两个过程应用都处于阻塞状态。
 2、非阻塞IO(recvfrom系统调用)是应用发出IO操作后可以立刻返回,通过轮询盘判断数据是否准备好,在copy数据阶段阻塞应用。
 3、多路复用IO(select 、recvfrom系统调用)是阻塞调用select,查找可用的套接字,如果有套接字可用,那么就阻塞调用(recvfrom)完成数据的copy过程。
 4、异步IO(aio-read)是应用发出aio-read后马上返回,数据准备好后,由操作系统把数据copy到应用,并通知应用数据copy完成。
 NIO有缓存缓存,不需要一对一的线程阻塞等待,NIO服务器最核心的一点就是反应器模式,一个线程接受请求,其他处理,线程利用率高。
 Channel(通道):NIO把它支持的I/O对象抽象为Channel。它模拟了通信连接,类似于原I/O中的流(Stream),用户可以通过它读取和写入数据。目前已知的实例类有SocketChannel、  




ServerSocketChannel、DatagramChannel、FileChannel等。
 Buffer(缓冲区):Buffer是一块连续的内存区域,一般作为Channel收发数据的载体出现。所有数据都通过Buffer对象来处理。
 Selector(选择器):Selector类提供了监控一个和多个通道当前状态的机制。只要Channel向Selector注册了某种特定的事件,Selector就会监听这些事件是否会发生,一旦发生某个事件,  
 便会通知对应的Channel。使用选择器,借助单一线程,就可对数量庞大的活动I/O通道实施监控和维护。




Java BIO : 同步并阻塞(一个请求,启动一个线程,适用连接数目比较小且固定的架构)
Java NIO : 同步非阻塞。(连接比较短(轻操作)的架构,比如聊天服务器)
Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理(jre7支持,连接比较长(重操作)的架构,比如相册)




Select
select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:
1 单个进程可监视的fd数量被限制
2 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大
3 对socket进行扫描时是线性扫描
Poll
poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发




现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。
它没有最大连接数的限制,原因是它是基于链表来存储的,但是同样有一个缺点:大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。
poll还有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd。
Epoll
epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次。
在前面说到的复制问题上,epoll使用mmap减少复制开销。
还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知








8:jvm
 1、程序计数器,虚拟机栈,本地方法区,JAVA堆,方法区  调优工具:Jconsole,jProfile,VisualVM。
 
 堆区:只存放类对象,线程共享;
 方法区:又叫静态存储区,存放class文件和静态数据,线程共享;
 栈区:存放方法局部变量,基本类型变量区、执行环境上下文、操作指令区,线程不共享;




 Java中有几种不同的引用方式,它们分别是:强引用、软引用、弱引用和虚引用。
 StackOverflowError:栈溢出(比如方法不断回调自身)
 OutOfMemoryError: Java heap space :堆内存不足。
 栈溢出的原因排查:
   一)、是否有递归调用(递归中用到了大量的建新的对象)
   二)、是否有大量循环或死循环(循环中用到了大量的新建的对象
   三)、全局变量是否过多
   四)、 数组、List、map数据是否过大
   五)使用jconsole工具进行查找大概出现栈溢出的位置
 栈大小:栈导致内存占用过多,而频繁页交换阻碍效率,有系统分配
 堆大小:程序员分配




OOM异常:
  StackOverFlowError,OutOfMemeoryError,
  常量池的OOM异常(String类的intern()方法向方法区中的常量池添加内容),
  方法区的OOM异常(方法区中存放的是Class的相关信息,如:类名、访问修饰符、常量池、字段描述、方法描述等)




9:类加载
  (1) 装载:查找和导入Class文件;
  (2) 链接:把类的二进制数据合并到JRE中;
     (a)校验:检查载入Class文件数据的正确性;
     (b)准备:给类的静态变量分配存储空间;
     (c)解析:将符号引用转成直接引用;
  (3) 初始化:对类的静态变量,静态代码块执行初始化操作
1)Bootstrap ClassLoader
负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
2)Extension ClassLoader
负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
3)App ClassLoader
负责记载classpath中指定的jar包及目录中class
4)Custom ClassLoader
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader
加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有




ClassLoader加载一次。
而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。




双亲委派:(不是一个类加载器加载,同一个类,也不相同,初始化对象也不一样,java类的隔离性)
(1).如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器去完成。
(2).每一层的类加载器都把类加载请求委派给父类加载器,直到所有的类加载请求都应该传递给顶层的启动类加载器。
(3).如果顶层的启动类加载器无法完成加载请求,子类加载器尝试去加载,如果连最初发起类加载请求的类加载器也无法完成加载请求时,将会抛出ClassNotFoundException,而不再调用其




子类加载器去进行类加载。
双亲委派 模式的类加载机制的优点是java类它的类加载器一起具备了一种带优先级的层次关系,越是基础的类,越是被上层的类加载器进行加载,保证了java程序的稳定运行。
4:自定义类加载器一般继承ClassLoader,自定义类加载器时不需要在自己写双亲委派的逻辑,而推荐重写findClass方法。




10:mavn 依赖(jar依赖)、聚合(工程a,b,c依赖项目o)、继承(所有工程继承项目o)、插件




11:分布式集群
Zookeeper:
设计目的:最终一致性,实时性,等待无关,原子性,顺序性
优点:可以实现集群中的分布式协调服务,所谓的分布式协调服务,就是在集群的节点中进行可靠的消息传递,来协调集群的工作,Zookeeper之所以能够实现分布式协调服务,靠的就是它能
够保证分布式数据一致性。
所谓的分布式数据一致性,指的就是可以在集群中保证数据传递的一致性,Zookeeper能够提供的分布式协调服务包括:数据发布订阅、负载均衡、命名服务、分布式协调/通知、集群管理、




分布式锁、分布式队列等功能
缺点:读写性能不佳,只容忍(N-1)/2的故障,ZK在网络堵塞,选主时间长,在此期间所有服务不能使用。
优化:zoo_sample.cfg参数调优。






Nosql: Hbase按列存储数据,列查询速度快。
MongoDB文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系数据库的某些功能。
mongodb是一个介于nosql数据库和mysql数据库之间的一个数据存储系统,它没有严格的数据格式,但同时支持复杂查询。
mongodb缺点:数据库级锁,如果锁定,查询干等,不过有锁放弃机制,建索引导致数据库阻塞,foreground长时间占用写锁(默认),background不会
MemcacheDB,Redis可以通过key快速查询到其value。Redis支持更多的数据格式,支持本地化,也可以关闭这个功能。







12:spring
1:反射,初始化对象。
2:设计模式: 简单工厂,工厂方法,单例模式,适配器(实现AOP),包装器(数据源切换),代理,观察者,策略,模板方法。


13:tomcat
   bio: tomcat默认用伪nio,即线程池模型处理缓存请求。
   nio:
   apr: 因为这种模式是基于JNI的,即JAVA调用本地库的方式来进行IO
   使用NIO方式处理并发性能好的前提是 每个请求耗时不能高,但是这样对现有的request response处理要有额外处理。 如果不能达到这个要求,用 NIO反而会是整体性能下降。
   现在一般的处理流程: 请求进来,查数据库,执行业务逻辑,渲染,然后返回。整体耗时很长。
   静态资源的服务器开启Nio模型,处理速度高。




12:dubbo
优点:
Remoting: 网络通信框架,实现了 sync-over-async 和 request-response 消息机制.
RPC: 一个远程过程调用的抽象,支持负载均衡、容灾和集群功能.
Registry: 服务目录框架用于服务的注册和服务事件发布和订阅.
Provider: 暴露服务方称之为“服务提供者”。
Consumer: 调用远程服务方称之为“服务消费者”。
连通性,健状性,伸缩性。


缺点:
 dubbo不支持事务:
  1:事务补偿机制,编写逆向代码,保证事务。2:基于消息的最终一致性,确认支付结果,支持重复调用。
     dubbo不支持大数据传输,dubbo是长连接,每个连接最大的是7MB,每个包大小是500kb,传递大数据,网络成瓶颈。
  2:dubbo基于netty,mina通讯,Hessian二进制序列化。
 
dubbo标签:
 DubboNamespaceHandler  
   application:消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样。
   registry: 注册中心(zookeeper(protocol="zookeeper"),redis(protocol="redis"))
   reference: 生成远程服务代理,可以和本地bean一样.
   service: 声明需要暴露的服务接口
   method: reference子标签用于方法级别控制。
   -- 可缺省
   module:模块配置,用于配置当前模块信息,可选。
   monitor:监控中心配置,用于配置连接监控中心相关信息,可选。
   argument:用于指定方法参数配置。
   provider:提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。
   consumer:消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。


dubbo其他配置:
   1:启动时检查:  dubbo:reference,dubbo:registry  check="false" 。(Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。)
   2:       订阅:  dubbo:registry  register="false". (为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。)
   3:回声测试:回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。
   4:延迟连接: dubbo:protocol  lazy="true" (延迟连接,用于减少长连接数,当有调用发起时,再创建长连接。)
   5:令牌验证:  dubbo:service, dubbo:provider  token="true"
   
   


12:springMvc
1:dispatcherservlet 拦截器






15: 《深入理解Java虚拟机》




16:java垃圾回收器
 垃圾回收器原则: 可到达算法(解决自我引用)
 垃圾回收器工作(线程暂停):Minor GC 新生代清理, Major GC 是清理老年代,Full GC 是清理整个堆空间—包括年轻代和老年代
 垃圾回收器种类: 
 串行回收器(应用线程全部冻结),并行/吞吐量回收器(线程暂停),CMS回收器(CMS以获取最小停顿时间为目的,用户程序不能有长时间的停顿,CMS 可以用于此场景),G1回收器(它
 的设计目标是能更好地支持大于4GB的堆。G1回收器将堆分为多个区域,大小从1MB到32MB不等,并使用多个后台线程来扫描它们。)




14:HashMap 线程不安全,可以一个null的key, HashTable是基于字典的结构方式 ,不容许有null的key,线程安全,ConcurrentHashMap 分段线程安全,LinkedHashMap(散列表+循环双向
链表,保存了记录的插入顺序)、TreeMap(红黑树结构,默认按key进行升序排序)有顺序。




18:HTTP 关系密切的协议 : IP、TCP 和 DNS
发出源主机-->传输层-->网络层-->链路层-->网络层-->传输层-->目的主机




在源主机上,应用层将一串应用数据流传送给传输层。
●传输层将应用层的数据流截成分组,并加上TCP报头形成TCP段,送交网络层。
●在网络层给TCP段加上包括源、目的主机IP地址的IP报头,生成一个IP数据包,并将IP数据包送交链路层。
●链路层在其MAC帧的数据部分装上IP数据包,再加上源、目的主机的MAC地址和帧头,并根据其目的MAC地址,将MAC帧发往目的主机或IP路由器。
●在目的主机,链路层将MAC帧的帧头去掉,并将IP数据包送交网络层。
●网络层检查IP报头,如果报头中校验和与计算结果不一致,则丢弃该IP数据包;若校验和与计算结果一致,则去掉IP报头,将TCP段送交传输层。
●传输层检查顺序号,判断是否是正确的TCP分组,然后检查TCP报头数据。若正确,则向源主机发确认信息;若不正确或丢包,则向源主机要求重发信息。
●在目的主机,传输层去掉TCP报头,将排好顺序的分组组成应用数据流送给应用程序。这样目的主机接收到的来自源主机的字节流,就像是直接接收来自源主机的字节流一样。




0 0
原创粉丝点击