一些被问到的面试题(xcx)

421 阅读16分钟

购物车总结计算实现的方式

首先判断购物车当中的商品是否被选中,把选中的商品取到放入一个数组当中,然后把数组传入后台,后台将满减优惠券等计算完成,再返回给前端最终总价,然后我们再回显到页面上

  1. 初始化获取商品列表 /p/shopCart/info
  2. 计算总价 发送购物车商品ID数组 =》返回总价、减额、总额 /p/shopCart/totalPay

小程序的优化方式

  1. 首屏时间
    首屏时间是指用户从打开小程序看到第一屏主要内容的时间,首屏时间太长会导致用户长时间看到的都是白屏,影响使用体验。
  2. 脚本执行时间
    脚本执行时间是指JS脚本在一次同步执行中消耗的时间,比如生命周期回调、事件处理函数的同步执行时间。
  3. setData调用频率
    setData接口的调用涉及逻辑层与渲染层间的线程通信,通信过于频繁可能导致处理队列阻塞,界面渲染不及时而导致卡顿,应避免无用的频繁调用。
  4. setData数据大小
    由于小程序运行逻辑线程与渲染线程之上,setData的调用会把数据从逻辑层传到渲染层,数据太大会增加通信时间。
  5. 图片缓存
    开启 HTTP 缓存控制后,下一次加载同样的图片,会直接从缓存读取,大大提升加载速度。
  6. 图片大小
    图片太大会增加下载时间和内存的消耗,应根据显示区域大小合理控制图片大小。 得分条件:图片宽高乘积 <= 实际显示宽高乘积 * (设备像素比 ^ 2)
  7. 网络请求数
    短时间内发起太多请求会触发小程序并行请求数量的限制,同时太多请求也可能导致加载慢等问题,应合理控制请求数量,甚至做请求的合并等。
  8. 图片请求数
    短时间内发起太多图片请求会触发浏览器并行加载的限制,可能导致图片加载慢,用户一直处理等待。应该合理控制数量,可考虑使用雪碧图技术或在屏幕外的图片使用懒加载。

防抖怎么实现

防抖是指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。(就是在触发某个事件后,在下一次触发之前,中间的间隔时间如果超过设置的时间才会发送请求,一直触发就不会发送请求) 主要应用场景有:
a、scroll事件滚动触发,
b、搜索框输入查询
c、表单验证
d、按钮提交事件
e、浏览器窗口缩放,resize事件

节流是指如果持续触发某个事件,则每隔n秒执行一次。

小程序拦截器的实现方式

从请求和响应两方面来说

搜索功能怎么实现

拿到搜索框中的内容,跳转到搜索结果页面,搜索结果页面在onload中拿到搜索框中的内容,再去搜索内容,并展示搜索到的内容

  1. 获取全局热搜
  2. 搜索历史缓存在本地 读取和存储
  3. 点击历史搜索 或则 搜索 跳转商品列表页

搜索的历史记录怎么实现

将每次搜索的内容存入到本地存储当中,并渲染到历史记录当中,并且在存入本地存储当中做一下去重,并且在搜索记录过多时将过去的搜索记录清除一部分

  1. 点击搜索后,以搜索商品名称组成的数组,缓存在本地存储
  2. 进入页面从本地获取搜索历史记录

下拉加载怎么实现

全局开启下拉刷新:在app.json--->window--->enablePullDownRefresh设置为true, onPullDownRefresh和onReachBottom方法实现小程序下拉加载和上拉刷新

  scroll-view里面有一个bindscrolltoupper属性  会触发 scrolltoupper 事件,所以我们可以利用这个属性,
 来实现下拉刷新功能。 

小程序的像素单位和h5的区别

px和rpx的区别,rpx就相当于h5当中的rem,比如一般移动端常用的开发型号 iphone6/7/8当中,375的屏幕宽度下,1rpx大致相当于0.5px

  1. 计算方式不同 在微信小程序中, 1rem = 设计稿宽度/20 ; 而在HTML5中,1rem的值是用js根据页面宽度动态设置文档根元素得来的。
  2. rpx实际上就是系统级的rem(把页面按比例分割750份,1rpx=window.innerWidth/750)。也就是说,微信小程序的rpx布局把rem布局的js设置根元素字体尺寸这步省了。
  3. HTML5和微信小程序实现自适应的方式不同。微信小程序只要使用rpx单位进行布局,就可以实现自适应布局。而HTML5需要先用js根据页面宽度动态设置。 比如在html标签中:1rem = 100px; 那么在body标签中的元素,宽为50px时,需要设置成 0.5rem(50/100);

