一个面试官对面试问题的分析

IcyFenix 写道
linchao198401 写道
IcyFenix 写道
mogui258 写道
最后介绍一下自己的背景,在一间不大不小的上市软件公司担任平台架构师,有3年左右的面试官经验,工作主要方向是大规模企业级应用,参与过若干个亿元级的项目的底层架构工作。

3年面试经验,多少年工作经验??
总觉得楼主面试的这道面试题很难,10%的人能回答出都觉得很高了。
如果是10%,他们都又有多少年工作经验呢!
工作3年以下的应该很少有看 《深入jvm》 这本书的吧!



3年面试经验,多少年工作经验?? 
工作经验不好说,06年本科毕业,09年在职硕士毕业,但是本科没有毕业就已在公司工作的正式员工。

总觉得楼主面试的这道面试题很难,10%的人能回答出都觉得很高了。
确实,回答道第三点的,10%都不到,回答道第四点的几乎没有。

如果是10%,他们都又有多少年工作经验呢!
能回答道第三点的,应届生到工作10年的人都有。
工作经验某种程度上只能代表实践程度,应届生可能确实只能从书本上看来的,而社招应聘者可能是工作中、调优中用到时去学习的。天份与实践经验我都看重。

工作3年以下的应该很少有看 《深入jvm》 这本书的吧!
感觉论坛上好多人都看过。


楼主确实能力不错,工作四年,有这样的成就,而且平时的时间还去读研究生,可见对自己的人生有很好的规划,前途很好啊。

我工作五年了,可惜还发展的不好。

我最近在看数据库的知识。
我能随便问你些问题,然后你在不查资料的情况下,随便说说嘛?

因为我用的比较多的是MySQL和Oracle。
请问你这两个数据库熟悉吗?
知道事务吗?
事务有哪些隔离性?
事务的并发是怎么实现的?一般有几种你知道的实现方式?
你知道数据库的锁吗,有哪些锁类型,对于MySQL不同的引擎有哪些不同的锁机制。例如什么引擎有什么样的锁?

Oracle有哪些类型的锁?为什么说Oracle里面没有锁升级的概念?为什么MySQL里面需要锁升级?
Oracle和MySQL都用多版本并发控制也就Multi Versioning Concurrency Control。MVCC。能知道他是怎么样的一个机制吗?有什么样的好处?
对于不同的隔离性,哪些是可以使用MVCC,哪些是不能使用?

知道Latch,也就是闩,Oracle什么时候会用到呢?

为什么说有些数据库的锁加的越多,需要升级锁,因为锁对于哪些数据库是一种宝贵的资源,而对于Oracle来说确不是这样。Oracle是怎么做到的?
跟Java里面的锁有什么相同和不同的地方?
Java的Synchronized和Compare And Set有什么不同吗?什么时候会用Compare And Set,Java JDK里面有实现吗?
对于锁资源的管理来说,锁管理是怎么样的一个实现呢。是队列吗,是Hash吗?如果让你实现你会怎么实现?

我记得Java分配对象的时候也需要有某种锁,所以对于每个线程会预先提供一些内存空间,因为是线程内的,所以就不会和多线程竞争内存空间,你觉得我说的对吗?你有了解,能更清晰的解释这个机制吗?

期待你的解答。
同时我也可以多学点锁和同步并发,以及里面的实现等问题。
为以后的面试做准备。


已看到,现在下班,回家就回答一下,不GOOGLE。

公司有数据库组,所以数据库实在说不上擅长,很多题目都被问倒了@_@

------------------------------------------

我写完了,编译一下这楼,觉得自己回答得有点失败。

因为我用的比较多的是MySQL和Oracle。
请问你这两个数据库熟悉吗?

公司用Oracle,我自己做点小东西的时候比较乐意选择SQLite,MySQL没有用过,我只回答Oracle的吧。

知道事务吗?
呃,如果只是定义为知道而不是什么擅长、精通的话……我想应该能叫知道吧

事务有哪些隔离性?
串行、可重复读、读取已提交数据、读取未提交数据

事务的并发是怎么实现的?一般有几种你知道的实现方式?
是问乐观、悲观锁定吗?
实现方式一般是两种,一种是锁,一种MVCC。乐观锁其实不是数据库的实现之一,只是UPDATE的过程中发现WHERE原来的字段的值已经不存在了,然后UPDATE的更新条目为0,你的程序或者框架如果发现是0就会报错或者抛运行时异常。



你知道数据库的锁吗,有哪些锁类型,对于MySQL不同的引擎有哪些不同的锁机制。例如什么引擎有什么样的锁?
性质上来讲,共享和排他锁,范围上来讲,数据库级(SQLite只提供这个范围的锁)、表、行,也有称表级锁为DDL锁,行级为DML锁,Oracle里面根据性质和范围,组合成……呃TM、SX之类的几种锁,具体就不记得了。这个回答我知道不太准确@_@
我也记得不是很清楚,首先Oracle里面据说没有共享锁,只要你想要SELECT东西都是能SELECT得到的。锁分成TX,事务锁,TM所以,和DDL。TX就是事务的时候加锁,加锁的位置是在行的数据头里面,例如置1,这样其他事务如果要更改这一行会发现这个已经是1了,你只能等待。TM锁是当你要修改某行的数据,你需要在表的头加个锁,这个锁不允许其他DDL语句把整个表的结构改掉,例如删除列或者添加列。DDL锁是你在删除列或者添加列等其他操作的时候加的,这个锁可以保证其他DDL的操作等待。Oracle里面还有个Latch,也就是非常轻量级的锁,这个锁在共享池中使用,共享池会放编译解析过的SQL语句或者片段,所以设计添加和查询删除的操作,而且因为是共享的,所以需要有锁,这个锁是很轻量级的,你程序员是不能控制的,如果使用不当,锁会生成很多。例如如果你使用的是JDBC里面的Statement而不是PrepareStatement,就不能重用共享池里面的SQL语句。例如SELECT * FROM user WHERE userId=i。以及SELECT * FROM user WHERE userId= :id。第一个语句每次都发送拼出来的SQL语句,Oracle每次都需要进行解析,解析是很费CPU的。如果把每次解析的SQL放入共享池,因为整个数据库要共享的,所以Latch就会很多。

