引言

2020阿里巴巴专家组出题,等你来答:

题目:如何判断两个链表是否相交

出题人:阿里巴巴新零售技术质量部

参考答案

$O(n^2)$: 两层遍历,总能发现是否相交

$O(n)$: 一层遍历,遍历完两个链表,如果两个链表的最后一个结点指针相同,则相交,否则不相交

题目:一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素?

出题人:阿里巴巴出题专家:子团/创新产品虚拟化&稳定性资深技术专家

参考答案

及格: 每执行一条mov指令需要消耗1个时钟周期,所以每秒执行的mov指令和CPU主频相关。

加分: 在CPU微架构上,要考虑数据预取,乱序执行,多发射,内存stall(前端stall和后端stall)等诸多因素,因此除了cpu主频外,还和流水线上的效率(IPC)强相关,比较复杂的一个问题。

题目:如何实现一个高效的单向链表逆序输出?

出题人:阿里巴巴出题专家:昀龙/阿里云弹性人工智能负责人

参考答案:下面是其中一种写法,也可以有不同的写法,比如递归等。供参考。

typedef struct node{
    int           data;
    struct node*  next;
    node(int d):data(d), next(NULL){}
}node;

void reverse(node* head)
{
    if(head == NULL){
        return;
    }

    node* pleft = NULL;
    node* pcurrent = head;
    node* pright = head->next;

    while(pright){
        pcurrent->next = pleft;
        node *ptemp = pright->next;
        pright->next = pcurrent;
        pleft = pcurrent;
        pcurrent = pright;
        pright = ptemp;
    }

    while(pcurrent != NULL){
        cout<< pcurrent->data << "\t";
        pcurrent = pcurrent->next;
    }
}

class Solution<T> {

    public void reverse(ListNode<T> head) {
       if (head == null || head.next == null) {
        return ;
       }
       ListNode<T> currentNode = head;
       Stack<ListNode<T>> stack = new Stack<>();
       while (currentNode != null) {
        stack.push(currentNode);
        ListNode<T> tempNode = currentNode.next;
        currentNode.next = null; // 断开连接
        currentNode = tempNode;
       }
       
       head = stack.pop();
       currentNode = head;
       
       while (!stack.isEmpty()) {
        currentNode.next = stack.pop();
        currentNode = currentNode.next;
       }
    }
}

class ListNode<T>{
 T val;
 public ListNode(T val) {
  this.val = val;
 }
 ListNode<T> next;
}

题目:已知 sqrt (2)约等于 1.414,要求不用数学库,求 sqrt (2)精确到小数点后 10 位。

出题人:——阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家

参考答案

* 考察点

  1. 基础算法的灵活应用能力(二分法学过数据结构的同学都知道,但不一定往这个方向考虑;如果学过数值计算的同学,应该还要能想到牛顿迭代法并解释清楚)
  2. 退出条件设计

二分法

1. 已知 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)

2. 退出条件

a) 前后两次的差值的绝对值<=0.0000000001, 则可退出

const double EPSILON = 0.0000000001;

double sqrt2() {
    double low = 1.4, high = 1.5;
    double mid = (low + high) / 2;

    while (high - low > EPSILON) {
        if (mid * mid > 2) {
            high = mid;
        } else {
            low = mid;
        }
        mid = (high + low) / 2;
    }

    return mid;
}

牛顿迭代法

1.牛顿迭代法的公式为:

xn+1 = xn-f(xn)/f'(xn)

对于本题,需要求解的问题为:f(x)=x2-2 的零点

EPSILON = 0.1 ** 10
def newton(x):
    if abs(x ** 2 - 2) > EPSILON:
        return newton(x - (x ** 2 - 2) / (2 * x))
    else:
        return x

题目: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);
            }
        }
}

题目:关于 epoll 和 select 的区别,哪些说法是正确的?(多选)

A. epoll 和 select 都是 I/O 多路复用的技术,都可以实现同时监听多个 I/O 事件的状态。

B. epoll 相比 select 效率更高,主要是基于其操作系统支持的I/O事件通知机制,而 select 是基于轮询机制。

C. epoll 支持水平触发和边沿触发两种模式。

D. select 能并行支持 I/O 比较小,且无法修改。

出题人:阿里巴巴出题专家:寈峰/阿里技术专家

参考答案:A,B,C

【延伸】那在高并发的访问下,epoll使用那一种触发方式要高效些?当使用边缘触发的时候要注意些什么东西?

题目:从 innodb 的索引结构分析,为什么索引的 key 长度不能太长?

