面试问题
1. Innnodb和MyIASM的区别
Innodb引擎
Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。
MyIASM引擎
MyIASM是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。不过和Innodb不同,MyIASM中存储了表的行数,于是SELECT COUNT(*) FROM TABLE时只需要直接读取已经保存好的值而不需要进行全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyIASM也是很好的选择。
主要区别:
1、MyIASM是非事务安全的,而InnoDB是事务安全的
2、MyIASM锁的粒度是表级的,而InnoDB支持行级锁
3、MyIASM支持全文类型索引,而InnoDB不支持全文索引
4、MyIASM相对简单,效率上要优于InnoDB,小型应用可以考虑使用MyIASM
5、MyIASM表保存成文件形式,跨平台使用更加方便
应用场景:
1、MyIASM管理非事务表,提供高速存储和检索以及全文搜索能力,如果在应用中执行大量select操作,应该选择MyIASM
2、InnoDB用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量insert和update操作,应该选择InnoDB
2. mysql的事务隔离等级及脏读,不可重复读,幻读?
见博客
3. 索引?什么时候使用?Explain?
建索引:CREATE INDEX index_name ON table_name(column_list)
删除索引:DROP INDEX index_name ON table_name
ALTER TBALE table_name DROP INDEX index_name
查看索引:SHOW INDEX FROM table_name
SHOW keys FROM table_name
4. 项目中为什么使用逻辑回归算法?
首先逻辑回归和传统的线性回归不同,线性回归给出的是一个分类结果,比如是或者不是等,但时逻辑回归的模型给出的是每个东西在那些特征基础上的一个概率模型,我们可以通过计算每个特征集的总的概率,然后进行一个汇总,最终得到一个概率排名,通过概率排名来进行推荐,在推荐的时候一般会有多个推荐,选取前面的前N个进行推荐。
5. Sed 、grep、awk操作!
看笔记本
6. OSI七层模型和TCP/IP4层模型?
7. TCP和UDP的区别?
基于连接与无连接;
对系统资源的要求(TCP较多,UDP少);
UDP程序结构较简单;
流模式与数据报模式 ;
TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
8. TCP的三次握手和四次握手?
http://blog.csdn.net/yqlakers/article/details/69950482
9. TCP协议中的慢启动,拥塞避免,快速重传,快速恢复:
http://blog.csdn.net/itmacar/article/details/12278769
10. HashMap和HashTable的比较及相关的底层实现?
继承类不同:
A.HashMap继承AbstractMap
B.Hashtable继承Dictionary
执行效率不同:
A.HashMap是非线程安全的,是Hashtable的轻量级实现,效率较高
B.Hashtable是线程安全的,效率较低
put方法对key和value的要求不同
A.HashMap允许Entry的key或value为null
B.Hashtable不允许Entry的key或value为null,否则出现NullPointerException
4
有无contains方法
A.HashMap没有contains方法
B.Hashtable有contains方法
11. HashMap和HashTable的底层实现原理的区别?
口述
12. HashMap和HashSet的区别?
HashSet和HashMap的区别
*HashMap* | *HashSet* |
HashMap实现了Map接口 | HashSet实现了Set接口 |
HashMap储存键值对 | HashSet仅仅存储对象 |
使用put()方法将元素放入map中 | 使用add()方法将元素放入set中 |
HashMap中使用键对象来计算hashcode值 | HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false |
HashMap比较快,因为是使用唯一的键来获取对象 | HashSet较HashMap来说比较慢 |
13. ConcurrentHashMap的实现原理
http://blog.csdn.net/yqlakers/article/details/76113730
ConcurrentHashMap底层是有segment的数组组成,segment由hashEntry数组组成,segment的底层结构就是一个Hashtable,实现了对segment的细粒度的控制,concurrentHashMap进行扩容时,从segment内部进行扩容,默认segment和HashEntry的大小都是16,loadFacotr为0.75,每个segment对元素内部大小是可见的,当调用size(),方法去统计ConcurentHashMap大小的时候,会首先统计两次左右segment的元素之和,如果相同,那么就将其结果返回,如果不同,那么就将所有的segment锁定然后计算结果然后返回。
14. LinkedList和ArrayList的区别?
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
3.LinkedList不支持高效的随机元素访问。
4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
15. JAVA的GC回收机制及相关算法。
http://blog.csdn.net/yqlakers/article/details/70138786
16. JDK7和JDK8的区别
17. 线程的几种状态?(P350)
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
18. 进程间的通信方式?
管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);
报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
19. 索引为何选B树,B+树,不选二叉树?
B+相对于B树,(1)B+树空间利用率更高,因为B+树的内部节点只是作为索引使用,而不像B-树那样每个节点都需要存储硬盘指针。(2)增删文件(节点)时,效率更高,因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率。
20. 数据库数据改变后怎么获取哪些数据改变了,哪些没改变?
?
21. 范式?
一共有6个范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
22. Mapreduce的10个步骤?
见笔记
23. 设计模式?
24. COOKIE和SEEION?
1,session 在服务器端,cookie在客户端(浏览器)
2,session 默认被存在在服务器的一个文件里(不是内存)
3,session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
4,session 可以放在 文件、数据库、或内存中都可以。
5,用户验证这种场合一般会用 session
因此,维持一个会话的核心就是客户端的唯一标识,即 session id
比如说我们在购物网站上去某个东西加入购物车,通过cookie知道是谁的账户操作的,并将这些信息存储到session,并给这个cookie传递一个sesiion_id,下次可以通过这个session_id知道是那个用户了。
25. HTTP/HTTPS?
https在http基础上加了stl协议,更加安全。
26. HADOOP1.0和2.0区别?(4点)
(1)针对Hadoop1.0单NameNode制约HDFS的扩展性问题,提出HDFS Federation,它让多个NameNode分管不同的目录进而实现访问隔离和横向扩展,同时彻底解决了NameNode单点故障问题;
(2)针对Hadoop1.0中的MapReduce在扩展性和多框架支持等方面的不足,它将JobTracker中的资源管理和作业控制分开,分别由ResourceManager(负责所有应用程序的资源分配)和ApplicationMaster(负责管理一个应用程序)实现,即引入了资源管理框架Yarn。
(3)Yarn作为Hadoop2.0中的资源管理系统,它是一个通用的资源管理模块,可为各类应用程序进行资源管理和调度,不仅限于MapReduce一种框架,也可以为其他框架使用,如Tez、Spark、Storm等
2. 从MapReduce计算框架来讲
MapReduce1.0计算框架主要由三部分组成:编程模型、数据处理引擎和运行时环境。它的基本编程模型是将问题抽象成Map和Reduce两个阶段,其中Map阶段将输入的数据解析成key/value,迭代调用map()函数处理后,再以key/value的形式输出到本地目录,Reduce阶段将key相同的value进行规约处理,并将最终结果写到HDFS上;它的数据处理引擎由MapTask和ReduceTask组成,分别负责Map阶段逻辑和Reduce阶段的逻辑处理;它的运行时环境由一个JobTracker和若干个TaskTracker两类服务组成,其中JobTracker负责资源管理和所有作业的控制,TaskTracker负责接收来自JobTracker的命令并执行它。
MapReducer2.0具有与MRv1相同的编程模型和数据处理引擎,唯一不同的是运行时环境。MRv2是在MRv1基础上经加工之后,运行于资源管理框架Yarn之上的计算框架MapReduce。它的运行时环境不再由JobTracker和TaskTracker等服务组成,而是变为通用资源管理系统Yarn和作业控制进程ApplicationMaster,其中Yarn负责资源管理的调度而ApplicationMaster负责作业的管理。
27. 槽位数的共享问题?需要注意什么?(REDUCE SLOT提前启动和MAPSLOT饿死)
28. ZK的LEADER选举算法?
数据最新进行比较然后比较Leader_id。逻辑时钟,同一次选举的逻辑时钟是相同的,随着选举的进行,逻辑时钟的值不断增大。假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的.假设这些服务器依序启动,来看看会发生什么.
1) 服务器1启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的选举状态一直是LOOKING状态
2) 服务器2启动,它与最开始启动的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是3),所以服务器1,2还是继续保持LOOKING状态.
3) 服务器3启动,根据前面的理论分析,服务器3成为服务器1,2,3中的老大,而与上面不同的是,此时有三台服务器选举了它,所以它成为了这次选举的leader.
4) 服务器4启动,根据前面的分析,理论上服务器4应该是服务器1,2,3,4中最大的,但是由于前面已经有半数以上的服务器选举了服务器3,所以它只能接收当小弟的命了.
5) 服务器5启动,同4一样,当小弟.
以上就是fastleader算法的简要分析,还有一些异常情况的处理,比如某台服务器宕机之后的处理,当leader宕机之后的处理等等,后面再谈.
29. Mapreduce和Hive的比较?
1. 运算资源消耗
无论从时间,数据量,计算量上来看,一般情况下mr都是优于或者等于hive的。mr的灵活性是毋庸置疑的。在转换到hive的过程中,会有一些为了实现某些场景的需求而不得不用多步hive来实现的时候。
2. 开发成本/维护成本
毫无疑问,hive的开发成本是远低于mr的。如果能熟练的运用udf和transform会更加提高hvie开发的效率。另外对于数据的操作也非常的直观,对于全世界程序员都喜闻乐见的sql语法的继承也让它更加的容易上手。
hive独有的分区管理,方便进行数据的管理。
代码的管理也很方便,就是直接的文本。
逻辑的修改和生效很方便。
但是当出现异常错误的时候,hive的调试会比较麻烦。特别是在大的生产集群上面的时候。
3. 底层相关性
在使用hive以后,读取文件的时候,再也不用关心文件的格式,文件的分隔符,只要指定一次,hive就会保存好。相比mr来说方便了很多。
当侧重关心与业务相关的内容的时候,用hive会比较有优势。而在一些性能要求高,算法研究的时候,mr会更加适合。
30. SUFFLE?COMBINER?写不写?写了有什么好处?不写有什么问题?写的时候注意什么?PARTION?
Shuffle发生在map的输出到reduce输入这段过程,首先将将map的输入数据进行分区然后进行排序然后进入缓存,溢写到磁盘,在磁盘中进行merge,将不同分区的map输出并进行merge,然后传到reduce进行操作。大概是:partition->sort->spill todisk->merge on disk->merge
Combiner:在map输入后在内存缓冲的过程中,去不断得执行操作,合并相同的key,减少到磁盘的溢写,从而减少到reduce的输出。如果client设置过Combiner,那么现在就是使用Combiner的时候了。将有相同key的key/value对的value加起来,减少溢写到磁盘的数据量。Combiner会优化MapReduce的中间结果,所以它在整个模型中会多次使用。那哪些场景才能使用Combiner呢?从这里分析,Combiner的输出是Reducer的输入,Combiner绝不能改变最终的计算结果。所以从我的想法来看,Combiner只应该用于那种Reduce的输入key/value与输出key/value类型完全一致,且不影响最终结果的场景。比如累加,最大值等。Combiner的使用一定得慎重,如果用好,它对job执行效率有帮助,反之会影响reduce的最终结果
Spill:读取split之后产生map的key/value后会存到内存中,默认缓冲大小为100MB,一旦缓冲达到一个阈值(默认为0.8,80MB)时,会将缓存到内存的内容溢写(spill)到磁盘中,这个过程就叫做spill,当然在溢写之前会在内存中key/value进行排序。
MapReduce提供Partitioner接口,它的作用就是根据key或value及reduce的数量来决定当前的这对输出数据最终应该交由哪个reduce task处理。默认对key hash后再以reduce task数量取模。默认的取模方式只是为了平均reduce的处理能力,如果用户自己对Partitioner有需求,可以订制并设置到job上。
31. MR运行时候优先级如何设置?
#1:调用API
JobConf.setJobPriority(JobPriority.NORMAL)
#2:Configuration设置
Configuration c = new Configuration();
c.set(' mapred.job.priority',JobPriority. NORMAL.name());
优先级有五种:VERY_HIGH 、HIGH、 NORMAL、 LOW、VERY_LOW
32. capacity scheduler和fair scheduler调度器?详细说下?区别?对比?
公平调度器:公平调度器的目标是让每个用户公平享用集群的资源,如果只有一个作业运行,就会得到集群的所有资源,但是随着作业提交的增加,闲置的任务槽会让每个用户公平共享集群的资源。某个用户的耗时短的作业将在合理的时间内完成,即便另外一个用户的长时间作业仍然在运行之中。
作业都放在作业池中,每个用户都有一个作业池,作业提交多的用户不会因此获得更多的资源。公平调度器支持抢占机制,如果一个作业池在特定的一段时间内未能公平共享资源,就会中止运行池中得到过多资源的任务,把空出来的任务槽让给运行资源不足的作业池。
容量调度器:容量调度器以队列为单位划分资源,每个队列都有资源使用的下限和上限。每个用户也可以设定资源使用上限。一个队列的剩余资源可以共享给另一个队列,其他队列使用后还可以归还。管理员可以约束单个队列、用户或作业的资源使用。支持资源密集型作业,可以给某些作业分配多个slot(这是比较特殊的一点)。支持作业优先级,但不支持资源抢占。
计算能力调度器与公平调度器对比
(1) 相同点
@均支持多用户多队列,即:适用于多用户共享集群的应用环境
@单个队列均支持优先级和FIFO调度方式
@均支持资源共享,即某个queue中的资源有剩余时,可共享给其他缺资源的queue
(2) 不同点
@核心调度策略不同。 计算能力调度器的调度策略是,先选择资源利用率低的queue,然后在queue中同时考虑FIFO和memory constraint因素;而公平调度器仅考虑公平,而公平是通过作业缺额体现的,调度器每次选择缺额最大的job(queue的资源量,job优先级等仅用于计算作业缺额)。
@内存约束。计算能力调度器调度job时会考虑作业的内存限制,为了满足某些特殊job的特殊内存需求,可能会为该job分配多个slot;而公平调度器对这种特殊的job无能为力,只能杀掉这种task。(不会让你多获得资源的)
也就是说公平调度器给每个用户的任务队列分配相同的资源,而capacity调度器根据每个用户的任务队列的所需资源大小进行资源分配,同时在 每个队列中支持优先级和FIFO调度方式。
33. HBASE均衡负载?
HBase的均衡算法可以通过实现了LoadBalancer接口hbase.master.loadbalancer.class来自定义。
Hbase的均衡是通过HMaster去实现的,如果在某个RegionServer的region的数量过多,那么就会通过HMaster去实现调度,将将多region的RegionServer上的region移到较少regioon的RegionServer上。
负载均衡以特定时间间隔(hbase.balancer.period 默认是5分钟)执行。
当遇到如下场景时候不进行负载均衡:
1.均衡负载开关balanceSwitch关闭。
2.HMase未完成初始化。
3.RIT中有未处理完的regions。
4.有正在处理的DeadRegionserver.
负载的算法思路:首先对RegeionServer的负载大小进行排序,如果负载大小相同就按Servername进行排序,排序完了之后通过算法计算出是否需要进行负载均衡,如果需要的话,会算出一个最大负载和最小负载,将RegionServer上的region移动到较少的RegionServer上,实现满足负载最小和最大之间。
34. 线程的几种状态并画出其状态转换图?
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
小小的作下解释:
1、线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了这个对象后,线程就进入了初始状态;
2、当该对象调用了start()方法,就进入可运行状态;
3、进入可运行状态后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;
4、进入运行状态后情况就比较复杂了
4.1、run()方法或main()方法结束后,线程就进入终止状态;
4.2、当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片;
4.3、线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到可运行状态,这时与其他进程处于同等竞争状态,OS有可能会接着又让这个进程进入运行状态;
4.4、当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchroniza(同步),获取不到锁标记,将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待OS分配CPU时间片;
4.5、当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。
35. Java的内存模型,volatile?
http://www.importnew.com/18126.html
36. Linux下kill包含java关键字的程序?
ps –ef | grep ‘java’ | awk ‘{print $2}’ |xargs kill -9;
ps –ef | grep ‘java’ | cut –c 9-15 | xargs kill -9
ps –ef:显示所有的线程
grep ‘java’:获取所有包含java关键字的程序
awk ‘{print $2}’:选出第二列,即为PID
cut –c 9-15:选出PID
xargs kill -9:将PID位变量,kill掉
37. Happen before?
下面就来具体介绍下happens-before原则(先行发生原则,8条):
· 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
· 锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作
· volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
· 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
· 线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作
· 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
· 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
· 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始。
38. 数据库中TRUNCATE 和DELETE的区别?
虽然TRUNCATE和DELETE都可以删除表的所有记录,但有原理不同。DELETE的效率没有TRUNCATE高!
TRUNCATE其实属性DDL语句,因为它是先DROPTABLE,再CREATE TABLE。而且TRUNCATE删除的记录是无法回滚的,但DELETE删除的记录是可以回滚的(回滚是事务的知识!)。
39. 怎么查看刚才kill掉的程序?怎么替换中某个文件中的‘java’,替换为‘python’?
将刚才的kill之前的程序存到一个文件中,kill掉之后再查看剩下的就知道kill掉了哪些。sed "s/原字符串包含'/替换字符串包含'/" s表示替换的意思