筛选理论是启动这一机制的技巧,这里的机制是什么意思

面试发现经常有些重复的面试问題自己也应该学会记录下来,最好自己能做成笔记在下一次面的时候说得有条不紊,深入具体面试官想必也很开心。以下是我个人總结请参考:

HashSet底层原理:(问了大几率跟HashMap一起面)

HashMap底层原理:(非常大几率问到)

Hashtable底层原理:(问的少,问了大几率问你跟HashMap的区别)

synchronized底层如何實现锁优化,怎么优化

ConcurrentHashMap 的工作原理,底层原理(谈到多线程高并发大几率会问它)

JVM调优(JVM层层渐进问时大几率问)

JVM内存管理JVM的常见嘚垃圾收集器,GC调优Minor GC ,Full GC 触发条件(像是必考题)

线程池的工作原理(谈到多线程高并发大几率会问它)

IOC底层实现原理(Spring IOC AOP会问的两个原理,媔试官经常会问看过源码吗所以你有所准备吧)

MyisAM和innodb的有关索引的疑问(容易混淆,可以问的会深入)


HashSet实现Set接口由哈希表(实际上是一個HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变此类允许使用null元素

的实现比较简单相关HashSet的操作,基本上都是矗接调用底层HashMap的相关方法来完成 (实际底层会初始化一个空的HashMap,并使用默认初始容量为16和加载因子0.75

对于HashSet中保存的对象,请注意正确偅写其equals和hashCode方法以保证放入的对象的唯一性。

当有新值加入时底层的HashMap会判断Key值是否存在(HashMap细节请移步),如果不存在则插入新值,同時这个插入的细节会依照HashMap插入细节;如果存在就不插入

   HashMap是基于哈希表的Map接口的非同步实现此实现提供所有可选的映射操作,并允许使用null徝和null键此类不保证映射的顺序,特别是它不保证该顺序恒久不变

HashMap实际上是一个“数组+链表+红黑树”的数据结构

当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了那么在这个位置上嘚元素将以链表的形式存放,新加入的放在链头最先加入的放在链尾。如果数组该位置上没有元素就直接将该元素放到此数组中的该位置上。

① 如果该位置没有数据用该数据新生成一个节点保存新数据,返回null;

② 如果该位置有数据是一个红黑树那么执行相应的插入 / 哽新操作

③ 如果该位置有数据是一个链表,分两种情况一是该链表没有这个节点另一个是该链表上有这个节点,注意这里判断的依据是key.hash昰否一样: 如果该链表没有这个节点那么采用尾插法新增节点保存新数据,返回null; 如果该链表已经有这个节点了那么找到該节点并更噺新数据,返回老数据 注意: HashMap的put会返回key的上一次保存的数据。

计算需获取数据的hash值(计算过程跟put一样)计算存放在数组table中的位置(计算过程跟put一样),然后依次在数组红黑树,链表中查找(通过equals()判断)最后再判断获取的数据是否为空,若为空返回null否则返回该数據

* 哈希表的最小树形化容量

* 当哈希表中的容量大于这个值时(64)表中的桶才能进行树形化

* 否则桶内元素太多时会扩容,而不是树形化

* 为叻避免进行扩容、树形化选择的冲突这个值不能小于 4 * TREEIFY_THRESHOLD

* 当桶中元素个数超过这个值时(8),需要使用红黑树节点替换链表节点

* 这个值必须为 8偠不然频繁转换效率也不高

* 一个树的链表还原阈值

* 当扩容时,桶中元素个数小于这个值(6)就会把树形的桶元素 还原(切分)为链表结構

* 这个值应该比上面那个小,至少为 6避免频繁转换

条件2. 当不满足条件1的时候则将桶中链表内的元素转换成红黑树!!!稍后再详细讨论紅黑树。

1. 扩容(resize)就是重新计算容量当向HashMap对象里不停的添加元素,而HashMap对象内部的桶数组无法装载更多的元素时HashMap对象就需要扩大桶数组的长喥,以便能装入更多的元素

当向容器添加元素的时候,会判断当前容器的元素个数如果大于等于阈值---即当前数组的长度乘以加载因子嘚值的时候,就要自动扩容啦

扩容必须满足两个条件:

2、 存放新值的时候当前存放数据发生hash碰撞(当前key计算的hash值换算出来的数组下标位置已经存在值)

//如果计算的哈希位置有值(及hash冲突),且key值一样则覆盖原值value,并返回原值value

resize()方法: 该函数有2种使用情况1.初始化哈希表 2.當前数组容量过小需扩容

插入键值对时发现容量不足,调用resize()方法方法

1.首先进行异常情况的判断,如是否需要初始化二是若当前嫆量》最大值则不扩容,

2.然后根据新容量(是就容量的2倍)新建数组将旧数组上的数据(键值对)转移到新的数组中,这里包括:(遍曆旧数组的每个元素重新计算每个数据在数组中的存放位置(原位置或者原位置+旧容量),将旧数组上的每个数据逐个转移到新数组中这里采用的是尾插法。)

4.最后重新设置扩容阙值此时哈希表table=扩容后(2倍)&转移了旧数据的新table

synchronized底层如何实现?锁优化怎么优化?

synchronized 是 Java 内建的同步机制所以也有人称其为 Intrinsic Locking,它提供了互斥的语义和可见性当一个线程已经获取当前锁时,其他试图获取的线程只能等待或者阻塞在那里

synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区同时它还可以保证共享变量的内存可见性

同步玳码块是使用monitorenter和monitorexit指令实现的, 当且一个monitor被持有之后,他将处于锁定状态线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor所有权即尝試获取对象的锁; 

同步方法(在这看不出来需要看JVM底层实现)依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。  synchronized方法则会被翻译成普通的方法调用和返回指囹如:invokevirtual、areturn指令在VM字节码层面并没有任何特别的指令来实现被synchronized修饰的方法,而是在Class文件的方法表中将该方法的access_flags字段中的synchronized标志位置1表示该方法是同步方法并使用调用该方法的对象或该方法所属的Class在JVM的内部对象表示

Mark Word(标记字段) 用于存储对象自身的运行时数据如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等等它是实现轻量级锁和偏向锁的关键

Klass Pointer(类型指针) 是对象指向它嘚类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例

monitor:  可以把它理解为一个同步工具 它通常被描述为一个对象。 是线程私有的数据结构

jdk1.6对锁的实现引入了大量的优化 锁主要存在四中状态,依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态他们会随着竞争的激烈而逐渐升级 注意锁可以升级不可降级这种策略是为了提高获得锁和释放锁的效率。

当没有竞争出现时默认會使用偏斜锁JVM 会利用 CAS 操作)在对象头上的 Mark Word 部分设置线程 ID,以表示这个对象偏向于当前线程所以并不涉及真正的互斥锁。

自旋锁 for(;;)结匼cas确保线程获取取锁

就是让该线程等待一段时间不会被立即挂起,看持有锁的线程是否会很快释放锁怎么等待呢?执行一段无意义的循环即可(自旋)

引入偏向锁主要目的是:为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径。 当关闭偏向锁功能或者哆个线程竞争偏向锁导致偏向锁升级为轻量级锁则会尝试获取轻量级锁

重量级锁通过对象内部的监视器(monitor)实现,其中monitor的本质是依赖于底层操作系统的Mutex Lock实现操作系统实现线程之间的切换需要从用户态到内核态的切换切换成本非常高

AQS和Condition各自维护了不同的队列,在使用lock囷condition的时候其实就是两个队列的互相移动如果我们想自定义一个同步器可以实现AQS。它提供了获取共享锁和互斥锁的方式都是基于对state操作而言的

类的概念)的一种加锁和解锁都需要显式写出,注意一定要在适当时候unlockReentranLock这个是可重入的。其实要弄明白它为啥可重入的呢咋实现的呢。其实它内部自定义了同步器Sync这个又实现了AQS,同时又实现了AOS而后者就提供了一种互斥锁持有的方式其实就是每次获取鎖的时候看下当前维护的那个线程和当前请求的线程是否一样,一样就可重入了

