介绍目前常见其他面试题
编程题
广度优先搜索如何遍历一棵树,算法,说思路
以上的这几种遍历都可以称之为深度遍历,对应的还有种遍历叫做广度遍历,也就是一层层地遍历树。对于广度遍历来说,我们需要利用之前讲过的队列结构来完成
1 | breadthTraversal() { |
其他问题
乐观锁和悲观锁
参考连接:https://blog.csdn.net/weixin_44045828/article/details/126169360
乐观锁和悲观锁是两种思想,用于解决并发场景下的数据竞争问题。
- 基本概念:
- 乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。
- 悲观锁:悲观锁在操作数据时比较悲观,认为别人会同时修改数据。因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。
实现方式:
注意:乐观锁和悲观锁是两种思想,它们的使用是非常广泛的,不局限于某种编程语言或数据库。
悲观锁的实现方式是加锁,加锁既可以是对代码块加锁(如Java的synchronized关键字),也可以是对数据加锁(如MySQL中的排它锁)。
乐观锁的实现方式主要有两种:CAS机制和版本号机制。
1、CAS(Compare And Swap)
CAS操作包括了3个操作数:需要读写的内存位置(V)、进行比较的预期值(A)、拟写入的新值(B)。
CAS操作逻辑如下:如果内存位置V的值等于预期的A值,则将该位置更新为新值B,否则不进行任何操作。
许多CAS的操作是自旋的:如果操作不成功,会一直重试,直到操作成功为止。
这里引出一个新的问题,既然CAS包含了Compare和Swap两个操作,它又如何保证原子性呢?
答案是:CAS是由CPU支持的原子操作,其原子性是在硬件层面进行保证的。
下面以Java中的自增操作(i++)为例,看一下悲观锁和CAS分别是如何保证线程安全的。
我们知道,在Java中自增操作不是原子操作,它实际上包含三个独立的操作:(1)读取i值;(2)加1;(3)将新值写回 i 因此,如果并发执行自增操作,可能导致计算结果的不准确。
在下面的代码示例中:value1没有进行任何线程安全方面的保护,value2使用了乐观锁(CAS),value3使用了悲观锁(synchronized)。运行程序,使用1000个线程同时对value1、value2和value3进行自增操作,可以发现:value2和value3的值总是等于1000,而value1的值常常小于1000。
2、版本号机制
除了CAS,版本号机制也可以用来实现乐观锁。版本号机制的基本思路是在数据中增加一个字段version,表示该数据的版本号,每当数据被修改,版本号加1。当某个线程查询数据时,将该数据的版本号一起查出来;当该线程更新数据时,判断当前版本号与之前读取的版本号是否一致,如果一致才进行操作。需要注意的是,这里使用了版本号作为判断数据变化的标记,实际上可以根据实际情况选用其他能够标记数据版本的字段,如时间戳等。
- 优缺点及其适用场景
- 乐观锁和悲观锁并没有优劣之分,它们有各自适合的场景;下面从两个方面进行说明。
- 1、功能限制:与悲观锁相比,乐观锁适用的场景受到了更多的限制,无论是CAS还是版本号机制。例如,CAS只能保证单个变量操作的原子性,当涉及到多个变量时,CAS是无能为力的,而synchronized则可以通过对整个代码块加锁来处理。再比如版本号机制,如果query的时候是针对表1,而update的时候是针对表2,也很难通过简单的版本号来实现乐观锁。
- 2、竞争激烈程度:如果悲观锁和乐观锁都可以使用,那么选择就要考虑竞争的激烈程度。当竞争不激烈 (出现并发冲突的概率小)时,乐观锁更有优势,因为悲观锁会锁住代码块或数据,其他线程无法同时访问,影响并发,而且加锁和释放锁都需要消耗额外的资源。当竞争激烈(出现并发冲突的概率大)时,悲观锁更有优势,因为乐观锁在执行更新时频繁失败,需要不断重试,浪费CPU资源。
- 乐观锁加锁吗?
- 乐观锁本身是不加锁的,只是在更新时判断一下数据是否被其他线程更新了;
AtomicInteger
便是一个例子。 - 有时乐观锁可能与加锁操作合作,例如,在前述
updateCoins()
的例子中,MySQL在执行update时会加排它锁。但这只是乐观锁与加锁操作合作的例子,不能改变“乐观锁本身不加锁”这一事实。
- 乐观锁本身是不加锁的,只是在更新时判断一下数据是否被其他线程更新了;
怎么统计从百度过来访问当前的页面的浏览数量
在网站建设完成后,很多人都希望统计到网站的访问情况,如访问了哪个页面、页面停留时间、访问者的IP地址以及访问设备、访问者所在的省份区域、访问来源等诸多信息,要实现这种功能可以自行编写代码,从http请求信息中获取,也可使用百度统计的功能进行快速开发实现。百度统计是百度推出的一款免费的专业网站流量分析工具。
(1)自行开发统计功能
可以自行编写代码从请求信息中获取用户的相关信息,如用户的访问设备、用户IP、用户访问的页面等情况,这一系列的代码开发涉及到比较多的东西,在此文章中不详细阐述,读者可自行查阅网上相关资料即可获取。
(2)使用百度统计功能
百度统计是百度推出的一款免费的专业网站流量分析工具,能够告诉用户访客是如何找到并浏览用户的网站,在网站上做了些什么,有了这些信息,可以帮助用户改善访客在用户的网站上的使用体验,不断提升网站的投资回报率。
使用的步骤是:进入百度统计官网,注册好相应的百度账号登录后,进入管理页面,添加你的网站,如下图:
添加完毕后,左侧树形菜单中有个代码管理–代码获取的菜单,或者从网站记录中的右侧获取代码进入。
进入获取代码页面后,页面上有一段该网站特有的Javascript
统计代码,按照提示将该代码添加到标签前即可
上述代码安装成功后,一般20分钟后,即可登录百度统计查看相应的网站分析数据。
面试题目
百度一面
- 自我介绍
- html语义化标签有啥用,列举几个
- css响应式布局设计思想
- css弹性布局几种方式
- 行内元素和块级元素,列举?区别?
- Array的api列举
- Vue的生命周期,父子组件产生顺序
- Vue组件通信方式
- 项目遇到的难点
- 如何设计一个组件
- es6新特性?
- js数据类型
- 怎么判断js数据类型,几种?
- js内存泄漏怎么造成的?如何避免?
- css单位几种?区别?
百度二面
- 自我介绍
- 广度优先搜索如何遍历一棵树,算法,说思路
- js数字不足6为前补0如何实现,多种方式?
- websocket对比http?
- Array常用api
- 如何删除指定index的数组元素
- Vue双向绑定原理?
- 如何实现浅拷贝和深拷贝?
- Promise了解吗,好处?封装过吗?
- es6新特性
- ts对比js?
- Vue2和Vue3?
- 封装过组件吗?能写一个吗?
滴滴一面
- 自我介绍
- 后端了解多少
- websocket断开连接咋办
- es6
- Array和Object的常用API
- Promise的all和race了解吗,场景?
- 防抖和节流了解吗,怎么实现?
- 如何水平垂直居中对齐
- flex的align-item和align-content区别
- bind和apply,call区别
- 箭头函数对比普通函数
- v-if和v-show
- 浏览器缓存
- http缓存
- 如何画一个三角形
- 跨域
- css选择器哪些
- 手写一个数组去重,不用new set
实习、大概50分钟
自我介绍
实习情况,一些个人规划,个人情况
实习当中比较有挑战的问题,如何解决的?有没有沉淀文档?平时遇到问题怎么解决?
工作上有没有遇到棘手的问题?
工作上的需求文档介绍一下?
工作上对一些产品设计等方面有没有自己的看法,并且怎么处理的?
平时有没有看过一些代码风格?
手写节流? 防抖?
手写 apply?
koa 的源码介绍一下? 洋葱模型?
微信小程序的原理有没有了解过?
有没有写过 react 的类编程?
react 的 hooks 和 vue 的composition API 的异同?
巴拉巴拉聊算法,面试官很有趣,很随和,聊了很多关于这方面的,本来以为会问我算法,结果没问,就是聊了很久的算法,dp,链表,树,聊的很愉快…
工作上有没有用到过算法?在哪里用到了?
来我们这实习,最主要的目的是什么?
如果来我们这,可能一开始要做一些繁琐的任务,没那么高级,有什么看法?
如果给你一个很难的任务,怎么看待,规定时间内没完成咋办?
反问,我说面试官很年轻哈哈哈~
体验很好,八股没问啥,主要偏实践,聊了蛮久~期待能oc
旷视科技一面
自我介绍
css动画了解吗
BFC有啥好处,为啥用BFC,如何开启BFC
事件循环机制
事件委托原理
typeof和instanceof区别
Vue的computed和watch区别
Vuex采用API,执行原理
闭包,使用场景,你用过吗?
Object.is和===区别
遍历对象属性的几种方式?