首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > oracle >

杭州阿里巴巴第二轮电话面试,被BS好几回,特留此贴以及有关问题,请大家指点

2012-02-14 
杭州阿里巴巴第二轮电话面试,被BS好几回,特留此贴以及问题,请大家指点!大家还记得我8天前发的阿里巴巴一面

杭州阿里巴巴第二轮电话面试,被BS好几回,特留此贴以及问题,请大家指点!
大家还记得我8天前发的阿里巴巴一面的帖子吗?过去了一个星期了,我以为事情已经黄了,所以就再也没有做相关准备,结果今天阿里巴巴第二轮笔试电话突然而至,搞的我措手不及啊!

1,如果有row_number() 分析函数,如果我有一张学生表student,里面有班级、学生名、分数,排名我想得到如下数据,该如何用row_number() 排序写一条sql获取,不能用union all来连接获取。
--班级、学生名、分数,排名
  一班 李一 100 1
  一班 李二 100 1
  一班 李三 100 1
  一班 李四 100 4
  一班 李五 99 5
  一班 李六 98 6
.......-- 一班很多学生,依次排下去。
  二班 王一 100 1
  二班 王二 100 1
  二班 王三 99 3
  二班 王四 98 4
  二班 王五 80 5
...... 二班有很多学生,依次排下去。

我的答案是:select banji,name,score,row_number() over(order by banji, name,score desc)。结果他说不对,最近在做sqlserver开发,可能长时间没有碰oracle了,所以导致当时一下没有想出来,被严重BS了,事后仔细一想,其实很简单的,我以前还写过类似的sql,只是时间长了,忘记了,呵呵,不知道大家知道怎么写了么?

2,有关优化的事情,A表500万数据,B表2亿条数据。A与B的数据结构相同,select count(*) from A,B where A.id=B.id。问下,这条sql很耗时,如何优化这条sql,使之效率最高。

我答案,看执行计划,是否走索引,不走的话,就重建所以,他说,如果索引都是完好无损的,而且2亿条数据走索引时优化不过来的,问我还有别的方式来优化这条sql不?我一时就答不出来了,因为sql很简单了,不知道如何优化了,而且我们的oracle库也没有类似的查询,所以一下想不出来怎么回答,结果又被BS了。

3,数据仓库里面,如果你根据客户的需求写完了sql,取到了数据,你如何保证这些数据时准确的呢?

我回答,1,根据需求写一些测试sql来验证,比如数据总量,主要字段,主要信息,抽取几条验证。
  2,找客户,跳一些数据来验证。
结果他反问我这些方法是我自己想出来的吗?我说是的,我感觉我的回答不太对,有点不妙。

还有一些我回答正确的问题,比如管理方面的,我就答的不错,我就不列出来了。反正今天在引以为强项的sql编写与优化上面被问到了,证明我的oracle开发基本功还是很差的,以后要加强这方面的练习了。

欢迎大家对上面的3个问题,发表下自己的看法,在此先行谢过!




 

[解决办法]
我也想知道答案
[解决办法]
LZ,我面试的是一家阿里巴巴的外包公司,也是阿里巴巴的人面试我的,问题跟你差不多啊!!

rownum_over这个没问,第二个问题我是分三个方面回答的,分区、并行、索引,感觉索引这方面回答得有问题,被bs了,不过还是拿到offer了。
阿里巴巴的HR面试水平还是很高的,这种开放式的问题比那种问你知道decode函数什么意思吗之类的SB问题有水平多了。
[解决办法]
先谢谢楼主无私!

SQL code
--1.with student as(  select '一班' class,'李一' name, 100 score from dual union all  select '一班' class,'李二' name, 100 score from dual union all  select '一班' class,'李三' name, 100 score from dual union all  select '一班' class,'李四' name, 100 score from dual union all  select '一班' class,'李五' name, 99  score from dual union all  select '一班' class,'李六' name, 98  score from dual union all  select '二班' class,'王一' name, 100 score from dual union all    select '二班' class,'王二' name, 100 score from dual union all  select '二班' class,'王三' name, 99  score from dual union all  select '二班' class,'王四' name, 98  score from dual union all  select '二班' class,'王五' name, 80  score from dual),  tt as(    SELECT t.*, row_number() over(PARTITION BY CLASS ORDER BY score DESC) rn FROM student t)  SELECT a.class, a.name, a.score, b.mrn    FROM tt a, (SELECT CLASS, score, MIN(rn) mrn FROM tt GROUP BY CLASS, score) b   WHERE a.class = b.class AND         a.score = b.score;--2.先用集合运算不知效率怎样SELECT COUNT(*)  FROM (SELECT *          FROM a        INTERSECT        SELECT * FROM b);
[解决办法]
1:直接用DENSE_RANK()函数不是更好?
2:select count(*) from A,B where A.id=B.id。没有执行计划,没有表结构,我的水平还没有到这个程度。。。难道用EXIST做?
3:总数量验证,SQL语句的WHERE条件审查,数据仓库分析结果验证,感觉就这样了,简单的验证。。。。
[解决办法]
1:我觉得用rank()比较好实现排名,不知道row_number()怎么实现这种排名
2:首先从表连接方式,然后分区、并行
3;不知道,我只能说,我在分析需求时,会尽量把问题澄清,不知道此处强调数据仓库,有什么意思

