面试题整理 有经验自己的语言
Posted shan1393
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题整理 有经验自己的语言相关的知识,希望对你有一定的参考价值。
4、谈谈你对JVM的理解?
答: Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。Java编译器只要面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。
JVM执行程序的过程 :I.加载。class文件 ,II.管理并分配内存 ,III.执行垃圾收集
JRE(java运行时环境)由JVM构造的java程序的运行环境
1、SpringMVC的原理以及返回数据如何渲染到jsp/html上?
答:Spring MVC的核心就是 DispatcherServlet , 一个请求经过 DispatcherServlet ,转发给HandlerMapping ,然后经反射,对应 Controller及其里面方法的@RequestMapping地址,最后经ModelAndView和ViewResoler返回给对应视图
2、一个类对象属性发生改变时,如何让调用者知道?
答:Java event时间监听 ,即在set方法改变属性时,触发 ,这种模式也可以理解为观察者模式,具体查看:观察者模式简单案例和说明
IO NIO
面向流 面向缓冲
阻塞IO 非阻塞IO
无 选择器
Java NIO和IO的区别
面向流与面向缓冲
Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
红黑树, 二叉树
https://blog.csdn.net/yang_yulei/article/details/26066409
索引的工作原理
为什么需要索引(Why is it needed)?
当数据保存在磁盘类存储介质上时,它是作为数据块存放。这些数据块是被当作一个整体来访问的,这样可以保证操作的原子性。硬盘数据块存储结构类似于链表,都包含数据部分,以及一个指向下一个节点(或数据块)的指针,不需要连续存储。
记录集只能在某个关键字段上进行排序,所以如果需要在一个无序字段上进行搜索,就要执行一个线性搜索(Linear Search)的过程,平均需要访问N/2的数据块,N是表所占据的数据块数目。如果这个字段是一个非主键字段(也就是说,不包含唯一的访问入口),那么需要在N个数据块上搜索整个表格空间。
但是对于一个有序字段,可以运用二分查找(Binary Search),这样只要访问log2 (N)的数据块。这就是为什么性能能得到本质上的提高。
什么是索引(What is indexing)?
索引是对记录集的多个字段进行排序的方法。在一张表中为一个字段创建一个索引,将创建另外一个数据结构,包含字段数值以及指向相关记录的指针,然后对这个索引结构进行排序,允许在该数据上进行二分法排序。
副作用是索引需要额外的磁盘空间,对于MyISAM引擎而言,这些索引是被统一保存在一张表中的,这个文件将很快到达底层文件系统所能够支持的大小限制,如果很多字段都建立了索引的话。
索引如何工作(How does it work?)
首先,我们建立一个示范数据库表:
字段名 数据类型 大小
id (Primary key) Unsigned INT 4 bytes
firstName Char(50) 50 bytes
lastName Char(50) 50 bytes
emailAddress Char(100) 100 bytes
注意:使用char是为了指定准确的磁盘占用大小。这个示范数据库包含500万行,而且没有索引。我们将分析一些查询语句的性能,一个是使用主键id(有序)查询,一个是使用firstName(非关键无序字段)。
例1
我们的示范数据库有r=5,000,000条记录,每条记录长度R=204字节而且使用MyISAM引擎存储(默认数据块大小为B=1024字节),这张表的块因子(blocking factor)会是bfr = (B/R) = 1024/204 = 5 条记录每磁盘数据块。保存这张表所需要的磁盘块为N = (r/bfr) = 5000000/5 = 1,000,000 blocks。
在id字段上的线性搜索平均需要N/2 = 500,000块访问来找到一条记录假设id字段是查询关键值,不过既然id字段是有序的,可以执行一个二分查询,这样平均只需要访问log2 (1000000) = 19.93 = 20 个数据块。我们马上就看到了极大的提高。
现在firstName字段既不是有序的,无法执行二分搜索,数值也不具有唯一性,所以对这张表的查找必须到最后一个记录即全表扫描N = 1,000,000个数据块访问。这就是索引用来改进的地方。
假如索引记录只包含一个索引列以及一个指向原记录数据的指针,那么它显而易见会比原记录(多列)要小。所以索引本身所需要的磁盘块要更少,扫描数目也少。firstName索引表结构如下:
Field name Data type Size on disk
firstName Char(50) 50 bytes
(record pointer) Special 4 bytes
注意: mysql里的指针按表大小的不同分别可能是 2, 3, 4 或 5 个字节。
例2
假设我们的数据库有r = 5,000,000 条记录,建立了一个长R = 54字节的索引,并且使用默认磁盘块大小为1,024字节。那么该索引的块因子为bfr = (B/R) = 1024/54 = 18 条记录每磁盘块。容纳这个索引表总共需要的磁盘块为N = (r/bfr) = 5000000/18 = 277,778 块。
现在使用FirstName字段来进行搜索就可以利用索引来提高性能。这允许使用一个二分查找,平均log2 (277778) = 18.08 -> 19次数据块访问。找到实际记录的地址,这需要进一步的块读取,这样总数达到19 + 1 = 20次数据块访问,这和非索引表的数据块访问次数有天壤之别。
什么时候使用索引(When should it be used?)
鉴于创建索引需要额外的磁盘空间(上面的例子需要额外的277778个磁盘块),以及太多的索引会导致文件系统大小限制所产生的问题,所以对哪些字段建立索引,什么情况下使用索引,需要审慎考虑。
由于索引只是用来加速数据查询,那么显然对只是用来输出的字段建立索引会浪费磁盘空间以及发生插入、删除操作时的处理时间,所以这种情况下应该尽量避免。此外鉴于二分搜索的特性,数据的基数或独立性是很重要的。在基数为2的字段上建立索引,将把数据分割一半,而基数为1000则将返回大约1000条记录。低基数的二分查找效率将降低为一个线性排序,而且查询优化器可能会在基数小于记录数某个比例时(如30%)的情况下将避免使用索引而直接查询原表,所以这种情况下的索引浪费了空间。
面向流与面向缓冲
Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
红黑树, 二叉树
https://blog.csdn.net/yang_yulei/article/details/26066409
索引的工作原理
为什么需要索引(Why is it needed)?
当数据保存在磁盘类存储介质上时,它是作为数据块存放。这些数据块是被当作一个整体来访问的,这样可以保证操作的原子性。硬盘数据块存储结构类似于链表,都包含数据部分,以及一个指向下一个节点(或数据块)的指针,不需要连续存储。
记录集只能在某个关键字段上进行排序,所以如果需要在一个无序字段上进行搜索,就要执行一个线性搜索(Linear Search)的过程,平均需要访问N/2的数据块,N是表所占据的数据块数目。如果这个字段是一个非主键字段(也就是说,不包含唯一的访问入口),那么需要在N个数据块上搜索整个表格空间。
但是对于一个有序字段,可以运用二分查找(Binary Search),这样只要访问log2 (N)的数据块。这就是为什么性能能得到本质上的提高。
什么是索引(What is indexing)?
索引是对记录集的多个字段进行排序的方法。在一张表中为一个字段创建一个索引,将创建另外一个数据结构,包含字段数值以及指向相关记录的指针,然后对这个索引结构进行排序,允许在该数据上进行二分法排序。
副作用是索引需要额外的磁盘空间,对于MyISAM引擎而言,这些索引是被统一保存在一张表中的,这个文件将很快到达底层文件系统所能够支持的大小限制,如果很多字段都建立了索引的话。
索引如何工作(How does it work?)
首先,我们建立一个示范数据库表:
字段名 数据类型 大小
id (Primary key) Unsigned INT 4 bytes
firstName Char(50) 50 bytes
lastName Char(50) 50 bytes
emailAddress Char(100) 100 bytes
注意:使用char是为了指定准确的磁盘占用大小。这个示范数据库包含500万行,而且没有索引。我们将分析一些查询语句的性能,一个是使用主键id(有序)查询,一个是使用firstName(非关键无序字段)。
例1
我们的示范数据库有r=5,000,000条记录,每条记录长度R=204字节而且使用MyISAM引擎存储(默认数据块大小为B=1024字节),这张表的块因子(blocking factor)会是bfr = (B/R) = 1024/204 = 5 条记录每磁盘数据块。保存这张表所需要的磁盘块为N = (r/bfr) = 5000000/5 = 1,000,000 blocks。
在id字段上的线性搜索平均需要N/2 = 500,000块访问来找到一条记录假设id字段是查询关键值,不过既然id字段是有序的,可以执行一个二分查询,这样平均只需要访问log2 (1000000) = 19.93 = 20 个数据块。我们马上就看到了极大的提高。
现在firstName字段既不是有序的,无法执行二分搜索,数值也不具有唯一性,所以对这张表的查找必须到最后一个记录即全表扫描N = 1,000,000个数据块访问。这就是索引用来改进的地方。
假如索引记录只包含一个索引列以及一个指向原记录数据的指针,那么它显而易见会比原记录(多列)要小。所以索引本身所需要的磁盘块要更少,扫描数目也少。firstName索引表结构如下:
Field name Data type Size on disk
firstName Char(50) 50 bytes
(record pointer) Special 4 bytes
注意: MySQL里的指针按表大小的不同分别可能是 2, 3, 4 或 5 个字节。
例2
假设我们的数据库有r = 5,000,000 条记录,建立了一个长R = 54字节的索引,并且使用默认磁盘块大小为1,024字节。那么该索引的块因子为bfr = (B/R) = 1024/54 = 18 条记录每磁盘块。容纳这个索引表总共需要的磁盘块为N = (r/bfr) = 5000000/18 = 277,778 块。
现在使用FirstName字段来进行搜索就可以利用索引来提高性能。这允许使用一个二分查找,平均log2 (277778) = 18.08 -> 19次数据块访问。找到实际记录的地址,这需要进一步的块读取,这样总数达到19 + 1 = 20次数据块访问,这和非索引表的数据块访问次数有天壤之别。
什么时候使用索引(When should it be used?)
鉴于创建索引需要额外的磁盘空间(上面的例子需要额外的277778个磁盘块),以及太多的索引会导致文件系统大小限制所产生的问题,所以对哪些字段建立索引,什么情况下使用索引,需要审慎考虑。
由于索引只是用来加速数据查询,那么显然对只是用来输出的字段建立索引会浪费磁盘空间以及发生插入、删除操作时的处理时间,所以这种情况下应该尽量避免。此外鉴于二分搜索的特性,数据的基数或独立性是很重要的。在基数为2的字段上建立索引,将把数据分割一半,而基数为1000则将返回大约1000条记录。低基数的二分查找效率将降低为一个线性排序,而且查询优化器可能会在基数小于记录数某个比例时(如30%)的情况下将避免使用索引而直接查询原表,所以这种情况下的索引浪费了空间。
Java序列化机制和原理
答1:最直接的表现就是减轻数据库的压力。避免因为数据读取频繁或过大而影响数据库性能,降低程序宕机的可能性
答2:nginx常用做静态内容服务和代理服务器,直面外来请求转发给后面的应用服务。nginx本身也能做缓存,比如静态页面的缓存什么的。而tomcat是应用服务器,处理JAVA WEB程序功能等等 。你也可以这么理解,假设把用户的请求当做是一条河流,那么nginx就相当于一个水利工程,tomcat相当于一条条分流的支流,而redis 相当于支流旁边的一个个水库。 当你洪水来了,nginx根据你每条支流的承受力度分发不同的水流量,在确保程序正常运行的情况下,分发给每条支流(tomcat)不同的水流量。而redis相当于一个个支流的水库,存储水源,降低压力,让后面的水量平稳。
谈谈你对分布式的理解
答:个人理解:分布式就是把一个系统/业务 拆分成多个子系统/子业务 去协同处理,这个过程就叫分布式,
redis实现消息队列 比ActiveMQ要轻量
https://blog.csdn.net/jacman/article/details/51246449
java实战开发经验 播客分享 问答形式
https://ask.csdn.net/subjects/16?page=11
JVM和JC
说到GC,记住两点:1、GC是负责回收所有无任何引用对象的内存空间。 注意:垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身,2、GC回收机制的两种算法,a、引用计数法 b、可达性分析算法( 这里的可达性,大家可以看基础2 Java对象的什么周期),至于更详细的GC算法介绍,大家可
4、当数据表中A、B字段做了组合索引,那么单独使用A或单独使用B会有索引效果吗?(使用like查询如何有索引效果)
答:看A、B两字段做组合索引的时候,谁在前面,谁在后面,如果A在前,那么单独使用A会有索引效果,单独使用B则没有,反之亦然。同理,使用like模糊查询时,如果只是使用前面%,那么有索引效果,如果使用双%号匹配,那么则无索引效果
Object类的一些方法
protected Object clone()创建并返回此对象的一个副本。
boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
protected void finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
Class<?> getClass()返回此 Object 的运行时类。
int hashCode()返回该对象的哈希码值。
void notify()唤醒在此对象监视器上等待的单个线程。
void notifyAll()唤醒在此对象监视器上等待的所有线程。
String toString()返回该对象的字符串表示。
void wait()在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
void wait(long timeout)在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
void wait(long timeout, int nanos)在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
5、一条sql执行过长的时间,你如何优化,从哪些方面?
答:1、查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)
2、涉及链表的查询,是否能进行分表查询,单表查询之后的结果进行字段整合
3、如果以上两种都不能操作,非要链表查询,那么考虑对相对应的查询条件做索引。加快查询速度
4、针对数量大的表进行历史表分离(如交易流水表)
5、数据库主从分离,读写分离,降低读写针对同一表同时的压力,至于主从同步,mysql有自带的binlog实现 主从同步
6、explain分析sql语句,查看执行计划,分析索引是否用上,分析扫描行数等等
7、查看mysql执行日志,看看是否有其他方面的问题
个人理解:从根本上来说,查询慢是占用mysql内存比较多,那么可以从这方面去酌手考虑
设计模式有什么用?
个人观点
作为设计模式的忠实粉丝和推广人员,在正式学习设计模式之前,我结合多年的模式应用和教育培训经验与大家分享几点个人的看法,以作参考:
(1) 掌握设计模式并不是件很难的事情,关键在于多思考,多实践,不要听到人家说懂几个设计模式就很“牛”,只要用心学习,设计模式也就那么回事,你也可以很“牛”的,一定要有信心。
(2) 在学习每一个设计模式时至少应该掌握如下几点:这个设计模式的意图是什么,它要解决一个什么问题,什么时候可以使用它;它是如何解决的,掌握它的结构图,记住它的关键代码;能够想到至少两个它的应用实例,一个生活中的,一个软件中的;这个模式的优缺点是什么,在使用时要注意什么。当你能够回答上述所有问题时,恭喜你,你了解一个设计模式了,至于掌握它,那就在开发中去使用吧,用多了你自然就掌握了。
(3) “如果想体验一下运用模式的感觉,那么最好的方法就是运用它们”。正如在本章最开始所说的,设计模式是“内功心法”,它还是要与“实战招式”相结合才能够相得益彰。学习设计模式的目的在于应用,如果不懂如何使用一个设计模式,而只是学过,能够说出它的用途,绘制它的结构,充其量也只能说你了解这个模式,严格一点说:不会在开发中灵活运用一个模式基本上等于没学。所以一定要做到:少说多做。
(4) 千万不要滥用模式,不要试图在一个系统中用上所有的模式,也许有这样的系统,但至少目前我没有碰到过。每个模式都有自己的适用场景,不能为了使用模式而使用模式?【怎么理解,大家自己思考,】,滥用模式不如不用模式,因为滥用的结果得不到“艺术品”一样的软件,很有可能是一堆垃圾代码。
(5) 如果将设计模式比喻成“三十六计”,那么每一个模式都是一种计策,它为解决某一类问题而诞生,不管这个设计模式的难度如何,使用频率高不高,我建议大家都应该好好学学,多学一个模式也就意味着你多了“一计”,说不定什么时候一不小心就用上了,。因此,模式学习之路上要不怕困难,勇于挑战,有的模式虽然难一点,但反复琢磨,反复研读,应该还是能够征服的。
(6) 设计模式的“上乘”境界:“手中无模式,心中有模式”。模式使用的最高境界是你已经不知道具体某个设计模式的定义和结构了,但你会灵活自如地选择一种设计方案【其实就是某个设计模式】来解决某个问题,设计模式已经成为你开发技能的一部分,能够手到擒来,“内功”与“招式”已浑然一体,要达到这个境界并不是看完某本书或者开发一两个项目就能够实现的,它需要不断沉淀与积累,所以,对模式的学习不要急于求成。
(7) 最后一点来自GoF已故成员、我个人最尊敬和崇拜的软件工程大师之一John Vlissides的著作《设计模式沉思录》(Pattern Hatching Design Patterns Applied):模式从不保证任何东西,它不能保证你一定能够做出可复用的软件,提高你的生产率,更不能保证世界和平,。模式并不能替代人来完成软件系统的创造,它们只不过会给那些缺乏经验但却具备才能和创造力的人带来希望。
以上是关于面试题整理 有经验自己的语言的主要内容,如果未能解决你的问题,请参考以下文章
6年测试开发经验面试28K公司后,整理出这套高频面试题和答案
别整天“学妹/学弟”了,清华学姐花7天时间吐血整理软件测试面试100题,自我检测一下把~