高级软件工程师面试问题 Interview SeniorSoftwareEngineers

hanselman这篇文章很有意思,尽管不是每个问题都很值得作为面试问题出现,但是很多都值得去仔细想想。

一个优秀的面试问题,尤其是针对Senior Engineer的面试问题,不应该仅仅是问某个api的用法,某个很容易从帮助中找到的内容。有发散性,可以基于问题进行扩展的问题才是一个比较好的问题。

下面是一个非常长的问题列表,主要是关于面向对象设计,设计模式,以及一些实际工程中会用到概念,都是比较基本的,但是也非常能考察一个高级工程师的水平,因为会牵涉到非常多方面。

另外要说明的是下面很多概念性问题可以直接从wiki维基百科上找到答案。另外我会标记出个人觉得比较值得问的问题。

原文在这里 http://www.hanselman.com/blog/NewInterviewQuestionsForSeniorSoftwareEngineers.aspx

# What is something substantive that you’ve done to improve as a developer in your career?

有没有做过什么比较实质性的事情来提升你的程序员职业水平?

好问题。我的回答:这个很难说,我的做法是坚持学习,坚持写技术类博客。另外有些经验在这里提到过http://sunxiunan.com/?p=1799

# Would you call yourself a craftsman (craftsperson) and what does that word mean to you?

不敢叫自己大师啊,那得多牛逼?!

# Implement a <basic data structure> using <some language> on <paper|whiteboard|notepad>.

用某种语言在纸面上实现一个基本的数据结构。(用近似真实格式的伪代码来表达?)

好问题。我的回答,找一本基础的数据结构书籍吧,比如这一本《数据结构与算法分析:C语言描述(原书第2版)》

# What is SOLID?

参考http://en.wikipedia.org/wiki/Solid_%28object-oriented_design%29

这个solid不是说“结实的”,而是面向对象五大原则的简称:单一责任原则,开闭原则,莱西科夫替换原则,接口分离原则,依赖倒置原则。

好问题。这几个原则的确应该背下来,太基础了。

# Why is the Single Responsibility Principle important?

为什么单一责任原则重要?

好问题。我的回答,因为职责明确,设计就不容易混乱,即使有后续变化也是可控的。

# What is Inversion of Control? How does that relate to dependency injection?

参考http://en.wikipedia.org/wiki/Inversion_of_control

实际中的例子,通知开会,一种可以打电话通知到每个人(这属于中心控制型的,必须有个controller/manager之类的);也可张贴一个告示,大家自己来看,这属于事件响应型的。

# How does a 3 tier application differ from a 2 tier one?

三层应用与两层应用的区别是什么?

我只知道MVC三层应用。

# Why are interfaces important?

为什么接口重要?

好问题。接口的重要在于消费者(客户端)不需要了解生产者(服务端)的细节,接口相当于合同,当合同不变的时候,谁生产如何生产都不是消费者关心的问题。

# What is the Repository pattern? The Factory Pattern? Why are patterns important?

关于设计模式的问题,

第一个参考http://msdn.microsoft.com/en-us/library/ff649690.aspx

工厂模式基本上是众人皆知的模式了。

为何模式重要?我不觉得模式重要,模式的重要性在于让你能“喔!原来是这个”。但是对于一个没有几年编程经验的开发者而言,模式只能让你更混乱。

设计模式很多情况下是通过加入一个抽象层来解决耦合之类的问题,但是层次越多越复杂,就好比单位中领导的级别越多越官僚一样。

# What are some examples of anti-patterns?

反模式?少用模式,多写点清晰的代码吧。

# Who are the Gang of Four? Why should you care?

四人组,名字叫不上来,但是他们是设计模式的总结者。

# How do the MVP, MVC, and MVVM patterns relate? When are they appropriate?

这也是微软特色,大家只要知道MVC就行了,其实大家现在用的都是MVC,但是由于水平高低,效果就是千差万别。

啥MVP,MVVM我不知啊(也不是不知,只知道MVVM是wpf的一个概念,可我也不用wpf啊)

# Explain the concept of Separation of Concerns and it’s pros and cons.

参考http://en.wikipedia.org/wiki/Separation_of_concerns

我也不是了解的很细。

# Name three primary attributes of object-oriented design. Describe what they mean and why they’re important.

封装/继承/多态?

参考这里吧http://en.wikipedia.org/wiki/Object-oriented_programming

学C++这几个概念是基础啊

# Describe a pattern that is NOT the Factory Pattern? How is it used and when?

不是工厂模式,我知道个单件模式。还有模板模式/facade模式/strategy模式,具体也要翻翻书,很少有意识的套用。

# You have just been put in charge of a legacy code project with maintainability problems. What kind of things would you look to improve to get the project on a stable footing?