用户授权登录怎么实现

  • 小程序 wx.checkSession 校验登陆态

    • success :接口调用成功,session_key未过期;
    • fail :接口调用失败,session_key已过期;
  1. 小程序端 wx.login 获取code 并 wx.request 提交 code 给己方服务器
  2. 服务器 提交Appid + appSecret + code 到微信方服务器 获取 session_key & openid
  3. 服务器 根据 session_key & openid 生成 3rd_session(微信方提出的基于安全性的考虑,建议开发者不要将openid等关键性信息进行数据传输) 并返回 3rd_session 到小程序端
  4. 小程序端 wx.setStorage 存储 3rd_session 在后续用户操作需要凭证时 附带该参数
  5. 小程序端 wx.getUserInfo 获取用户信息 + wx.getStorage 获取 3rd_session 数据后,一并 wx.request 提交给己方服务器
  6. 服务器 SQL 用户数据信息更新 image.png

小程序目录下的4个文件的作用

  • index.js 页面逻辑
  • index.json 页面配置
  • index.wxml 页面结构
  • index.wxss 页面样式

navigateTo和redirectT的区别

  • wx.navigateTo(object):保留当前页面,跳转到应用的某个页面;
  • wx.redirectTo(object):关闭当前页面,跳转到应用内的某个页面。
  • wx.reLauch(object):关闭所有页面,打开到应用内的某个页面 。
  • wx.navigateBack(object)关闭当前页面,返回上一页面或者多级页面。
  • wx.switchTab(object),跳转到新的tabBar页面。并关闭其他页面;

关闭定时器和释放内存在哪里操作

wx.setinterval(function(){},durtion)函数可以产生一个定时执行的函数,返回代表定时器的int值
clearinterval(interval)可以清除定时器。
在onUnload监听页面卸载生命周期函数中清除。

小程序的发版流程

  • 上传代码,在代码编写完毕后,在他顶部的导航条上找到【上传】
  • 提交审核,进入他们的官网,进入【开发管理】,找到刚才提交的版本,点击提交审核
  • 发布版本

小程序的微信后台的主要配置项 ?

配置app。json?还是在网页配置小程序id或者合法域名(https)?

小程序的埋点怎么操作

  • 一般来说埋点是个重后轻前的,前端一般将收集到的数据发送给后台,
  • 在生命周期当中或在用户的点击事件当中,例如把点击最多的地方发送给后台,增强用户体验(C端比较常用) www.infoq.cn/article/bwh… juejin.cn/post/703630…

小程序的分享功能怎么实现

button有个属性是open-type,值为share就是分享,

支付功能怎么实现

理解图的思路

QQ图片20220302150101.jpg

小程序怎么调用地图

wx.chooseLocation(Object object) 添加地图组件,那么只需要添加一个,然后我们需要给这个组件添加一些属性来丰富这个地图。调整大小,

  • 指南针 选填在map组件中,添加属性show-compass,默认是不显示出来的,当地图在俯视、旋转等情况下,指南针会自动显示出来,点击指南针,会回到垂直和正北的状态。

  • 比例尺 选填添加show-scale,左下角自动显示比例尺。官文中写2.8.0暂不支持,但是实际上我在真机中调试可以出现比例尺

  • 显示带方向的当前定位点 选填添加show-location,这个从1.0.0就开始支持了,所以很稳定

  • 设置地图初始中心位置 必填填写longitude和latitude这两个属性,经纬度都是gcj02 坐标系的(国测坐标系),对wgs84的经纬度进行加密,一般的电子地图都会支持该坐标系的坐标转换。

  • 设置地图比例尺 选填scale 默认是16,取值范围在3-20。

  • 设置地图旋转角度 选填rotate,范围 0 ~ 360, 地图正北和设备 y 轴角度的夹角,允许旋转才有效- 设置地图倾斜角度 选填skew,倾斜角度,范围 0 ~ 40 , 关于 z 轴的倾角,允许俯视才有效

  • 允许3D楼块 选填 enable-3D 同样官文说暂不支持,实际上已经可以,缩放级别够大,可以看到效果

  • 允许俯视 选填enable-overlooking 同样两指下滑

  • 允许缩放 选填enable-zoom,默认开启

  • 允许拖动 选填enable-scroll,默认开启

  • 允许旋转 选填enable-rotate

  • 开启卫星图 选填enable-satellite

  • 开启实时路况 选填enable-traffic

  • 显示点线面 选填点是用markers来表示,markers是由marker组成的数组,每个marker可以定义坐标、id、title还有label等属性,根据用户需要来设置。 线是polyline,由点集构成,默认是不会首尾相连的。可以设置线的样式。 面有两种,一种是circles,一种是polygons,同理,可以绘制多圆和多面

  • 视野包含坐标点 选填include-points,需要填point数组。

