1.1.1 如何实现一个高效的单向链表逆序输出?
出题人:阿里巴巴出题专家:昀龙/阿里云弹性人工智能负责人
参考答案:下面是其中一种写法,也可以有不同的写法,比如递归等。供参考。
typedef struct node{
int data;
struct node* next;
node(int d):data(d), next(NULL){}
}node;
void reverse(node* head)
{
if(NULL == head || NULL == head->next){
return;
}
node* prev=NULL;
node* pcur=head->next;
node* next;
while(pcur!=NULL){
if(pcur->next==NULL){
pcur->next=prev;
break;
}
next=pcur->next;
pcur->next=prev;
prev=pcur;
pcur=next;
}
head->next=pcur;
node*tmp=head->next;
while(tmp!=NULL){
cout<<tmp->data<<"\t";
tmp=tmp->next;
}
}
1.1.2 已知sqrt(2)约等于1.414,要求不用数学库,求sqrt(2)精确到小数点后10位
出题人:——阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家
参考答案:
- 考察点
1.基础算法的灵活应用能力(二分法学过数据结构的同学都知道,但不一定往这个方向考虑;如果学过数值计算的同学,应该还要能想到牛顿迭代法并解释清楚)
2.退出条件设计
- 解决办法
-
已知 sqrt(2)约等于 1.414,那么就可以在(1.4, 1.5)区间做二分 查找,如: a) high=>1.5 b) low=>1.4 c) mid => (high+low)/2=1.45 d) 1.45*1.45>2 ? high=>1.45 : low => 1.45 e) 循环到 c)
-
退出条件 a) 前后两次的差值的绝对值<=0.0000000001, 则可退出
const double EPSINON = 0.0000000001;
double sqrt2( ){
double low = 1.4, high = 1.5;
double mid = (low + high) / 2;
while (high – low > EPSINON){
if (mid*mid < 2){
high = mid;
}
else{
low = mid;
}
mid = (high + low) / 2;
}
return mid;
}
1.1.3 给定一个二叉搜索树(BST),找到树中第 K 小的节点
出题人:阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家
参考答案:
- 考察点 1.基础数据结构的理解和编码能力
2.递归使用
5
/ \
3 6
/ \
2 4
/
1
说明:保证输入的 K 满足 1<=K<=(节点数目)
树相关的题目,第一眼就想到递归求解,左右子树分别遍历。联想到二叉搜索树的性质,root 大于左子树,小于右子树,如果左子树的节点数目等于 K-1,那么 root 就是结果,否则如果左子树节点数目小于 K-1,那么结果必然在右子树,否则就在左子树。因此在搜索的时候同时返回节点数目,跟 K 做对比,就能得出结果了。
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
private class ResultType {
boolean found; // 是否找到
int val; // 节点数目
ResultType(boolean found, int val) {
this.found = found;
this.val = val;
}
}
public int kthSmallest(TreeNode root, int k) {
return kthSmallestHelper(root, k).val;
}
private ResultType kthSmallestHelper(TreeNode root, int k) {
if (root == null) {
return new ResultType(false, 0);
}
ResultType left = kthSmallestHelper(root.left, k);
// 左子树找到,直接返回
if (left.found) {
return new ResultType(true, left.val);
}
// 左子树的节点数目 = K-1,结果为 root 的值
if (k - left.val == 1) {
return new ResultType(true, root.val);
}
// 右子树寻找
ResultType right = kthSmallestHelper(root.right, k - left.val - 1);
if (right.found) {
return new ResultType(true, right.val);
}
// 没找到,返回节点总数
return new ResultType(false, left.val + 1 + right.val);
}
}
1.1.4 LRU 缓存机制 设计和实现一个 LRU(最近最少使用)缓存数据结构,使它应该支持一下操作:get 和 put。 get(key) - 如果 key 存在于缓存中,则获取 key 的 value(总是正数),否则返回 -1。 put(key,value) - 如果 key 不存在,请设置或插入 value。当缓存达到其容量时,它应该在插入新项目之前使最近最少使用的项目作废。
出题人:文景/阿里云 CDN 资深技术专家
参考答案:
python版本的:
class LRUCache(object):
def __init__(self, capacity):
"""
:type capacity: int
"""
self.cache = {}
self.keys = []
self.capacity = capacity
def visit_key(self, key):
if key in self.keys:
self.keys.remove(key)
self.keys.append(key)
def elim_key(self):
key = self.keys[0]
self.keys = self.keys[1:]
del self.cache[key]
def get(self, key):
"""
:type key: int
:rtype: int
"""
if not key in self.cache:
return -1
self.visit_key(key)
return self.cache[key]
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: void
"""
if not key in self.cache:
if len(self.keys) == self.capacity:
self.elim_key()
self.cache[key] = value
self.visit_key(key)
def main():
s =
[["put","put","get","put","get","put","get","get","get"],[[1,1],[2,2],[1],[3,3],[2],[
4,4],[1],[3],[4]]]
obj = LRUCache(2)
l=[]
for i,c in enumerate(s[0]):
if(c == "get"):
l.append(obj.get(s[1][i][0]))
else:
obj.put(s[1][i][0], s[1][i][1])
print(l)
if __name__ == "__main__":
main()
c++版本的:
class LRUCache{
public:
LRUCache(int capacity) {
cap = capacity;
}
int get(int key) {
auto it = m.find(key);
if (it == m.end()) return -1;
l.splice(l.begin(), l, it->second);
return it->second->second;
}
void set(int key, int value) {
auto it = m.find(key);
if (it != m.end()) l.erase(it->second);
l.push_front(make_pair(key, value));
m[key] = l.begin();
if (m.size() > cap) {
int k = l.rbegin()->first;
l.pop_back();
m.erase(k);
}
}
}
1.3.5 假如给你一个新产品,你将从哪些方面来保障它的质量?
出题人:阿里巴巴出题专家:晨晖 /阿里云中间件技术部测试开发专家
参考答案:
可以从代码开发、测试保障、线上质量三个方面来保障。
在代码开发阶段,有单元测试、代码Review、静态代码扫描等;
测试保障阶段,有功能测试、性能测试、高可用测试、稳定性测试、兼容性测试等;
在线上质量方面,有灰度发布、紧急回滚、故障演练、线上监控和巡检等。
下期预告:
1.1.6 MySQL的数据如何恢复到任意时间点?
1.1.7 NFS 和 SMB 是最常见的两种 NAS(Network Attached Storage)协议,当把一个文件系统同时通过 NFS 和 SMB 协议共享给多个主机访问时,以下哪些说法是错误的
1.1.8 输入 ping IP 后敲回车,发包前会发生什么?
1.1.9 请解释下为什么鹿晗发布恋情的时候,微博系统会崩溃,如何解决?
1.2.0 现有一批邮件需要发送给订阅顾客,且有一个集群(集群的节点数不定,会动态扩容缩容)来负责具体的邮件发送任务,如何让系统尽快地完成发送?
小结:
在互联网边缘OB数几年,发现面试是程序员开启神奇之门的第一步。
小伙近期会和大家一起探讨互联网巨头们2019最新的面试题。
请大家多多关注小伙,您的关注与点赞是小伙更新的动力。
加小伙QQ更多福利资源等你领取哟,QQ 758810390