第一步,先把代码用最大警告级别编译一遍,然后fix所有值得fix的warning。

好问题。

# Show me a portfolio of all the applications you worked on, and tell me how you contributed to design them.

如果光是看文档,很难说到实质上。

好问题。

# What are some alternate ways to store data other than a relational database? Why would you do that, and what are the trade-offs?

好问题,很多啦,内存/文件/云存储/nosql等等。tradeoff就看你的应用需求了。blabla。。。

# Explain the concept of convention over configuration, and talk about an example of convention over configuration you have seen in the wild.

好问题。

我能想到的就是买车开车,很少有人买到车以后,拿着说明书调试这个那个,一般都是直接上路,因为汽车厂会给你一个比较不错的默认配置,也就是所谓的“方便”。

这个方便也保证了你开其它车,基本上都差不多,不用重新配置或者学习什么。

所谓方便”convention“就是把相对不错/比较普遍适用的配置都内置好了,用就是了。

# Explain the differences between stateless and stateful systems, and impacts of state on parallelism.

解释有状态与无状态系统,以及有状态系统在并行上的影响。

好问题。这个说不好。有状态系统因为保持状态,并发运行时的访问/修改需要有锁同步机制。

# Discuss the differences between Mocks and Stubs/Fakes and where you might use them (answers aren’t that important here, just the discussion that would ensue).

跟TDD相关的问题。不会哦。

# Discuss the concept of YAGNI and explain something you did recently that adhered to this practice.

解释“YAGNI”。

最简单的例子是当我们定义接口,会特意预留出一两个参数,说是为了将来使用,其实,没有将来。屁嘞!你根本不需要它!

不是说不考虑可扩展性,但是要基于可预测的基础上。

# Explain what is meant by a sandbox, why you would use one, and identify examples of sandboxes in the wild.

比如把虚拟机比如vmware virtualbox作为沙箱,用起来可以隔离风险。大不了重启,或者删除之。

# Concurrency

* What’s the difference between Locking and Lockless (Optimistic and Pessimistic) concurrency models?

* What kinds of problems can you hit with locking model? And a lockless model?

* What trade offs do you have for resource contention?

* How might a task-based model differ from a threaded model?

* What’s the difference between asynchrony and concurrency?

这些问题不错。并发相关的问题,设计多用户高性能系统必知。

# Are you still writing code? Do you love it?

我喜欢编程。

# You’ve just been assigned to a project in a new technology how would you get started?

如果是我,先了解这个技术的风险。小心求证,尽量缩小使用范围,否则是很致命的。

# How does the addition of Service Orientation change systems? When is it appropriate to use?

不懂。

# What do you do to stay abreast of the latest technologies and tools?

我跟的很紧哦!

# What is the difference between "set" logic, and "procedural" logic. When would you use each one and why?

不懂要问什么。

# What Source Control systems have you worked with?

ClearCase.很难用。最近不少问题都是跟CC相关的。

# What is Continuous Integration? Have you used it and why is it important?

持续集成。这个概念跟TDD也挂钩。

# Describe a software development life cycle that you’ve managed.

涉及的还是传统模型,不是scrum型的。

# How do you react to people criticizing your code/documents?

批评没问题,但是要有道理有根据。

# Whose blogs or podcasts do you follow? Do you blog or podcast?

这就很多了,看我以前写的文章吧。

# Tell me about some of your hobby projects that you’ve written in your off time.

主要是Lua和Py的,appengine上的比较多。

# What is the last programming book you read?

最近看得是《C++ FAQs》中文版。翻译的一般,内容也比较陈旧。更坚定了我使用C风格的C++的决心。

# Describe, in as much detail as you think is relevant, as deeply as you can, what happens when I type "cnn.com" into a browser and press "Go".

尽可能详细深入的描述,当你在浏览器敲网址然后go后面的技术细节。

好问题。很发散,绝对能看出面试者的技术厚度。

# Describe the structure and contents of a design document, or a set of design documents, for a multi-tiered web application.

# What’s so great about <cool web technology of the day>?

# How can you stop your DBA from making off with a list of your users’ passwords?

# What do you do when you get stuck with a problem you can’t solve?

参考这里计算机编程新人入行指导 

http://sunxiunan.com/?p=961

# If your database was under a lot of strain, what are the first few things you might consider to speed it up?

先profiling哦!

# What is SQL injection?

# What’s the difference between unit test and integration test?

单元测试应该是程序员做。集成测试就牵扯到tester了。

# Tell me about 3 times you failed.

# What is Refactoring ? Have you used it and it is important? Name three common refactorings.

我一直在重构自己的代码。重构原则参考这里

C++项目代码规范(偶自用)http://sunxiunan.com/?p=1787