Oracle有哪些类型的锁?为什么说Oracle里面没有锁升级的概念?为什么MySQL里面需要锁升级?
当锁定数据过于密集,将会将锁升级一个范围级别。譬如一张表被一个链接锁定的行太多,将可能升级为表锁,这时候大粒度的锁定反而更加有效率。Oracle为什么没有锁升级这个答不上来……
Oracle没有锁升级一说,因为Oracle的锁是放到行的数据头里面,就如Java的对象的头里面有个锁的字节,Java里面也没有锁升级吧。MySQL需要锁升级是因为使用的是锁管理器。这个管理器会处理每次的锁请求,如果请求到来之后会在锁表里面搜索这个记录行的地址,就像HashMap一样,如果找不到这一行,那么就把这一行加上,如果表示这一行已经有事务加锁了。如果找到了这一行表示其他事务正在加锁,那么就把当前的事务加入到等锁的队列Queue里面,等待锁。所以如果请求的锁很多,事务又很多,整个锁管理器会耗费很多的内存来管理行地址和事务等待队列。如果你升级锁的粒度,那么使用的锁对象和事务等待队列就会小点的。但是仍然不是很好的扩展性。


Oracle和MySQL都用多版本并发控制也就Multi Versioning Concurrency Control。MVCC。能知道他是怎么样的一个机制吗?有什么样的好处?
对于不同的隔离性,哪些是可以使用MVCC,哪些是不能使用?
回答不上来……

知道Latch,也就是闩,Oracle什么时候会用到呢?
我只知道是比锁更小的锁钉单位,具体在数据库中的使用过程真的不了解。

为什么说有些数据库的锁加的越多,需要升级锁,因为锁对于哪些数据库是一种宝贵的资源,而对于Oracle来说确不是这样。Oracle是怎么做到的?
同上面问过的……不知道

跟Java里面的锁有什么相同和不同的地方?
Java的Synchronized和Compare And Set有什么不同吗?什么时候会用Compare And Set,Java JDK里面有实现吗?
终于熬到Java了,上面数据库太打击人,我决定明天拿去数据库组给他们耍一下。
Java并发我还好曾经给在部门做过这个培训,这方面擅长一些,同步是基于临界区互斥检测的,CAS是依赖系统本身保证比较-设置这个操作的原子性。JDK5之后提供了java.util.concurrent包,里面的原子int、原子long等就是基于CAS实现。
并没有一定必须使用CAS才能完成的场景,使用CAS的最大理由是基于性能考虑,但是有很多一定需要使用Synchronized才能完成的场景,譬如最简单的你要使用object.wait/notify。
跟我理解的差不多,其实操作系统里面已经有CAS的实现,只需要一条CPU原语就可以了,CPU比较内存地址中的值是否是compare的值,如果是就把那个值复制到寄存器,然后内存中的值设置成true,如果这个时候有其他线程,那么会发现内存为true,因为是原语,所以CPU那时候肯定只有执行一个语句,也就是CAS,其他线程没有办法中断,然后切换线程。对于多核的CPU应该也是一样,没有具体的了解过。因为只是一个CPU的原语,所以肯定是比同步速度快,但是也是有缺陷的,就是只能同步的更新内存位置上的值。所以对于不管是更新int,long还是reference一样。
CAS在JDK里面的实现是AtomicInteger等等的。

对于锁资源的管理来说,锁管理是怎么样的一个实现呢。是队列吗,是Hash吗?如果让你实现你会怎么实现?
不好意思,这个问能否描述得更清楚一些,锁资源管理是指?

我记得Java分配对象的时候也需要有某种锁,所以对于每个线程会预先提供一些内存空间,因为是线程内的,所以就不会和多线程竞争内存空间,你觉得我说的对吗?你有了解,能更清晰的解释这个机制吗?
我的观点是与你有较大差别:除非强制指定了volatile,不然多线程中各个线程对变量的操作并不会直接竞争同一块内存空间,线程有自己的工作内存作为主内存中与此线程相关对象的复制品,线程中的操作都相对于工作内存而言,数据的修改只有在工作内从中修改然后同步回主内存后,才能被各个线程共享。而Java中基于性能考虑,修改与刷新回主内存并不保证严格顺序,所以才会有单例DCL失败这样的事情,关于这个在我javaeye的博客上,去年写的单例模式有过相关的叙述:)
首先,我问的这个问题是发生在分配内存,也就是NEW的时候,你说的volatile如果没有读和取的话是不会需要这个的,你说的工作栈我也知道,但是这个是执行方法的时候才有的。对于NEW这个简单的动作,首先不需要用到volatile,然后不需要用到工作栈,而且创建的对象是不会放到栈里面的,栈只能放int,long等原型类型,对于对象只能放置reference。只要是NEW就会有竞争,多个线程NEW一个内存为什么会没有竞争呢?


期待你的解答。
同时我也可以多学点锁和同步并发,以及里面的实现等问题。
为以后的面试做准备。

也谢谢你的问题,Java部分我们可以继续交流,数据库部分我真的受打击了,握手。

其实数据库的问题主要还是集中在事务和锁上面,这些对于数据库的调优,完整性都是很重要的。

你可能感兴趣的:(多线程,oracle,工作,mysql,面试)