前言
何为递归,递归就是递归,递去归来也。
一个很好的例子是GNU = GNU is NOT UNIX
|
|
这是一个永远不会返回的递归调用,或许也寓意GNU生生不息吧。
我们从几个简单的例子来说起:
求一组数据的累加和
这里不考虑数学算法层面,从常识的角度,有如下迭代解法
代码很简单,如下:
|
|
根据我的面试经历,技术面试的问题会集中在三个方面
1.确认项目经历
2.针对性地问些技术问题
3.算法和逻辑方面的问题
而这三方面的问题大多是通过项目经验来展开的,如何准备呢?
介绍的项目与目标职位要匹配
可以是工作项目,也可以是个人开源项目
切勿驴头不对马嘴,针对不同的职位要有不同的简历
比如我的简历就有几份,投递不同的职位
驱动高级开发简历 内核中级开发简历 C/C++高级开发简历 JAVA后端中级开发简历
这里有个插曲,在有的企业 BSP和驱动是严格分工的
用简短的语言概括项目的来源和需求,语在精炼不在多
比如客户是谁,是要干什么的,分哪些模块,大致的工期是多少。
主要是让面试官对项目整体有个印象,我一般按下面的步骤进行描述:
1.项目的人员组成
比如互联网项目:
前端5人+后端20人+美工2人+app2人+DBA2人+测试3人+QA1人+产品经理1人+项目经理1人
物联网项目:
前端2人+后端10人+DBA1人+协议2人+BSP1人+驱动1人+硬件1人+测试1人+QA1人+产品经理1人+项目经理1人
2.项目的分层模型
如互联网项目:
从前端->负载均衡(如nginx)–>管理层–>业务层(罗列主要的)<–>调用层(如dubbo)<–>数据层(如mysql redis)<—>日志层
物联网项目:
媒介层(如app web)—>中间件—>协议层—>管理层—->数据层—->驱动层<——硬件层
3.简要介绍项目用到的技术和创新点
关注职位匹配度
相比于整个项目,企业对自己的角色往往更感兴趣。
介绍做的模块里用到了哪些技术以及有哪些亮点,技术和亮点最好要和职位要求相一致。而且,面试官有可能会问你提到的技术的细节,也就是说,宁可只你非常熟悉的技术,而不提不熟悉的技术。
注意:
对于自己还没完全弄清的技术,被问到,除非毫无头绪,不然可按下面的方法回答:
比如,了解DTS吗?
答:DTS技术有过了解,简单看过代码,回答一下原理XXXXXXXXX,(话锋一转)但是在我的项目里,没有使用这个技术,表明原因:内核版本比较老,xxxxxxx(主要避免面试官问到太多细节,那就尴尬了)
有的面试官会问:看过那些开源项目的源码?
不要瞎说,列举自己比较熟悉的几个就行,一定要是真的看过的(一问三不知就尴尬了)
比如我一般这样回答
如果面试驱动,答:内核看得比较多,比较关注KVM
C/C++: 研究过libevent源码,用过mudulo,准备研究下源码
java: 用过netty dubbo nginx,正在看nginx源码
工作内容是要说明的重点,接下来的面试将会围绕这个展开,要充分回顾并挖掘工作内容的技术点、难点、创新点,做到有的放矢。
项目经验的介绍是一个细心活,需要求职前好好准备,提炼总结。
同时一定记住以下两点内容:
第一,切忌浮夸;
第二,如果是外企,最好能够做一个英文的介绍,以备不时之需。
关于算法面试:这些都是最基本的。
1.排序
基本排序手写一定要正确率100%,归并要手写,快排要手写,最好递归和迭代都能写
清楚每个算法的复杂度,知道如何优化,比如快排的随机化锚点,三路快排,直接插入优化
2.查找
二分手写,迭代和递归都要会
hash查找,hash function的构造,避免冲突,优势
3.链表
这个怎么变着花样玩,都要能手写出花来,
链表在linux内核中用得太多,可以这么说,看得懂内核的list,理论上就能看懂内核70%以上代码
再能懂体系结构,有面向对象思想,会一点汇编,理论上能看懂90%
再看懂树和hashtable,理论上内核代码100%阅读无障碍!
大多数据结构都是嵌入list,结构很复杂,但算法逻辑都很简单
红黑树在内核用在了schedule和epoll中,其他地方我还没看到过
4.树
前序 中序 后序 手写,构造,查找 插入
AVL 2-3树 B树 红黑树 trie树 radix树 原理要能说清楚,一般不会让写代码
5.图
BFS DFS 能手写
最小生成树 最短路径 自动寻路 说清原理 一般不会让手写
6.动态规划
基本的走楼梯还是要手写的
7.贪心 分治
原理和应用,说清便可
8.海量数据
说清原理,一般都是要建立最大/小堆
9.并发问题
ppc tpc select poll epoll 阻塞 非阻塞 同步IO 异步IO 原理要说清楚
10.TCP/IP
各层功能 编程模型 滑动窗口 粘包 优化 超时重传 三次握手 四次挥手
原始套接字 单播 组播 广播 心跳包
11.编译原理
至少能说清楚一个基于栈计算机的加法语言
add+push描述栈计算机 后序遍历描述语法树
本文分析树莓派从上电启动到linux内核启动整个流程,关于linux内核引导之后的流程那是后话,本文不涉及
首先需要说明的是,树莓派不是完整意义上的开源硬件,系统启动这一块的代码是没有的,git官网镜像提供的是已经编译好的二进制文件,我想正式树莓派这种半开源的模式成就了树莓派,一来保证了芯片供应商博通的商业利益,二来有效防止了树莓派的仿冒,从而让树莓派在开源硬件的竞争中站稳了脚跟。虽然没有源代码,关于树莓派启动这一块的分析还是可以大致分析的,下面就来简单分析下树莓派的启动流程。
为了降低成本,树莓派省去了传统计算机用来存储引导加载程序的板载存储器(BIOS), 直接把引导程序放在了SD卡中。树莓派2具有一款博通的BCM2836系统芯片, 当启动时,ARM Cortex-A7的CPU会处于复位状态,由VideoCore IV GPU核心负责启动系统,也就是boot的启动是由GPU code来完成,而不是cpu,这是与一般ARM架构的处理器不一样的地方。
众里寻他千百度,青天白夜荡谷歌,纵观整个网络,没有找到一篇详细介绍树莓派硬件设计的文章,不免唏嘘。树莓派作为一款开源卡片式电脑,基于Broadcom商业策略的考虑,硬件没有完全开源,可以理解,但是对于硬件已经开源的部分,很少人来分析、研究和扩展,我理解树莓派的生态在硬件层面上是有一定残缺的。
Anyway,树莓派作为一款“开源硬件”,其价值并不在于硬件的扩展性,而在于软件设计,Geek们利用树莓派开放的GPIO的硬件能力,构建起了庞大的软件生态,可以说,树莓派其实是一个基于硬件的软件开源平台。
下面,我简单分析下树莓派的硬件设计。
树莓派的第一手资料,当然要去github raspberry官方镜像获取
IoTgo项目的初衷是想让用户可以像部署zencart搭建博客,安装 phpbb创建论坛一样,通过部署IoTgo建立自己的云端服务器,服务器不仅仅是接口开放,而是全部代码开源
github链接
物联网平台及webUI
https://github.com/itead/IoTgo
手机端app demo
https://github.com/itead/IoTgo_Android_App
Arduino库
https://github.com/itead/ITEADLIB_Arduino_IoTgo
树莓派,CB等卡片式电脑SDK
https://github.com/itead/Segnix/tree/master/libraries/itead_IoTgo
通信协议层支持HTTP Websocket,MQTT, CoAP
其基本架构如下图所示