阿里经典面向对象面试题升级版(推荐看)

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: 阿里经典面向对象面试题升级版(推荐看)

前言


此题目为几年前阿里首创,此题一出就制造了面试中"惨案"。该题有可能你能说出结果,但你未必能说清楚原因。


我查阅了部分关于此题的解析,好多就是迷迷糊糊就给讲完了,根本没抓住问题核心,因此阿包也献上一篇自己的理解,希望能为正确一方添加一票,这样大家搜索到正确频率又能提高一点。


下面是原版阿里真题和解析:


传送门: 阿里题目链接


题目


分析


该题目涉及到的知识非常多,比如: 作用域、预编译、原型与原型链、new、事件循环。

我们首先来分析一下,该题上半部分到底做了些什么:


  1. 定义 test 函数
  2. test 函数创建一个静态方法 test.getName
  3. test 函数创建一个实例方法 test.prototype.getName
  4. 定义全局变量 getName,程序运行后赋值为 函数
  5. 定义全局函数 getName
  6. test 函数内部给全局变量 getName 赋新值,返回值为 this


与原题目相比,当前题目加入了事件循环的知识, Promise.thensetTimeout 都是异步任务,前者是微任务,后者为宏任务。


解析


预编译


  1. 函数预编译四部曲和全局预编译三部曲
  2. 变量声明,声明提升函数声明,整体提升


GO: {
    test: fn,
    getName: function getName() { console.log(6); }
}
复制代码


test.getName()


执行 test 函数上的静态方法 test.getName ,打印 3,setTimeout 的回调插入事件队列中,等待同步任务执行完毕


getName()


getName 执行之前, getName 已经被重新赋值为 console.log(5) ,打印 5


test().getName()


  1. test() 执行全局的 test 函数,修改全局 getName 值; test() 函数执行为默认绑定,非严格模式 this 指向 window ,返回值为 window


GO: {
    test: fn,
    // 全局 getName 值修改
    getName: function() { 
        Promise.resolve().then(() => console.log(0))
        console.log(1);               
    };
}
复制代码


  1. test().getName() 相当于执行 window.getName() ,调用 GO 中的 getNamePromise.then 压入微任务队列,打印 1


getName()


执行全局函数 getName() ,打印 1Promise.then 压入微任务队列


(⭐)new 知识补充


在进行后面题目的解析时,先补充一点关于 new 运算符的知识。


首先咱们来看一下 MDN 中对 new 的描述,语法是:


new constructor[([arguments])]
复制代码


([arguments]) 意味着可以缺省,会存在 new constructor(...args)new constructor 两种模式,并且前者的运算优先级高于后者。更详细的优先级见下图:


image.png


从上图可以看到,部分优先级如下:new(带参数列表) = 成员访问 = 函数调用 > new(不带参数列表)


new test.getName()


根据上面的知识,表达式中自左向右共有三个运算符: new 不带参数列表、成员访问、函数调用。


优先级相同的运算符执行顺序自左向右,因此先执行成员访问,获取到 test 函数上的静态方法 getName


成员访问之后,表达式相当于变为 new (test.getName)()new 操作符由不带参数列表变为带参数列表,自左向右执行,把 test.getName 视为构造函数,生成对应实例。


new (test.getName)() 执行,打印 3setTimeout 回调压入宏任务队列。


new test().getName()


表达式运算符自左向右分别为: new 带参数列表、成员访问、函数调用


  1. 执行 new test(): new 绑定, this 指向实例。
  2. new 生成实例上没有 getName 属性,沿原型链查找到 test.prototype.getName 属性,打印 4


new new test().getName()


表达式运算符自左向右分别为: new 不带参数、new 带参数、成员访问、函数调用

因此表达式可以转化为如下形式: new((new test()).getName())


  1. new test().getName: 访问到 test.prototype.getName 属性
  2. new new test().getName(): 以 test.prototype.getName 为构造函数,打印 4


Promise.then


执行微任务队列里的 promise.then ,微任务队列中共有两次 promise.then ,打印 20


setTimeout


执行宏任务队列里的 setTimeout 回调函数,打印 22


答案


3
5
1
1
3
4
4
0
0
2
2
复制代码


往期精彩文章



后语


如果大家感觉此文对你有一些帮助,希望能点个赞,鼓励一下阿包,阿包会不断努力的。另外如果本文章有问题,或者对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!


相关文章
|
7月前
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
6月前
|
监控 Java 数据安全/隐私保护
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
|
5月前
|
负载均衡 架构师 Cloud Native
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选  CP 还是 AP?为什么?
|
6月前
|
SQL Java 数据库连接
阿里腾讯互联网公司校招 Java 面试题总结及答案解析
本文总结了阿里巴巴和腾讯等互联网大厂的Java校招面试题及答案,涵盖Java基础、多线程、集合框架、数据库、Spring与MyBatis框架等内容。从数据类型、面向对象特性到异常处理,从线程安全到SQL优化,再到IOC原理与MyBatis结果封装,全面梳理常见考点。通过详细解析,帮助求职者系统掌握Java核心知识,为校招做好充分准备。资源链接:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
196 2
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
11月前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
8月前
|
存储 NoSQL Redis
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 +  无锁架构 +  EDA架构  + 异步日志 + 集群架构
|
8月前
|
存储 算法 架构师
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案