出题人:阿里巴巴出题专家:近秋/阿里云数据库产品技术部技术专家

参考答案:key 太长会导致一个页当中能够存放的 key 的数目变少,间接导致索引树的页数目变多,索引层次增加,从而影响整体查询变更的效率。

题目:MySQL 的数据如何恢复到任意时间点?

出题人:阿里巴巴出题专家:近秋/阿里云数据库产品技术部技术专家参考答案

参考答案:恢复到任意时间点以定时的做全量备份,以及备份增量的 binlog 日志为前提。恢复到任意时间点首先将全量备份恢复之后,再此基础上回放增加的 binlog 直至指定的时间点。

题目:NFS 和 SMB 是最常见的两种 NAS(Network Attached Storage)协议,当把一个文件系统同时通过 NFS 和 SMB 协议共享给多个主机访问时,以下哪些说法是错误的:(多选)

A. 不可能有这样的操作,即把一个文件系统同时通过 NFS 和 SMB协议共享给多个主机访问。

B. 主机 a 的用户通过NFS 协议创建的文件或者目录,另一个主机 b的用户不能通过 SMB 协议将其删除。

C. 在同一个目录下,主机 a 通过 NFS 协议看到文件 file.txt,主机b 通过 SMB 协议也看到文件 file.txt,那么它们是同一个文件。

D. 主机 a 通过 NFS 协议,以及主机 b 通过 SMB 协议,都可以通过主机端的数据缓存,提升文件访问性能。

出题人:阿里巴巴出题专家:起影/阿里云文件存储高级技术专家

参考答案:A,B,C

题目:输入 ping IP 后敲回车,发包前会发生什么?

出题人:阿里巴巴出题专家:怀虎/阿里云云效平台负责人

参考答案: ping目标ip时,先查路由表,确定出接口

  • 如果落在直连接口子网内,此时若为以太网等 多路访问网络 则先查询arp缓存,命中则直接发出,否则在该接口上发arp询问目标ip的mac地址,取得后发出,若为ppp等 点对点网络 ,则直接可以发出;
  • 如果查表落在缺省路由上,此时若为以太网等 多路访问网络 则先查询网关arp缓存,命中则直接发出,否则在该接口上发arp询问网关的mac地址,取得后发出,若为ppp等 点对点网络 ,则直接可以发出;
  • 若查表未命中,则返回不可达。

题目:如何实现两金额数据相加(最多小数点两位)?

出题人:阿里巴巴出题专家:御术/蚂蚁金服数据可视化高级技术专家

参考答案

其实问题并不难,就是考察候选人对 JavaScript 数据运算上的认知以及考虑问题的缜密程度,有很多坑,可以用在笔试题,如果用在面试,回答过程中还可以随机加入有很多计算机基础的延伸。

回到这个问题,由于直接浮点相与加会失精,所以要转整数;(可以插入问遇到过吗?是否可以举个例子?)。

转整数是第一个坑,虽然只有两位可以通过乘以100转整数,但由于乘以一百和除以一百都会出现浮点数的运算,所以也会失精,还是要通过字符串来转;(可以插入问字符串转整数有几种方式?)字符串转整是第二个坑,因为最后要对齐计算,如果没考虑周全先toFixed(2),对于只有一位小数点数据进入计算就会错误;转整数后的计算是个加分点,很多同学往往就是直接算了,如果可以考虑大数计算的场景,恭喜同学进入隐藏关卡,这就会涉及如何有效循环、遍历、算法复杂度的问题。

题目: 关于并行计算的一些基础开放问题。

如何定义并计算,请分别阐述分布式内存到共享内存模式行编程的区别和实现(例子代码)?

请使用 MPI 和 OpenMP 分别实现 N 个处理器对 M 个变量的求和?

请说明 SIMD 指令在循环中使用的权限?向量化优化有哪些手段?

请用 Amdahl 定律说明什么是并行效率以及并行算法的扩展性?并说明扩展性的性能指标和限制因素,最后请说明在共享内存计算机中,共享内存的限制?OpenMP 是怎样实现共享内存编程环境的?MPI 阻塞和非阻塞读写的区别?

出题人:阿里巴巴出题专家:何万青/阿里云高性能计算资深技术专家

参考答案

(简要答案,但必须触及,可以展开) 同时执行多个/算法/逻辑操作/内存访问/IO,相互独立同时运行,分三个层次:进程级,多个节点分布式内存通过MPI通信并行;线程级,共享内存的多路机器,通过OpenMP实现多线程并行;指令集:通过SIM指令实现单指令多数据。。。。举例吧啦吧啦。