期待高人给出解释
[解决办法]
我也来看看:

1.一班 李一 100 1
一班 李二 100 1
一班 李三 100 1
一班 李四 100 4 (数据有误?这是为啥是4?)

2.select count(*) from A,B where A.id=B.id
这个语句就写法上来说,是最简洁的。
1)假如是OLAP之类的系统,可以使用位图索引(传说中位图索引对COUNT这种运算相当地快)
2) OLTP,2张表都得有索引,fast full scan 2个表的索引再hash join(其中A为驱动表), 速度应该是OK的了。


3)不怕BUG的话,可以开启parellel, 并行查询速度肯定会快些
4)涉及一些参数的优化,比如在fast full scan索引时,db_file_multiblock_read_count参数的影响(这个参数在扫索引时会不会有用,不确定。

3. 数据稽核。 楼主回答的已经很OK了,好像我差这多是这样单元测试的。我一般会构造一小部分数据,执行SQL, 验查取出来的数据。

[解决办法]
1.
select 班级,学生名,分数,排名
from student a
order by 班级,分数,学生名

2. select count(*) from B,A where B.id=A.id

3. 只能多测试了。


[解决办法]
楼主你这面的什么职位啊
[解决办法]
2 select count(*) from A where exist (select 1 from B where A.id=B.id)
[解决办法]
2、用count(1)代替count(*),在大数据量时,count(1)比count(*)效率要高N倍。实际开发中一般都不允许出现count(*)这样的出现。
正解:select count(1) from A,B where A.id=B.id

[解决办法]
LS的,count(1)比count(*)效率要高N倍,能够验证一下吗?只听过count索引字段会比较快,但是count(1)和count(*)貌似没有大的区别。
[解决办法]

探讨

LS的,count(1)比count(*)效率要高N倍,能够验证一下吗?只听过count索引字段会比较快,但是count(1)和count(*)貌似没有大的区别。

[解决办法]
探讨
LS的,count(1)比count(*)效率要高N倍,能够验证一下吗?只听过count索引字段会比较快,但是count(1)和count(*)貌似没有大的区别。

[解决办法]
count(*)与count(1)效率的区别老早前就有人争论过了
从逻辑上来讲是没有什么差别的
[解决办法]
count(1)本来就比count(*)快,我都试过N次了,还要验证?
[解决办法]
1、题目要求,需要用row_number()来做,那么看下这样写如何,题目意思应该是要获取每个班级前三名,包含并列份数人数:
SELECT banji,name,score FROM (
 SELECT banji,name,score,row_number() OVER(PARTITION BY banji ORDER BY score DESC) RN
FROM student
)
WHERE RN < 4;

2、因为需要统计数量,所以两个表的关联信息需要全部创建,这弄不好会把机器弄死掉,这个需要用分区了。分区内部需要有对应的分区索引了,最好逐个分区统计完后到中间数据,然后通过中间数据进行二次统计比较好,我这也没有那么大的数据量,所以测试出来的结果未必正确,刚才用了一个几十万关联几百万的表,直接关联的确容易死掉,我改了一种写法可以迅速出来,你也可以试一试:
SELECT SUM(
SELECT COUNT(t2.id)
FROM B t2
WHERE t2.id = t1.id

FROM A t1;
此SQL仅仅提供参考,你可以用几千万的数据试一试(我用的是一张几十万关联一张几百万的),我测试的数据量不太大,因为我本地的磁盘的确不够花了,呵呵,不过用关联COUNT的话,我机器基本快死掉了,两分钟还没有出来,最终关掉执行窗口,用这个SQL是400毫秒内提取结果的,这个SQL是根据A的id去获取B的对应数量,然后将这些数量进行SUM操作。。。。

3、关于数据仓库数据正确性验证,我想最重要的就是测试,呵呵,我个人有些自己的意见吧:
3.1、首先是代码逻辑的走吧,往往自己的逻辑自己写的时候不能发现,绕进去了不知道,所以一般我自己写的核心代码或统计算法需要检查三次以上。
3.2、从小数据量开始测试,不一定开始就要要用大数据量测试,因为那样即使有一两个对的,也不一定整体是正确的。
3.3、按照逻辑处理顺序绘制逻辑轨迹图形,按照各类轨迹制作跟踪数据,不一定要很多,注意空值的特殊情况以及数据类型的隐式转换,每条轨迹至少要有两三组不同代表性的测试数据进行测试。
3.4、利用客户的实际应用数据进行测试,历史信息的统计和现有统计的对比并追踪问题的处理细节过程。

须保证正确性,在设计上需要清晰算法的逻辑过程,该抽象的就将逻辑抽象,不要复杂化问题,在非常非常复杂的运算中,如果能抽象出数学算法模型来设计那是最好的。这些算法逻辑最好有一些文档或者纸张记录,并用以自己分析BUG所在以及提供给测试时路径分析参考。


至于讨论得很沸沸扬扬的COUNT(1)快还是COUNT(*)怎么样的,我认为看下执行计划是否一致就OK了,呵呵,从我的角度来说,在ORACLE数据库吧,绝大部分情况下COUNT(1)和COUNT(*)一致,不过不论怎么样,我习惯的还是用COUNT(索引字段),最好这个索引字段在WHERE上用过。
[解决办法]
补充下,第一个题目看错意思了,你是要降序排列下去,并且实现并列值同下标,下一个小标实现跳跃,这样排序下去?你要用row_number()我还真不知道怎么写呢,因为这个函数写出来的下标是不重复的,完全在分组内按照递增顺序生成出来,我要写的话,我就用:RANK(),实现并列排名并跳跃下标:
SELECT banji,name,score,RANK() OVER(PARTITION BY banji ORDER BY score DESC) RN
FROM student;

[解决办法]
我来解释一下第二个问题,大家看看对不对。
该sql最起码有两个地方需要优化,第一:count(*)需要使用count(1),因为数据量比较大,使用*会非常占内存。第二:select count(*) from A,B where A.id=B.id,大家知道对于oracle对于表解析是从又向左解析,where语句是从下往上解析,所以我们在表链接的时候要把小表放在右边,大表放左边,where条件是索引的放下边。所以综上上面的可以改成select count(1) from B,A where B.id=A.id


[解决办法]
1.用rank,用row_number多余
2.要改写sql,两个大表还是用exists试试,然后count(*)改为count(主键),必要的时候加上并行之类的东西,可能的话最好分区
3.测试呗,根据测试规范来
[解决办法]
感谢楼主的分享啊。。。我以前有个同事去了阿里巴巴,好像笔试面试都没有这么难哦。。。

汗。。。看了下上面的问题,我也基本上回答不出来啊。。。希望前辈们多来指点,同时也非常感谢楼主的无私分享
[解决办法]

探讨
1、题目要求,需要用row_number()来做,那么看下这样写如何,题目意思应该是要获取每个班级前三名,包含并列份数人数:
SELECT banji,name,score FROM (
SELECT banji,name,score,row_number() OVER(PARTITION BY banji ORDER BY score DESC) RN
FROM student
)……

[解决办法]
第二的问题A,B表换一下位置吧。
[解决办法]

第二题用位图连接索引是不是好一些?
当然,还是得拿执行计划说话
[解决办法]
第一题明显要用dense_rank(),找不到必须用row_number()的理由
[解决办法]
探讨
引用:
引用:
1、题目要求,需要用row_number()来做,那么看下这样写如何,题目意思应该是要获取每个班级前三名,包含并列份数人数:
SELECT banji,name,score FROM (
SELECT banji,name,score,row_number() OVER(PARTITION BY ban……

[解决办法]
第一题我觉得大家想多了吧,就是要按班级跟名次排序而已
select banji,name,score,mingci from 
(
select banji,name,score,row_number() mingci from student
) order by banji,mingci
[解决办法]
2,有关优化的事情,A表500万数据,B表2亿条数据。A与B的数据结构相同,select count(*) from A,B where A.id=B.id。问下,这条sql很耗时,如何优化这条sql,使之效率最高。


count(1) 此处可优化。。然后表解析。先解析右边表。B.ID=A.ID就行了。。你想你是解析2E数据的表快,还是解析500W数据的表快

热点排行