官网地址 developers.weixin.qq.com/miniprogram…

怎么获取用户的手机号

具体看 open-type developers.weixin.qq.com/miniprogram…

小程序直播的实现方式及限制

developers.weixin.qq.com/miniprogram…

小程序直播限制

  1. 必须是商家
  2. 直播内容必须是小程序运行直播的类别
  3. 账号商家主体半年内没有严重违规
  4. 小程序近90天内有过支付行为

骨架屏的优势

围绕用户体验来说,就像是当数据没有加载出来的时候给用户展示一个loading图的意思是一样的,让用户等待的过程中不会太无聊

高负载情况小程序怎么优化

  • 分包
  • 相当于小程序的性能优化

怎么接收后台的推送

小程序的消息推送很简单,主要把几个步骤理清就好了。

  • 在小程序的微信开发平台上配置服务器
  • 前端传递必要参数
  • 后端实现推送功能

用户足迹的实现思路

  • 记录页面停留时间、功能点击次数
  • 创建个足迹文件用于记录

倒计时器怎么实现和销毁

wx.setinterval(function(){},durtion)函数可以产生一个定时执行的函数,返回代表定时器的int值
clearinterval(interval)可以清除定时器。
在onUnload监听页面卸载生命周期函数中清除。

修改头像功能怎么实现

从头申请一个小程序的步骤

扫码注册一个小程序账号,设置小程序的id,生成自己的小程序

小程序的生命周期

  • onLoad  :  页面加载时触发。一个页面只会调用一次,可以在 onLoad的参数中获取打开当前页面路径中的参数
  • onShow :   页面显示 / 切入前台时触发调用。
  • onReady :  页面初次渲染完成时触发,一个页面只会调用一次。
  • onHide : 页面隐藏 / 切入后台时触发,如 navigateTo 或底部tab切换到其他页面,小程序切入后台等
  • onUnload : 页面卸载时触发。如 redirectTo或 navigateBack 到其他页面时.

客服功能怎么实现

  1. button open-type=contact
  2. 手动实现使用 socket.io

类组件的优化方式

  • shouldComponentUpdate避免重复渲染
  • 组件尽可能的进行拆分、解耦
  • 列表类组件优化,添加key值
  • props尽量只传需要的数据,避免多余的更新,尽量避免使用{...props}

hooks的使用及优化方式

  • useMemo useCallback 区别
  • useCallback或者useEffect依赖项问题
  • useEffect和useLayoutEffect区别

promise和async await的理解

异步的解决方案

单页面应用的理解

只有一张Web页面的应用,是一种从Web服务器加载的富客户端,单页面跳转仅刷新局部资源 ,公共资源(js、css等)仅需加载一次,常用于PC端官网、购物等网站

如图:

单页面应用结构视图

单页面应用结构视图

加载优化的方式有哪些

redux-saga的使用方式

redux-saga 是一个用于管理 Redux 应用异步操作的中间件(又称异步 action)。 redux-saga 通过创建 Sagas 将所有的异步操作逻辑收集在一个地方集中处理,可以用来代替 redux-thunk 中间件。

  • Reducers 负责处理 action 的 state 更新
  • Sagas 负责协调那些复杂或异步的操作

Sagas是通过Generator函数来创建的,如果有不熟悉 Generator函数使用的,

Effect Creators

redux-saga框架提供了很多创建effect的函数,下面我们就来简单的介绍下开发中最常用的几种

  • take(pattern)

  • put(action)

  • call(fn, ...args)

  • fork(fn, ...args)

  • select(selector, ...args)

  • take函数可以理解为监听未来的action,它创建了一个命令对象,告诉middleware等待一个特定的action, Generator会暂停,直到一个与pattern匹配的action被发起,才会继续执行下面的语句,也就是说,take是一个阻塞的 effect

  • put函数是用来发送action的 effect,你可以简单的把它理解成为redux框架中的dispatch函数,当put一个action后,reducer中就会计算新的state并返回,注意: put 也是阻塞 effect

  • call函数你可以把它简单的理解为就是可以调用其他函数的函数,它命令 middleware 来调用fn 函数, args为函数的参数,注意: fn 函数可以是一个 Generator 函数,也可以是一个返回 Promise 的普通函数,call 函数也是阻塞 effect

  • fork 函数和 call 函数很像,都是用来调用其他函数的,但是fork函数是非阻塞函数,也就是说,程序执行完 yield fork(fn, args) 这一行代码后,会立即接着执行下一行代码语句,而不会等待fn函数返回结果后,在执行下面的语句

  • select 函数是用来指示 middleware调用提供的选择器获取Store上的state数据,你也可以简单的把它理解为redux框架中获取store上的 state数据一样的功能 :store.getState()