MPI代码,,,OpenMP代码,分别写出来 M个元素,N个处理器的累加,后者注意private 参数。

SIMD在循环中的应用,限制在于 SIMD指令处理的每一个数组的长度,cache line利用,内部循环间的依赖和条件调用等。

向量化,主要看SSE和AVX指令占比率,通过编译器优化...... 在loop代码中使用。

性能和计算规模随处理器增加的变化曲线,实测HPL和峰值HPL比率,能用用Amdahl定律表达Tpar(N) = (an + (1-a)n/N )t + C (n,N), 能够讲明白串行部分对整个并行的天花板效应,扩展性能够解释清楚算法的扩展性=并行效率随处理器数目的变化关系,画出来。

共享内存计算机OpenMP对变量的限制描述,EREW,CREW,ERCW,CRCW等区别,NUMA概念,如何保持coherent等。

写出OpenMP和MPI的核心函数,回答问题即可。

题目:假如给你一个新产品,你将从哪些方面来保障它的质量?

出题人:阿里巴巴出题专家:晨晖 /阿里云中间件技术部测试开发专家

参考答案

可以从代码开发、测试保障、线上质量三个方面来保障。

在代码开发阶段,有单元测试、代码Review、静态代码扫描等;

测试保障阶段,有功能测试、性能测试、高可用测试、稳定性测试、兼容性测试等;

在线上质量方面,有灰度发布、紧急回滚、故障演练、线上监控和巡检等。

题目:如何测试一辆自行车

出题人:阿里巴巴新零售技术质量部

参考答案

开放性问题,如果联系到测试角度上看的话,可以这么作答:

  1. 骑车试一试,看有没有问题,对应测试能不能跑通
  2. 看看车的核心部件,例如车闸,车把等,对应软件的核心功能
  3. 看看车是否安全,配锁质量如何,对应软件是否有安全问题

题目:给定一个链表,删除链表的倒数第 N 个节点,并且返回链表的头结点。

示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5. 说明: 给定的 n 保证是有效的。 要求: 只允许对链表进行一次遍历。

出题人:阿里巴巴出题专家:屹平/阿里云视频云边缘计算高级技术专家

参考答案

我们可以使用两个指针而不是一个指针。第一个指针从列表的开头向前移动 n+1 步,而第二个指针将从列表的开头出发。现在,这两个指针被 n 个结点分开。我们通过同时移动两个指针向前来保持这个恒定的间隔,直到第一个指针到达最后一个结点。此时第二个指针将指向从最后一个结点数起的第 n 个结点。我们重新链接第二个指针所引用的结点的 next 指针指向该结点的下下个结点。

参考代码

public ListNode removeNthFromEnd(ListNode head, int n)
{
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    ListNode first = dummy;
    ListNode second = dummy;
    // Advances first pointer so that the gap between first
    and second is n nodes apart
    for (int i = 1; i <= n + 1; i++) {
        first = first.next;
    }
    // Move first to the end, maintaining the gap
    while (first != null) {
        first = first.next;
        second = second.next;
    }
    second.next = second.next.next;
    return dummy.next;
}

复杂度分析:

  • 时间复杂度:O(L),该算法对含有 L 个结点的列表进行了一次遍历。因此时间复杂度为 O(L)。

  • 空间复杂度:O(1),我们只用了常量级的额外空间。

最后

​ 免费领取完整版各大厂商面试真题点赞+转发+评论,后台回复”面试”即可获取领取链接 ​