# You have two computers, and you want to get data from one to the other. How could you do it?

命名管道,socket,共享文件夹,路子还是很多的。

# Left to your own devices, what would you create?

# Given Time, Cost, Client satisfaction and Best Practices, how will you prioritize them for a project you are working on? Explain why.

这个很值得问。

# What’s the difference between a web server, web farm and web garden? How would your web application need to change for each?

# What value do daily builds, automated testing, and peer reviews add to a project? What disadvantages are there?

都是为了提升代码质量,但是会延长工期。

# What elements of OO design are most prone to abuse? How would you mitigate that?

# When do you know your code is ready for production?

看bug fix的统计曲线。

理解Node.js事件驱动编程

Node.js现在非常活跃,相关生态社区已经超过Lua(基本上比较知名的功能都有nodejs模块实现)。

但是我们为何要使用Node.Js?相比传统的webserver服务模式,nodejs有什么优点优势?

Node.Js是基于javascript语言,建构在google V8 engine以及Linux上的一个非阻塞事件驱动IO框架。nodejs是单进程单线程,但是基于V8的强大驱动力,以及事件驱动模型,nodejs的性能非常高,而且想达到多核或者多进程也不是很难(现在已经有大量的第三方module来实现这个功能)。

这里主要不是介绍nodejs具体应用代码,而是想介绍一下事件驱动编程。

在这篇文章(1)里面,Dan York介绍了两种典型的事件驱动实例。

第一个例子是关于医生看病。

在美国去看医生,需要填写大量表格,比如保险、个人信息之类,传统的基于线程的系统(thread-based system),接待员叫到你,你需要在前台填写完成这些表格,你站着填单,而接待员坐着看你填单。你让接待员没办法接待下一个客户,除非完成你的业务

想让这个系统能运行的快一些,只有多加几个接待员,人力成本需要增加不少。

基于事件的系统(event-based system)中,当你到窗口发现需要填写一些额外的表格而不仅仅是挂个号,接待员把表格和笔给你,告诉你可以找个座位填写,填完了以后再回去找他。你回去坐着填表,而接待员开始接待下一个客户。你没有阻塞接待员的服务

你填完表格,返回队伍中,等接待员接待完现在的客户,你把表格递给他。如果有什么问题或者需要填写额外的表格,他给你一份新的,然后重复这个过程。

这个系统已经非常高效了,几乎大部分医生都是这么做的。如果等待的人太多,可以加入额外的接待员进行服务,但是肯定要比基于线程模式的少得多。

第二个例子是快餐店点餐。

在基于线程的方式中(thread-based way)你到了柜台前,把你的点餐单给收银员或者给收银员直接点餐,然后等在那直到你要的食物准备好给你。收银员不能接待下一个人,除非你拿到食物离开。想接待更多的客户,容易!加更多的收银员!

当然,我们知道快餐店其实不是这样工作的。他们其实就是基于事件驱动方式,这样收银员更高效。只要你把点餐单给收银员,某个人已经开始准备你的食物,而同时收银员在进行收款,当你付完钱,你就站在一边而收银员已经开始接待下一个客户。在一些餐馆,甚至会给你一个号码,如果你的食物准备好了,就呼叫你的号码让你去柜台取。关键的一点是,你没有阻塞下一个客户的订餐请求。你订餐的食物做好的事件会导致某个人做某个动作(某个服务员喊你的订单号码,你听到你的号码被喊到去取食物),在编程领域,我们称这个为回调(callback function)。

 

Node.Js做了什么工作呢?

传统的web server多为基于线程模型。你启动Apache或者什么server,它开始等待接受连接。当收到一个连接,server保持连接连通直到页面或者什么事务请求完成。如果他需要花几微妙时间去读取磁盘或者访问数据库,web server就阻塞了IO操作(这也被称之为阻塞式IO).想提高这样的web server的性能就只有启动更多的server实例。

相反的,Node.Js使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)

考虑下面这个过程:

1,你用浏览器访问nodejs服务器上的"/about.html"

2,nodejs服务器接收到你的请求,调用一个函数从磁盘上读取这个文件。

3,这段时间,nodejs webserver在服务后续的web请求。

4,当文件读取完毕,有一个回调函数被插入到nodejs的服务队列中。

5,nodejs webserver运行这个函数,实际上就是渲染(render)了about.html页面返回给你的浏览器。

好像就节省了几微秒时间,但是这很重要!特别是对于需要相应大量用户的web server。

这也就是为什么Node.Js这么热这么惹人关注。而且它还使用了一个非常通用的编程语言Javascript,也让开发者可以快速容易的编写高可扩展性服务器。

(1) http://code.danyork.com/2011/01/25/node-js-doctors-offices-and-fast-food-restaurants-understanding-event-driven-programming/