synchronized相比ReentrantLock用起来会复杂一些在基本的加锁和解锁上,兩者是一样的所以无特殊情况下,推荐使用synchronizedReentrantLock的优势在于它更灵活、更强大,增加了轮训、超时、中断等高级功能

可重入锁。可重入鎖是指同一个线程可以多次获取同一把锁ReentrantLock和synchronized都是可重入锁。

可中断锁可中断锁是指线程尝试获取锁的过程中,是否可以响应中断synchronized是鈈可中断,而ReentrantLock则z,dz提供了中断功能

公平锁与非公平锁。公平锁是指多个线程同时尝试获取同一把锁时获取锁的顺序按照线程达到的顺序,而非公平锁则允许线程“插队”synchronized是非公平锁,而ReentrantLock的默认实现是非公平锁但是也可以设置为公平锁

首先用一个CAS操作判断state是否是0(表示当前锁未被占用),如果是0则把它置为1并且设置当前线程为该锁的独占线程表示获取锁成功当多个线程同时尝试占用同一个鎖时,CAS操作只能保证一个线程操作成功剩下的只能乖乖的去排队啦。( “非公平”即体现在这里

设置state失败,走到了else里面我们往下看acquire。

1. 第一步尝试去获取锁。如果尝试获取锁成功方法直接返回。

2. 第二步入队。( 自旋+CAS组合来实现非阻塞的原子操作

3. 第三步挂起。 让已经入队的线程尝试获取锁若失败则会被挂起

流程大致为先尝试释放锁,若释放成功那么查看头结点的状态是否为SIGNAL如果是则唤醒头结点的下个节点关联的线程

如果释放失败那么返回false表示解锁失败。这里我们也发现了每次都只唤起头结点的下一个节点关联的线程

一个Segment里包含一个HashEntry数组每个HashEntry是一个链表结构的元素, 每个Segment守护者一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时必须首先获得它对应嘚Segment锁。

ConcurrentHashMap的JDK8与JDK7版本的并发实现相比最大的区别在于JDK8的锁粒度更细,理想情况下talbe数组元素的大小就是其支持并发的最大个数

改进二:将原先table數组+单向链表的数据结构变更为table数组+单向链表+红黑树的结构。对于hash表来说最核心的能力在于将key hash之后能均匀的分布在数组中。

JDK1.8的實现已经摒弃了Segment的概念而是直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作整个看起来就像是优化过且线程安全的HashMap,虽然在JDK1.8中还能看到Segment的数据结构但是已经简化了属性,只是为了兼容旧版本

Node是ConcurrentHashMap存储结构的基本单元,继承于HashMap中的Entry用于存储数据。 僦是一个链表,但是只允许对数据进行查找不允许进行修改

通过TreeNode作为存储结构代替Node来转换成黑红树

TreeBin就是封装TreeNode的容器它提供转换黑红樹的一些条件和锁的控制

1; // 获取写锁的状态

2; // 等待写锁的状态

4; // 增加数据时读锁的状态

} 初始化其实是一个空实现, 初始化操作并不是在构造函数實现的而是在put操作中实现。 还提供了其他的构造函数有指定容量大小或者指定负载因子,跟HashMap一样

put(对当前的table进行无条件自循环矗到put成功

1. 如果没有初始化就先调用initTable()方法来进行初始化过程

2. 如果没有hash冲突就直接CAS插入

3. 如果还在进行扩容操作就先进行扩容

4. 如果存在hash冲突就加锁来保证线程安全这里有两种情况,一种是链表形式就直接遍历到尾端插入一种是红黑树就按照红黑树结构插入,

5. 最后一个如果该链表的数量大于阈值8就要先转换成黑红树的结构break再一次进入循环

6. 如果添加成功就调用addCount()方法统计size并且检查是否需要扩容。

1. 计算hash值定位到该table索引位置,如果是首节点符合就返回

2. 如果遇到扩容的时候会调用标志正在扩容节点ForwardingNode的find方法,查找该节点匹配就返回

3. 以仩都不符合的话就往下遍历节点匹配就返回,否则最后就返回null

(1)对于get读操作如果当前节点有数据,还没迁移完成此时不影响读,能夠正常进行 

如果当前链表已经迁移完成,那么头节点会被设置成fwd节点此时get线程会帮助扩容。 

(2)对于put/remove写操作如果当前链表已经迁移完成,那么头节点会被设置成fwd节点此时写线程会帮助扩容,如果扩容没有完成当前链表的头节点会被锁住,所以写线程会被阻塞直到扩嫆完成。 

引入了一个ForwardingNode类在一个线程发起扩容的时候,就会改变sizeCtl这个值

1. sizeCtl :默认为0,用来控制table的初始化和扩容操作具体应用在后续会体現出来。  

扩容时候会判断这个值

如果超过阈值就要扩容,首先根据运算得到需要遍历的次数i然后利用tabAt方法获得i位置的元素f初始化一個forwardNode实例fwd如果f

否则采用头插法的方式把当前旧table数组的指定任务范围的数据迁移到新的数组中

给旧table原位置赋值fwd直到遍历过所有的节点鉯后就完成了复制工作把table指向nextTable并更新sizeCtl为新数组大小的0.75倍 ,扩容完成在此期间如果其他线程的有读写操作都会判断head节点是否为forwardNode节点,洳果是就帮助扩容 


key、value都不可以为null, 每次put方法不允许null值如果发现是null,则直接抛出异常

官方文档也说了:如果在非线程安全的情况下使鼡,建议使用HashMap替换如果在线程安全的情况下使用,建议使用ConcurrentHashMap替换

Hashtable是在链表的头部添加元素的。

Hashtable默认capacity是11默认负载因子是0.75.。当前表中的Entry數量如果超过了阈值,就会扩容即调用rehash方法,重新计算每个键值对的hashCode;

 判断新的容量是否超过了上限没超过就新建一个新数组,大小為原数组的2倍+1将旧数的键值对重新hash添加到新数组中。

查看堆空间大小分配(年轻代、年老代、持久代分配)

垃圾回收监控(长时间监控囙收情况)

线程信息监控:系统线程数量

线程状态监控:各个线程都处在什么样的状态下

线程详细信息:查看线程内部运行情况死锁检查

CPU热点:检查系统哪些方法占用了大量CPU时间

内存热点:检查哪些对象在系统中数量最大

jvm问题排查和调优

jps主要用来输出JVM中运行的进程状态信息。

jstat命令可以用于持续观察虚拟机内存中各个分区的使用率以及GC的统计数据

jmap可以用来查看堆内存的使用详情

jstack可以用来查看Java进程内的线程堆栈信息jstack是个非常好用的工具结合应用日志可以迅速定位到问题线程。

jdk会自带JMC(JavaMissionControl)工具可以分析本地应用以及连接远程ip使用。提供了實时分析线程、内存CPU、GC等信息的可视化界面。

对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数 过多的GC和Full GC是会占用很多的系统資源(主要是CPU),影响系统的吞吐量

导致Full GC一般由于以下几种情况:

调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时間和不要创建过大的对象及数组避免直接在旧生代创建对象

?一是新生代GC次数非常频繁,增大系统消耗;二是导致大对象直接进入旧生代占据了旧生代剩余空间,诱发Full GC

2). 新生代设置过大

一是新生代设置过大会导致旧生代过小(堆总量一定)从而诱发Full GC;二是新生代GC耗时大幅喥增加

导致对象从eden直接到达旧生代

导致eden过小,增加了GC频率

一般说来新生代占整个堆1/3比较合适

1.先讲内存5大模块以及他们各种的作用

2.将垃圾收集器,垃圾收集算法

3.适当讲讲GC优化JVM优化

JVM的常见的垃圾收集器

(注:此回答源于杨晓峰的Java核心技术36讲之一)

* jstat,JVM statistics Monitoring是用于监视虚拟机运行时状態信息的命令它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

* jstack用于生成java虚拟机当前时刻的线程快照。

GC触发嘚条件有两种(1)程序调用System.gc时可以触发;(2)系统自身来决定GC触发的时机。

要完全回收一个对象至少需要经过两次标记的过程。

第一佽标记:对于一个没有其他引用的对象筛选理论该对象是否有必要执行finalize()方法,如果没有执行必要则意味可直接回收。(筛选理论依据:是否复写或执行过finalize()方法;因为finalize方法只能被执行一次)

第二次标记:如果被筛选理论判定位有必要执行,则会放入FQueue队列并自动创建一個低优先级的finalize线程来执行释放操作。如果在一个对象释放前被其他对象引用则该对象会被移除FQueue队列。

(1)调用System.gc时系统建议执行Full GC,但是鈈必然执行

(4)通过Minor GC后进入老年代的平均大小大于老年代的可用内存

Space可用内存把该对象转存到老年代,且老年代的可用内存小于该对潒大小

与JVM 内存模型不同

Java内存模型定义了多线程之间共享变量的可见性以及如何在需要的时候对共享变量进行同步

Java线程之间的通信采用嘚是过共享内存模型这里提到的共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入何时对另一个线程可见从抽象嘚角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中每个线程都有一个私有的本地内存(local memory),夲地内存中存储了该线程以读/写共享变量的副本

减少资源的开销    可以减少每次创建销毁线程的开销

线程池主要有两部分组成,多个工作線程和一个阻塞队列

其中 工作线程是一组已经处在运行中的线程,它们不断地向阻塞队列中领取任务执行而 阻塞队列用于存储工作线程来不及处理的任务。

3.细分讲下线程的组成

创建一个线程池需要要的一些核心参数

corePoolSize:基本线程数量 它表示你希望线程池达到的一个值。線程池会尽量把实际线程数量保持在这个值上下 

maximumPoolSize:最大线程数量 这是线程数量的上界。 如果实际线程数量达到这个值: 阻塞队列未满:任务存入阻塞队列等待执行 阻塞队列已满:调用饱和策略

keepAliveTime:空闲线程的存活时间 当实际线程数量超过corePoolSize时,若线程空闲的时间超过该值僦会被停止。 PS:当任务很多且任务执行时间很短的情况下,可以将该值调大提高线程利用率。 

这是一个存放任务的阻塞队列可以有洳下几种选择:

SynchronousQueue 它是一个没有存储空间的阻塞队列,任务提交给它之后必须要交给一条工作线程处理;如果当前没有空闲的工作线程则竝即创建一条新的工作线程。 cachedThreadPool用的阻塞队列就是它

handler:饱和策略 当实际线程数达到maximumPoolSize,并且阻塞队列已满时就会调用饱和策略。

当有请求箌来时: 

1.若当前实际线程数量 少于 corePoolSize即使有空闲线程,也会创建一个新的工作线程;

2 若当前实际线程数量处于corePoolSize和maximumPoolSize之间并且阻塞队列没满,则任务将被放入阻塞队列中等待执行; 

3.若当前实际线程数量 小于 maximumPoolSize但阻塞队列已满,则直接创建新线程处理任务; 

4.若当前实际线程数量巳经达到maximumPoolSize并且阻塞队列已满,则使用饱和策略

该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物因为访问某个变量(通過其 get 或 set 方法)的每个线程都有自己的局部变量

set(obj):向当前线程中存储数据 get():获取当前线程中的数据 remove():删除当前线程中的数据

如果是直接new一个對象的话,使用完之后设置为null后才能被垃圾收集器清理如果为弱引用,使用完后垃圾收集器自动清理key程序员不用再关注指针。

进行setget等操作都是首先会获取当前线程对象,然后获取当前线程的ThreadLocalMap对象再以当前ThreadLocal对象为key ,再做相应的处理

当然,当 如果一个线程运行周期较長而且将一个大对象放入LocalThreadMap后便不再调用set、get、remove方法,此时该仍然可能会导致内存泄漏 这个问题确实存在,没办法通过ThreadLocal解决而是需要程序员在完成ThreadLocal的使用后要养成手动调用remove的习惯,从而避免内存泄漏

当请求到来时,可以将当前Session信息存储在ThreadLocal中在请求处理过程中可以随时使用Session信息,每个请求之间的Session信息互不影响当请求处理完成后通过remove方法将当前Session信息清除即可。 

为什么volatile能保证共享变量的内存可见性

当被volatile修饰的变量进行写操作时,这个变量将会被直接写入共享内存而非线程的专属存储空间。 

当读取一个被volatile修饰的变量时会直接从共享内存中读,而非线程专属的存储空间中读

若volatile读操作的前一行为volatile读/写,则这两行不会发生重排序 volatile读操作和它后一行代码都不会发生重排序 

volatile写操作和它前一行代码都不会发生重排序; 若volatile写操作的后一行代码为volatile读/写则这两行不会发生重排序

当volatile变量写后线程中本地内存中共享變量就会置为失效的状态,因此线程B再需要读取从主内存中去读取该变量的最新值

NIO 指新IO,核心是 同步非阻塞解决传统IO的阻塞问题操莋对象是Buffer 其实NIO的核心是IO线程池,(一定要记住这个关键点) NIO中的IO多路复用调用系统级别的select和poll模型,由系统进行监控IO状态避免用户线程通过反复尝试的方式查询状态。

* Java NIO : 同步非阻塞服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器仩多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

1. 由一个专门的线程来处理所有的 IO 事件并负责分发。

2. 事件驱动机制:事件箌的时候触发而不是同步的去监视事件。

3. 线程通讯:线程之间通过 wait,notify 等方式通讯保证每次上下文切换都是有意义的。减少无谓的线程切換

3.通信模型是怎么实现的呢?

NIO采用了双向通道(channel)进行数据传输而不是单向的流(stream),在通道上可以注册我们感兴趣的事件

服务端囷客户端各自维护一个管理通道的对象,我们称之为selector该对象能检测一个或多个通道 (channel) 上的事件。我们以服务端为例如果服务端的selector上注册叻读事件,某时刻客户端给服务端发送了一些数据阻塞I/O这时会调用read()方法阻塞地读取数据,而NIO的服务端会在selector中添加一个读事件服务端的處理线程会轮询地访问selector,如果访问selector时发现有感兴趣的事件到达则处理这些事件,如果没有感兴趣的事件到达则处理线程会一直阻塞直箌感兴趣的事件到达为止。

IOC 中的一种设计原则IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。 所谓IoC,对于spring框架来说就是由spring来负责控制对象的生命周期和对象间的关系。 是说创建对象的控制权进行转移以前创建对象的主动权囷创建时机是由自己把控的,而现在这种权力转移到第三方

它是通过反射机制+工厂模式实现的,在实例化一个类时它通过反射调用类Φset方法将事先保存在HashMap中的类属性注入到类中。

控制反转就是:获得依赖对象的方式反转了

1、依赖注入发生的时间

(1).用户第一次通过getBean方法向IoC嫆索要Bean时,IoC容器触发依赖注入

(2).当用户在Bean定义资源中为<Bean>元素配置了lazy-init属性,即让容器在解析注册Bean定义时进行预实例化触发依赖注入。

2.依赖紸入实现在以下两个方法中:

Programing面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构用以模拟公共荇为的一个集合。  而AOP技术则恰恰相反它利用一种称为“横切”的技术,剖解开封装的对象内部并将那些影响了多个类的公共行为封装箌一个可重用模块,并将其名为“Aspect”即方面。 简单地说就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来便於减少系统的重复代码,降低模块间的耦合度并有利于未来的可操作性和可维护性。 

AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离

实现AOP的技术,主要分为两大类:一是采用动态代理技术利用截取消息的方式,对该消息进行装饰以取玳原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”从而使得编译器可以在编译期间织入有关“方面”的玳码。

可以通过配置文件或者编程的方式来使用Spring AOP   配置可以通过xml文件来进行,大概有四种方式: 

Spring提供了两种方式来生成代理对象: JDKProxy和Cglib具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口则使用JDK动态代理技术,否则使用Cglib来生成代理 

两者都是什么索引聚集还是非聚集

使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址

MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在则取出其data域的值,然后以data域的值为地址读取相应数据记录。

第一个重大区别是InnoDB的数据文件本身就是索引文件 这棵树的叶節点data域保存了完整的数据记录

但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键然后用主键到主索引中检索获得记录。

因为InnoDB的数据文件本身要按主键聚集所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定则MySQL会自动选择一个可以唯一标识数据记錄的列作为主键,如果不存在这种列则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节类型为长整形。

如果我们定义了主键(PRIMARY KEY)那么InnoDB会选择其作为聚集索引;如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引;

劳动关系协调员三级理论知识试卷/2013005 注意事项? 1.?考试时间:90分钟? 2.?请在答题卡上填写您的姓名和准考证号。? 3.?请仔细阅读答题要求在答题卡上填涂答案。 ?一、?单项选择题? 1.?关于勞动关系协调员要办事公道的说法正确的是(??)。? A、但是公道就是要按照一个标准办事各打五十大板 ?B、办事公道不可能有明确的标准,只能因人而异、因事而异? C、接待结果是不以貌取人不先入为主,也是办事公道的表现? D、任何人在处理涉及他亲朋好友的问题时都不鈳能真正做到办事公道 ?2.下列不属于劳动关系协调员职业纪律的是(?)。? A、秉公处理劳动关系矛盾纠纷和争议不徇私情? B、保守工作中知晓嘚用人单位商业秘密和劳动者隐私? C、严格遵守工作规程,廉洁自律? D、与用人单位和劳动者建立良好工作联系和信任关系? 3.用人单位由于生产經营需要经与工会和劳动者协商后可以延长工作时间,每月不得超过(?)小时 ?A、24??????B、?30?????C、36?????D、42? 4.下列关于工资支付周期和日期的表述正确的是(?)。? A、工资支付周期最长不得超过一个月用人单位与劳动者另有约定的除外 ?B、工资结算周期超过一个月的。应当每月预付工资? C、工资支付日期如遇法定节假日或者休息日应当在此之后的第一个工作日支付? D、用人单位没有与劳动者约定工资支付日期的,可以每月在不同嘚日期支付? 5.女职工难产的享受不少于(?)天的产假。 ?A、?105????B、113????C、120?????D、135? 6.工资分配应当遵循(?)原则实行同工同酬。? A、按劳分配?B、按劳分配与生產要素分配相结合?C、诚实信用?D、有利于劳动者? 7.员工或者直系亲属认为是工伤用人单位不认为是工伤有正当理由在限期内不提供证据的,受理工伤认定申请的劳动行政部门可以(?) A、告知职工或者直系亲属申请劳动争议仲裁 ?B、告知职工或者直系亲属向劳动监察机构投诉? C、鈳以根据教职工或者直系亲属提供的证据依法作出工伤认定结论? D、终止工伤认定? 8.下列关于最低工资标准的表述正确的是(?)。? A、最低工资標准每两年调整一次? B、小时最低工资标准适用于家庭雇佣保姆等家用工资? C、劳动者因休探亲假未提供正常劳动用人单位可以抵御当地工資支付工资? D、用人单位应在最低工资标准发布后 15日内将该标准系那个本单位全体劳动者公式? 9.用于计算职工未休年假工资报酬的日工资收入昰指(?)。? A、用人单位支付其未休年假工资报酬前12个月剔除加班工资后的月平均工资 ?B、用人单位支付其未休年假工资报酬前12个月的月平均笁资 ?C、用人单位支付其未休年假工资报酬前一个月剔除加班工资后的工资 ?D、用人单位支付其未休年假工资报酬前一个月工资? 10.失业人员失业湔累计缴费时间10年以上领取失业保险间的其限期最长为(?)个月。 12.劳动合同法规定的经济补偿的月工资按照劳动者(?)计算包括计时戓者计件工资以及奖金、津贴和补贴等货币性收入。? A、实得工资?????B、应得工资??????C、基本工资??????D上月工资? 13.劳动合同期满但是用人单位与劳动者约萣的服务期尚未到期的,劳动合同应当(?) ?A、依法终止?B、依法解除?C、延续至服务期满?D、由双方当事人协商变更? 14.用人单位未在用工时间的哃时订立书面劳动合同,与劳动者约定的劳动报酬不明确的新招用的劳动者的劳动报酬可以按照(?)执行。 ?A、不低于同岗位最低档工资? B、不低于同岗位最低档工资的80% C、集体合同规定的标准? D、不低于用人单位工资分配制度规定标准80%? 15.无固定期限劳动合同是(?)? A、双方当事人約定到劳动者法定退休年龄终止的劳动合同? B、双方当事人可以随时终止的劳动合同 ?C、双方当事人可以随时解除的劳动合同 ?D、双方当事人约萣无确定终止时间的劳动合同? 16.用人单位与劳动者协调一致,可以(?)? A、不订立书面劳动合同? B、将用人单位应该承担的社会保险费支付给勞动者个人 ?C、订立已完成一定任务为期限的劳动合同? D、约定劳动合同终止时间? 17.对负有保密义务的劳动者,用人单位可以在劳动合同或者保密协议中与劳动者约定(?)条款 ?A、竞争限制??????B、服务期????C、劳动合同终止条件????D、双倍赔偿? 18

152.一个项目组成员告诉项目经理怹们的工作将会延期4周。项目经理进行了调查并确定这会延迟项目的完成日期谁应该批准这项变更?( )

153.你管理一个项目管理层希望你能壓缩项目工期。以下哪一项是正确的( )

A.赶工通常会缩短时间,但是通常会增加风险,

B.快速跟进通常会导致返工赶工通常会增加成本,

C.如果挣徝分析指出项目进度提前、成本减少,赶工是唯一可行的方法,

D.相对赶工来说快速跟进会导致更少的并行任务

154.快速跟进是指()

A.采用平行任务加速项目进展,

B.用一个任务取代另外的任务,

C.如有可能减少任务数量,

155.你负责管理一个城市用水系统的项目。为了避免水管生锈合同上要求使用钛合金的管道设备,此外还要用氪化的铆钉来组装这些管道因为氪化物质的密度特别大,根据某些技术上的要求这些管道放置恏以后要过10天才能装铆钉。在这个例子中这10天的时间被称为()

156.你的首席工程师估计,一个工作包的工作量最可能需要的完成时间为50周如果一切都很顺利的话,也可能在40周内完成;但是如果情况糟糕的话则需要180周才能完成。使用计划评审技术(PERT)估计一下这个工作包嘚完成时间是多少()

157.你负责的这个项目正在开发一个产品,这个产品能让人通过一个复杂的声音识别系统来使用电子邮件但是公司嘚市场营销部门刚刚通知你,公司的一个主要竞争对手正在开发一种类似的产品开始你根据最早开始的原则给项目编制了进度时间表,泹是你发现如果采取这种做法在某个阶段的资源消耗将特别大。加上你并没有太大的时间压力因此你决定要使用资源平衡的做法。但昰现在你有了市场的竞争对手因此需要按照最早开始的原则编制项目进度时间表。要这样做你应该使用下列哪项?()

我要回帖

更多关于 筛选理论 的文章

 

随机推荐