阿里技术专家十五问,真题面试刀刀见肉,快来和阿里面试官battle的更多相关文章

  1. C#学习基础概念二十五问

    C#学习基础概念二十五问 1.静态变量和非静态变量的区别?2.const 和 static readonly 区别?3.extern 是什么意思?4.abstract 是什么意思?5.internal ...

  2. 面渣逆袭:Spring三十五问,四万字+五十图详解

    大家好,我是老三啊,面渣逆袭 继续,这节我们来搞定另一个面试必问知识点--Spring. 有人说,"Java程序员都是Spring程序员",老三不太赞成这个观点,但是这也可以看出S ...

  3. C#基础概念二十五问

    1.静态成员和非静态成员的区别? 答: 静态变量使用 static 修饰符进行声明,在类被实例化时创建,通过类进行访问 不带有 static 修饰符声明的变量称做非静态变量,在对象被实例化时创建,通过 ...

  4. 面渣逆袭:Redis连环五十二问,图文详解,这下面试稳了!

    大家好,我是老三,面渣逆袭系列继续,这节我们来搞定Redis--不会有人假期玩去了吧?不会吧? 基础 1.说说什么是Redis? Redis是一种基于键值对(key-value)的NoSQL数据库. ...

  5. 秋招如何抱佛脚?2022最新大厂Java面试真题合集(附答案

    2022秋招眼看着就要来了,但是离谱的是,很多同学最近才想起来还有秋招这回事,所以纷纷临时抱佛脚,问我有没有什么快速磨枪的方法, 我的回答是:有! 说起来,临阵磨枪没有比背八股文更靠谱的了,很多人对这 ...

  6. 大厂0距离:网易 Linux 运维工程师面试真题,内含答案

    作为 Linux 运维工程师,进入大公司是开启职业新起点的关键,今天马哥 linux 运维及云计算智囊团的小伙伴特别分享了其在网易面试 Linux 运维及云计算工程师的题目和经历,希望对广大 Linu ...

  7. 40k*16 薪,五年Android开发4轮面试拿下腾讯 Offer !(附真题)

    概述 感觉毕业后时间过得真快啊,从16年6月本科毕业入职了一家不大的公司,到现在快五年了,前段时间金三银四想着找一个新的工作,前前后后花了一个多月的时间复习以及面试,前几天拿到了腾讯的offer,想把 ...

  8. 2019年6月份,阿里最新Java高频面试真题汇总,仅供参考(附福利)

    目录 技术一面(23问) 技术二面(3大块) JAVA开发技术面试中可能问到的问题(17问) JAVA方向技术考察点(33快) 项目实战(7大块) 必会知识(48点) 面试小技巧 注意事项 1. 阿里 ...

  9. 【转】2019年7月份,阿里最新Java高频面试真题汇总

    技术一面(23问)技术二面(3大块)JAVA开发技术面试中可能问到的问题(17问)JAVA方向技术考察点(33快)项目实战(7大块)必会知识(48点)面试小技巧注意事项1. 阿里技术一面 Java I ...

随机推荐

  1. 将ImageMagic库编译进nginx

    1.首先要将ImageMagick库的相应头文件加到环境变量中 export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/ImageMagick/include ...

  2. Python+Appium运行简单的demo,你需要理解Appium运行原理!

    坚持原创输出,点击蓝字关注我吧 作者:清菡 博客:oschina.云+社区.知乎等各大平台都有. 目录 一.Appium 的理念 四个原则 1.Web-Selenium 的运行原理 2.Appium ...

  3. Ubuntu16.04 Nvidia显卡驱动简明安装指南

    简单得整理了一下Ubuntu16.04 Nvidia显卡驱动的安装步骤: 查看当前系统显卡参数: sudo lspci | grep -i nvidia 删除之前的驱动: sudo apt-get - ...

  4. 基础篇:Object对象

    目录 1 Object的内存结构和指针压缩了解一下 2 Object的几种基本方法 3 == . equals.Comparable.compareTo.Comparator.compara 四种比较 ...

  5. 基于mockito做有效的单元测试

    概述 本文讲解的主要是有效和单元的思想,并不是说如何编写单元测试,用于改善和提高开发效率.编码风格.编码可读性和单测效率,不盲目追求覆盖率. 背景 现在很多单元测试只是利用@Test注解把代码或者整个 ...

  6. CTFshow_Web入门源码

    Web1 题目打开始是这样的 直接看源码 Web2 题目打开是这样的,右键无法打开菜单,无法查看源码,F12也不可以 更改JavaScript权限,即可查看源码 Web3 真就抓个包看看 Web4 访 ...

  7. Codeforces Global Round 11 A~D题解

    A.Avoiding Zero 题目链接:https://codeforces.ml/contest/1427 题目大意:给定一个数组a1,a2...,an,要求找出一个a重排后的数组b1,b2,.. ...

  8. 4-K8S 部署Java应用及应用程序生命周期管理

    1.在kubernetes中部署应用程序流程 准备项目源码-->编译构建-->产出war包,打包到镜像中-->推送到镜像仓库 获取源代码是开发人员提交代码的代码托管地址,有Git.S ...

  9. docker容器命令1

    docker容器命令 新建并启动容器命令 docker run INAME(镜像名字) 语法:docker run [OPTIONS] INAME [COMMAND] 例子:docker run -i ...

  10. Oracle体系结构概述与SQL解析剖析

    Oracle服务器 是一个数据库管理系统,它提供了一种全面.开放.集成的方法来管理信息. Oracle服务器由Oracle数据库和Oracle实例组成. oracle数据库软件和Oracle数据库软件 ...