几个面试题

Wayne posted @ Wed, 15 Jun 2011 14:07:50 +0000 in Experience , 3102 readers

本来今天去面试动机就不纯,基本只是为了积累经验锻炼队伍去的,所以答得怎么样都无所谓了。不过第一眼看到笔试卷的时候,还是很庆幸:遇到简单题了。想象中的关于数据库各种机制的深刻挖掘基本没有,一些复杂类型的复杂用法也没有。总共12道题目,做完后感觉良好,有80%把握能对,不过现在回想一下,还是有不少题目答错了,或者答得不够好。

这笔试卷上来是几道我事后查了一下所谓的华为的面试题。

题:什么是事务?

这个要说我不知道什么是事务那真叫冤枉。但让我写,我却想不起来怎么个写法。最后只能走曲线,表示一次rollback/commit/rollback to savepoint到一次rollback/commit/rollback to savepoint 之间的那部分就是一个事务。事后查了下,原来这题的得分点在ACID上…… 原子性,一致性,隔离性,持久性。

 

题:游标的作用是什么?SQL游标的属性有哪些?如何知道游标走到底了?

游标我经常在用,但这里它说的作用我没想明白怎么写,最后只好写个“可以用来缓存数据”。刚刚查了下,标准答案是“用来指向结果集的某一行”,这答案让我感觉是废话。SQL游标,我想它应该是指隐式的那些吧,属性有4个,SQL%FOUND, SQL%NOTFOUND, SQL%ROWCOUNT, 还有一个我一下子没想起来的 SQL%ISOPEN。然后后面的如何知道游标走到底了就让我头疼了……前面都在问SQL游标,但这种隐式的游标要么直接用来赋值,要么在for循环里用,走没走到底不用我关心啊。最后不得已,只好写个等出现SQL%NOTFOUND就是走到底了。实际上,这个是会抛出个exception的,除非显式声明的游标,那可以放心用 cursor_name%NOTFOUND。

 

题:事前触发和事后触发有啥区别?语句级触发和行级触发有啥区别?

这题我应该是答错了。我的答案是事前事后触发在old和new的使用上会有些不同,语句级和行级触发在外观上行级有个for each row,然后语句级可能加的锁跟行级有点区别。标准答案是:事前触发在事前发生,事后触发在事后发生,事前触发可以得到新旧值。语句级触发在语句执行的前后发生,行级触发在单行记录变动时发生。----------这答案看得我很郁闷,这尼玛的都是废话啊!!

 

题:TRUNCATE 和 DELETE的区别

这题简单,不过可能用意在看答得全不全?我写了三点,网上标准答案是5点,但是在我看来,多出来的那两点纯粹是废话。什么truncate不会触发delete的触发器……这要触发了才扯蛋啊,名字都不一样……

 

题:存储过程和函数的区别

这题我答得比网上的标准答案好多了,不过没啥可说的。

 

====== 以上是网上流传的华为面试题 ======

题:一个写语句的题目,大意上就是让我用NOT IN, NOT EXISTS, 外联接 分别实现同一个功能,找出一张表里某字段在另一张表里没有值的那些记录,然后说哪个写法最好。

语句我自然都写对了,轻而易举。唯一的问题是,这所谓的“外联接”是个什么东西?outer join?不管是左还是右还是全外连接,都达不到效果的,只能用inner join或者nature join的啊。最后我自然没理这事情,按nature join写了。在分析哪个写法好时,我犯了个错误,居然无视了“NOT IN"里面的"NOT” !! 表面上看,它是在考你exists和in之间的效率,实际上它还挖了个坑,在考你索引的使用条件。当然,题目出的也不好,它压根就没说这上面有没有索引。如果没索引的话,多数情况还是NOT IN来得快。但是我的分析理由就彻底错了。我提出的理由是NOT IN 后面的那个子查询的表结果集 显然比前面的要小。大表嵌小表,用IN快,基本是这么个意思。可惜这个理论成立的前提是IN,而不是NOT IN。有索引的情况下,not exists能利用起来,而not in用不到,速度就被落下了。不过我也留了一手,在最后还加了句:实际中要看优化器给出的执行计划才能知道哪个快。这句很重要!至少我这么认为!!查询结果的数目大小,以及数据库可用的内存情况等等因素都会直接影响最终执行效率的,并没有铁定的事情。在这个问题上,事后做了番功课,收获不少,HASH JOIN和NEST LOOP两者之间的区别也算搞明白了。

 

题:写一个简单的存储过程,要求输出参数中至少有一个结果集。

这题是彻底做错了。问题出在“结果集”上。今天之前,我压根不知道“结果集”是个什么东西…… 书一直看的是英文,这下产生不良作用了…… 回来后查了一些提到“结果集”的资料,反复结合语境,终于灵光一闪,原来这尼玛的就是Result Set啊!!亏我还写了个collection,而且还写错了collection,作为一个nest table collection,使用的时候没有初始化……  只要一个REF CURSOR就能搞定的事情被弄得这么麻烦……

 

题:一个写语句的题目,给出三条一模一样的记录,让我使用ROWID,从里面找出一条唯一记录,并更新某字段。

这题我没看懂。就算使用了ROWID,那记录还是记录啊,难道把ROWID当做列搞进去?但这样一来,三条都是唯一记录了,哪来的一条唯一记录…… 要么三条都是,要么三条都不是,怎么可能只更新一条嘛。

 

题:写一个找出上月数据的语句,数据库字段类型是date。

写出语句实现功能很简单,不过我写的丑了点。select * from xxx where ddd>=trunc(trunc(sysdate,'mm')-1,'mm') and ddd<trunc(sysdate,'mm')。 其实应该可以用ADD_MONTHS这个函数,只不过当时我忘记这函数具体怎么用了。现在想来应该可以写的稍微好看点:select * from xxx where ddd>=add_Months(trunc(sysdate,'mm'),-1) and ddd<trunc(sysdate,'mm')

 

题:Oracle和另一个什么数据库中,要输出一个NULL值为0,怎么写?

这个很简单了,就是nvl的用法。

 

==================

其他的题目想不起来了。总的来说,这次的题目确实相当简单和基础。没有分析函数,没有connect,没有复杂的管理类语句,没有提到SQL优化……就连Record和Collection也没有,更不说Ojbect了。不过基础题也有不少可挖掘的地方。仔细深究下去,也很有收获。积累点经验果然大有好处。

明天的那场难度会怎样呢?

 


Login *


loading captcha image...
(type the code from the image)
or Ctrl+Enter