购物车怎么处理商品是否无货

无货的时候可以提示一下,然后无法加入购物车无法结算,可以让按钮无法点击

authorization: token的作用

header里面放Authorization,就是为了验证用户身份,现在前后端分离,有跨域问题,session经常会失效
所以使用了token来验证用户身份(目前只知道可以用于验证用户身份)
token和session拥有同一功能就是判断当前用户是不是之前登录了的用户
比如你登陆后,在同一浏览器不同页面打开同一网址,你想跳过登录环节
这时候因为跨域问题,发送给后台的session会是一个新的session
服务器没法通过session来验证你的身份,所以服务器的过滤器(或拦截器)会过滤掉你的请求,让你返回登陆界面重新登录,使用户体验变差


Authorization里面放的就是token,就相当于每次发送请求的时候,拦截器都会拦截一次你的请求,
把你请求头部的Authorization拿出来,与当前存在服务器上的token做对比
如果是同一个,则证明是同一用户,然后拦截器就为你当前的请求放行,继续执行你的请求
如果不是同一个,那么服务器会截断你的请求并发送错误码给前端,让前端验证身份重新登陆

vue和react的区别

数据流:

react主张函数式编程,所以推崇纯组件,数据不可变,单向数据流,

vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。

监听数据变化实现原理

  • Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能
  • React 默认是通过比较引用的方式进行的,如果不优化(PureComponent/shouldComponentUpdate)可能导致大量不必要的VDOM的重新渲染。

组件通信的区别:jsx和.vue模板。

  • HoC和Mixins(在Vue中我们组合不同功能的方式是通过Mixin,而在React中我们通过HoC(高阶组件))。

性能优化

  • React: shouldComponentUpdate
  • Vue:内部实现shouldComponentUpdate的优化,由于依赖追踪系统存在,通过watcher判断是否需要重新渲染(当一个页面数据量较大时,Vue的性能较差,造成页面卡顿,所以一般数据比较大的项目倾向使用React)。

vue双向数据绑定的机制

当一个Vue实例创建时,Vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher重新计算,从而致使它关联的组件得以更新

虚拟dom的diff算法的了解

虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象表现。 状态变更时,记录新树和旧树的差异 最后把差异更新到真正的domrender函数:

  1. 根据tagName生成父标签,读取props,设置属性,如果有content,设置innerHtml或innerText,
  2. 如果存在子元素,遍历子元素递归调用render方法,将生成的子元素依次添加到父元素中,并返回根元素。

bindtap和catchtap的区别

除 bind 外,也可以用 catch 来绑定事件。与 bind 不同, catch 会阻止事件向上冒泡。

  1. 相同点: 首先他們都是点击触发事件函数。作用一样。
  2. 不同点:bindtap 是冒泡的,catchtap 不冒泡

什么叫冒泡?

事件由子元素传递到父元素的过程,叫做冒泡

vue的mixin怎么使用

  1. 定义一个 js 文件(mixin.js)

image.png 2. 2.在vue文件中使用mixin

image.png

mixins的特点

方法和参数在各组件中不共享

原型和原型链的理解

  • 所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
  • 所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
  • 所有引用类型的__proto__属性指向它构造函数的prototype

image.png

小程序webview怎么使用

定义:它是一个承载网页的容器,会自动铺满整个页面

  • src : webview 指向网页的链接。可打开关联的公众号的文章,其它网页需登录小程序管理后台配置业务域名。
  • bindmessage : 网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息。e.detail = { data },data是多次 postMessage 的参数组成的数组
  • bindload : 网页加载成功时候触发此事件。e.detail = { src }
  • binderror : 网页加载失败的时候触发此事件。e.detail = { src } developers.weixin.qq.com/miniprogram… segmentfault.com/a/119000003… juejin.cn/post/692084…