思考过后方可断言
前言
前阵子去应聘了,总体来说还是挺愉快的。整个过程是:对方在招聘网站找到我的资料,然后打电话约我面试。抱着去结交一些技术人员的心态,我没啥准备就去了。首先是做了份试题, 然后是技术主管面试,最后是人事部经理面试。忘记说对方招的是Asp.net程序员。
没啥准备直接乘几个小时的车就过去了。
“试题”——试题感觉像是公司里一群人每个人拼凑几道题弄成的,不是难,就是太过细节,不大喜欢,都是些奇怪的偏门的细节 如: "IL 里 构造函数 的关键字,“ 还有一些 SQL(竟然是 SC、C、 S, 郁闷,什么命名!刚从学校学完SQL毕业吗?而且题目明显犯了把业务放到SQL 语句里的错误。后来和他们的技术主管面试时,得知他们业务其实是用ORM !?)。
面试
答题后就和他们的技术主管面试了。面试过程中有一个问题,他们的技术主管说:”看你的项目经验里有不少android的,好像没用C#“,我当时真后悔没自己打印一份过来,他们从网上拉的是旧的(标着51job)简历,我没有把以前的项目经验写上去。我赶紧回答一句:”这些android的服务器端都是C# 实现的“。
一道简单问题
”我还是不能确定你C# 的程度,这样吧做一道C#问题?”
“ 给定一个日期,给出它所在星期的星期一的日期“。
当他说做一道C#问题时我心里还是有几分害怕的,C#可运用场景那么多,在这么短的时间里,又没有机器纯口头,做不出什么东西来。这道题其实完全可以不用C# 来做。。(有点怀念 ACM/ICPC的日子了,那时候应付这种题目小Case)
我大致想了一下,记得DateTime 里有一个DayOfweek 的属性,然后说 大致算法应该是 拿日期减去这个数(DayOfweek)然后加1。
技术主管突然问:“为什么要加1”,楞了一下,我认为这是理所当然的,1到3的顺序标号是3 但是距离是2,我需要减的是距离不是标号,减多了就加回来。
“你的不对,其实正确算法应该是这样的: 利用7为周期循环 减去××然后再××”,技术主管靠在椅背上这样轻松的说着(请原谅我真的记不住他的说的了,我满脑子都是自己算法的实现,和自己的算法是否正确,有哪些漏洞)。
我没办法反驳,因为我没有验证,甚至连一个单元测试也没写,而且我相信他给出的算法肯定也是对的,(如此自信的表情,应该是最近遇到过类似的问题)
但是我顺序倒推的算法就错误了吗? 当中有什么陷阱我没有发觉?(我写出一个实现,也请大家拍砖)。
我可以肯定的是这位主管没有思考我我的算法。
扭转
主管似乎还想继续给我机会,翻了一下简历和我答的面试题, 问道“说一下委托”。我当时觉得没啥希望了,就想随便把自己想到得都说出来。从Java 的接口开始说起,但对方似乎不愿意听,于是赶紧转来说:“在C角度来看,它就像函数指针,但是C#的委更安全”。
“好的 不错 OK”
我本来还想继续扯“Java上观察者模式的实现 和C# 观察者模式的实现的不同,C# 观察者模式里的推与拉”。 结果就这样被打断了,有点意外。
人事部
然后就是等着人事主管面谈,谈的还算愉快。
“你看起来和一些技术人不同,没那么木纳,而且技术面也挺广的,c# Java 都懂”。
“我也是技术人,我也挺木纳,学Java就是想对比着看待C# ,这样能更好的深入学习”。
题外话:.net 确实非常不错,C#也很优秀,博客园里的技术也是.net为主,但是大家去看看另一门的语言也会有很大的收获的,另一门语言我指的不是“Java” 这种类似于C# 的,而是 python 、 Lisp等等这一类设计思想完全不同的的语言。
结果
其实我和人事主管没有谈拢,在期薪上他重复的说着:“试用期给你××,转正后×× 和期薪差一些,但是表现好的话半年可以有,回去等我们的联系吧”。我知道我的期薪超过他们预期,他们应该是保持观望的态度,看看还有没有更合适的人选。
我的算法的一个实现
首先是单元测试
[TestMethod] public void TestGeneral() { DateTime actual = MondayDate.GetTheDate(new DateTime(2012, 6, 22)); DateTime expected = new DateTime(2012, 6, 18); Assert.AreEqual(expected.Date, actual.Date); } [TestMethod] public void TestSameTime() { DateTime actual = MondayDate.GetTheDate(new DateTime(2012,6,25)); DateTime expected=new DateTime(2012,6,25); Assert.AreEqual(expected.Date, actual.Date); } [TestMethod] public void TestSaturday() { DateTime actual = MondayDate.GetTheDate(new DateTime(2012, 6, 30)); DateTime expected = new DateTime(2012, 6, 25); Assert.AreEqual(expected.Date, actual.Date); } [TestMethod] public void TestSundayTime() { DateTime actual = MondayDate.GetTheDate(new DateTime(2012, 6, 24)); DateTime expected = new DateTime(2012, 6, 25); Assert.AreEqual(expected.Date, actual.Date); } [TestMethod] public void TestBetweenMonth() { DateTime actual = MondayDate.GetTheDate(new DateTime(2012, 6, 1)); DateTime expected = new DateTime(2012, 5, 28); Assert.AreEqual(expected.Date, actual.Date); } [TestMethod] public void TestBetweenYear() { DateTime actual = MondayDate.GetTheDate(new DateTime(2011, 1, 1)); DateTime expected = new DateTime(2010, 12, 27); Assert.AreEqual(expected.Date, actual.Date); }
主要类:
public class MondayDate { public static DateTime GetTheDate(DateTime dateTime) { int week = (int)dateTime.DayOfWeek; TimeSpan span = new TimeSpan(week - 1, 0, 0, 0); var mondayDate = dateTime.Subtract(span); return mondayDate; } }
有问题的”归纳法推导“
假设 X为 给定的正确日期,且z (0~6) 为X所在星期的星期几 (一个星期有星期天开始 以0 表示,星期一为 1 二为 2以此类推),设y为x所在星期一的日期。
则假设 y=x-(z-1) 即 y=x-z+1;
一般情况(这个是我推导的缺陷)
[2012-6-25]=[2012-6-25]-1+1 (6.25 为星期一)
推导:
f(x+1)=(x+1)-(z+1)+1
f(x+1)=x-z+1;
__________________
从Z=1 开始分析:
当X为星期一时 z=1:
f(x)=x-1+1 => f(x)=x;
当X为星期二时,即X+1 而且z也会加1;
f(x+1)=(x+1)-(z+1)+1
=x-z+1 =>这和当x为星期一时是同一结果 即 f(x+1)=f(x);
......
当X为下一星期天时, 即X+6,而Z +6 (由于Z为 0~6 ,且我们是从1 开始的 此时Z的结果为0)
f(X+6)=(x+6)-(z+6)+1
=x+7, => 刚好为 下一个星期的星期一.
其他算法推广
做这道题时,顺便去看了看 推算日期是星期几的算法 (即DayOfWeek的算法),在维基百科上有了很详细的解释(可以看参考链接)。
最后抱怨一下
面试过人,也被面试。老实说如果身为面试官,我真做不到在面试时看出一个人的技术,面试很复杂,水很深。所有想到自己作为应聘者时,我都会在简历里附上自己 博客的地址,GitHub地址等。
但是这次面试的技术主管,很有可能就是当天 ,才拿到我的简历,明显的准备不足(查看一下我博客的目录也能看出,我对C#的掌握 远比Java好,也就不会出现那样的意味了)。
“博客园”大牛很多!虽然我自身不才,但赏个脸访问一下博客园,总会有收获的。
参考链接
http://zh.wikipedia.org/wiki/%E6%98%9F%E6%9C%9F%E7%9A%84%E8%A8%88%E7%AE%97