沐游虞笔记
  • 前端面试题

    • HTML面试题汇总(无答案)
    • HTML面试题汇总
    • CSS 面试题汇总(无答案)
    • CSS 面试题汇总
    • javascript 面试题汇总(无答案)
    • javascript 面试题汇总
    • promise 面试题(无答案)
    • promise 面试题
    • 浏览器面试题汇总(无答案)
    • 浏览器面试题汇总
    • 网络面试题汇总(无答案)
    • 网络面试题汇总
    • 工程化面试题汇总(无答案)
    • 工程化面试题汇总
    • VUE面试题汇总(无答案)
    • VUE面试题汇总
  • 直播课文件

    • 静态页面学习指导
    • 属性的计算过程
    • 层叠继承规则总结
    • BFC
    • JS基础知识回顾
    • DOM 事件的传播机制
    • DOM 事件的注册和移除
    • 阻止事件默认行为
    • 基础领航考试题
    • 基础领航考试题(答案)
    • 2024前端发展
    • JS核心概念学习指导
    • 第三方库与工程化学习指导
    • Vue入门学习指导
    • vue进阶学习指导
    • 前端性能优化
  • 笔面试环节知识讲解

    • 目录
    • 图像处理
    • 图像处理(面试)
    • Webpack构建优化
    • Webpack构建优化(面试)
    • TTS性能优化
    • TTS性能优化(面试)
    • 实时协作
    • 实时协作(面试)
    • 网页复制图片到剪贴板
    • 网页复制图片到剪贴板(面试)
    • vite插件
    • vite插件(面试)
    • 表单数据同步与保持
    • 表单数据同步与保持(面试)
    • 优化虚拟列表
    • 优化虚拟列表(面试)
    • 微前端解决巨石应用
    • 微前端解决巨石应用(面试)
    • DNS解析与优化
    • DNS解析与优化(面试)
    • 前端监控
    • 前端监控(面试)
    • 12.跨标签页通信
    • 12.跨标签页通信(面试)
    • 13.Vite相关优化
    • 13.Vite相关优化(面试)
    • 14.计时器节流问题
    • 14.计时器节流问题(面试)
    • 15.多文件预览支持
    • 15.多文件预览支持(面试)
    • 16.defer优化白屏时间
    • 16.defer优化白屏时间(面试)
  • Vue3整体变化
  • Vue2响应式回顾
  • Vue3响应式变化
  • nextTick实现原理
  • 两道代码题
  • Vue运行机制
  • 渲染器核心功能
  • 事件绑定与更新
  • computed面试题
  • watch面试题
  • 图解双端diff
  • 图解快速dff
  • 最长递增子序列
  • 模板编译器
  • 模板编译提升
  • 组件name作用
  • 路由传参方式
  • 基础篇

    • 序章React介绍
    • JSX基础语法
    • React基本介绍
    • 表单
    • 生命周期
    • 组件与事件绑定
    • 组件状态与数据传递
    • Hooks
    • React--redux介绍
    • React-router介绍
  • 就业篇

    • 属性默认值和类型验证
    • 高阶组件
    • Ref
    • Context
    • Render Props
    • Portals
    • 错误边界
    • 组件渲染性能优化
    • 前端框架的理解
    • Reacti和Vue描述页面的区别
    • 前端框架的分类
    • 虚拟DoM
    • React整体架构
    • React渲染流程
    • Fiber双缓冲
    • MessageChannel
    • Scheduleri调度普通任务
    • Scheduleri调度延时任务
    • 最小堆
    • React中的位运算
    • beginWork工作流程
    • completeWork工作流程
    • 图解diff算法
    • commit工作流程
    • lane模型
    • React中的事件
    • Hooks原理
    • useStateuseReducer.
    • effect相关hook
    • useCallbackuseMemo
    • useRef
    • Update
    • 性能优化策略之eagerState
    • 性能优化策略之bailout
    • bailoutContextAPl
    • 性能优化对日常开发启示
  • 前端监控概述
  • 错误监控
  • 数据上报
  • 页面性能监控
  • 用户行为收集与埋点
  • CSS3手册
  • HTML5手册
  • JavaScript语言提升

    • es补充
    • 事件循环
    • promise基础
    • Promise的链式调用
    • Promise的静态方法
    • async和await
    • Promise相关面试题
  • 网络

    • 客户端与服务器
    • 关于 Apifox 的使用
  • git文档
  • 工程化

    • CommonJS
    • ES module
    • npm文档(包管理)
    • Lass笔记
    • webpack工具
  • canvas详解
  • uinapp笔记
  • 自动化测试
  • oauth2令牌

    • 认识Oauth2
    • 三方应用实现github授权
    • 微信三方应用登录实现
    • 支付宝沙箱支付功能
  • 前端面试题

    • HTML面试题汇总(无答案)
    • HTML面试题汇总
    • CSS 面试题汇总(无答案)
    • CSS 面试题汇总
    • javascript 面试题汇总(无答案)
    • javascript 面试题汇总
    • promise 面试题(无答案)
    • promise 面试题
    • 浏览器面试题汇总(无答案)
    • 浏览器面试题汇总
    • 网络面试题汇总(无答案)
    • 网络面试题汇总
    • 工程化面试题汇总(无答案)
    • 工程化面试题汇总
    • VUE面试题汇总(无答案)
    • VUE面试题汇总
  • 直播课文件

    • 静态页面学习指导
    • 属性的计算过程
    • 层叠继承规则总结
    • BFC
    • JS基础知识回顾
    • DOM 事件的传播机制
    • DOM 事件的注册和移除
    • 阻止事件默认行为
    • 基础领航考试题
    • 基础领航考试题(答案)
    • 2024前端发展
    • JS核心概念学习指导
    • 第三方库与工程化学习指导
    • Vue入门学习指导
    • vue进阶学习指导
    • 前端性能优化
  • 笔面试环节知识讲解

    • 目录
    • 图像处理
    • 图像处理(面试)
    • Webpack构建优化
    • Webpack构建优化(面试)
    • TTS性能优化
    • TTS性能优化(面试)
    • 实时协作
    • 实时协作(面试)
    • 网页复制图片到剪贴板
    • 网页复制图片到剪贴板(面试)
    • vite插件
    • vite插件(面试)
    • 表单数据同步与保持
    • 表单数据同步与保持(面试)
    • 优化虚拟列表
    • 优化虚拟列表(面试)
    • 微前端解决巨石应用
    • 微前端解决巨石应用(面试)
    • DNS解析与优化
    • DNS解析与优化(面试)
    • 前端监控
    • 前端监控(面试)
    • 12.跨标签页通信
    • 12.跨标签页通信(面试)
    • 13.Vite相关优化
    • 13.Vite相关优化(面试)
    • 14.计时器节流问题
    • 14.计时器节流问题(面试)
    • 15.多文件预览支持
    • 15.多文件预览支持(面试)
    • 16.defer优化白屏时间
    • 16.defer优化白屏时间(面试)
  • Vue3整体变化
  • Vue2响应式回顾
  • Vue3响应式变化
  • nextTick实现原理
  • 两道代码题
  • Vue运行机制
  • 渲染器核心功能
  • 事件绑定与更新
  • computed面试题
  • watch面试题
  • 图解双端diff
  • 图解快速dff
  • 最长递增子序列
  • 模板编译器
  • 模板编译提升
  • 组件name作用
  • 路由传参方式
  • 基础篇

    • 序章React介绍
    • JSX基础语法
    • React基本介绍
    • 表单
    • 生命周期
    • 组件与事件绑定
    • 组件状态与数据传递
    • Hooks
    • React--redux介绍
    • React-router介绍
  • 就业篇

    • 属性默认值和类型验证
    • 高阶组件
    • Ref
    • Context
    • Render Props
    • Portals
    • 错误边界
    • 组件渲染性能优化
    • 前端框架的理解
    • Reacti和Vue描述页面的区别
    • 前端框架的分类
    • 虚拟DoM
    • React整体架构
    • React渲染流程
    • Fiber双缓冲
    • MessageChannel
    • Scheduleri调度普通任务
    • Scheduleri调度延时任务
    • 最小堆
    • React中的位运算
    • beginWork工作流程
    • completeWork工作流程
    • 图解diff算法
    • commit工作流程
    • lane模型
    • React中的事件
    • Hooks原理
    • useStateuseReducer.
    • effect相关hook
    • useCallbackuseMemo
    • useRef
    • Update
    • 性能优化策略之eagerState
    • 性能优化策略之bailout
    • bailoutContextAPl
    • 性能优化对日常开发启示
  • 前端监控概述
  • 错误监控
  • 数据上报
  • 页面性能监控
  • 用户行为收集与埋点
  • CSS3手册
  • HTML5手册
  • JavaScript语言提升

    • es补充
    • 事件循环
    • promise基础
    • Promise的链式调用
    • Promise的静态方法
    • async和await
    • Promise相关面试题
  • 网络

    • 客户端与服务器
    • 关于 Apifox 的使用
  • git文档
  • 工程化

    • CommonJS
    • ES module
    • npm文档(包管理)
    • Lass笔记
    • webpack工具
  • canvas详解
  • uinapp笔记
  • 自动化测试
  • oauth2令牌

    • 认识Oauth2
    • 三方应用实现github授权
    • 微信三方应用登录实现
    • 支付宝沙箱支付功能
  • 必看导言

    • 就业的核心问题

      • 课件
    • 表现力的训练

      • 课件
  • 简历制作

    • 课件
    • 简历准备课堂笔记
    • 个人信息课堂笔记
    • 求职意向课堂笔记
    • 技术栈课堂笔记
    • 教育经历课堂笔记
    • 个人优势与评价课堂笔记
    • 工作经历课堂笔记
    • 项目
    • 项目亮难点问题

    • 项目经历

  • 项目准备

    • 课件
    • 课件
  • 技术重点

    • 划重点

    • 非技术环节
  • 简历投递和面试准备

    • 简历投递
    • 面试准备
  • 笔面试环节知识讲解
  • 项目准备
  • 难点攻关
  • TTS性能优化
  • 课件资料
luzhichang
2024-09-18
目录

03-面试讲解

# TTS性能优化面试讲解

# 知识点图谱

整个知识点主要分为这么几个部分:

  • 文字分段请求

  • 情绪标记

  • 并发控制

    • 请求取消
  • 设置缓存

image-20240625160603441

# 难点叙述

模拟问题:我看到你的项目亮点里面写的是“优化 TTS 服务性能问题”,你能详细说一下这是啥么?然后讲一下有什么样的性能问题么?并且你这边具体是如何进行优化的?

问题分析

  1. 先解释一下什么是 TTS
  2. 简单介绍一下项目的背景
  3. 描述遇到的问题
  4. 你拿到这个问题你是如何思考的
  5. 你思考出来的落地方案
  6. 落地方案的一个效果

参考答案

TTS 是英语“Text-to-Speech”的缩写,中文就是“文本转语音”。(简单介绍什么是TTS)当时我们这个项目是一个知识分享平台的项目,有点像极客时间那种类型的,一些老师会分享一些知识的的文档,然后文档支持在线语音播放功能。(项目的背景)

由于 WebAPI 的语音转换太单板了,所以我们当时选择的是科大讯飞的 TTS 服务,不过会遇到这么一些问题:

  1. 文本过大导致转换时间过长
  2. 转换出来的音频数据过大,传输也比较耗时
  3. 需要根据文本内容给语音添加情绪

(描述遇到的问题)

我主要就是针对这些问题来进行优化。那么首先第一个问题和第二个问题其实是同一个问题,文本过大,自然传输到 TTS 服务所花费的时间就会越久,而且自然生成的音频数据也就越大,而且这一块儿用的是第三方服务平台,我是没法下手的。所以我就想到了从文本方面下手,将文本分段之后在发送请求,这样就大大降低了转换时间,并且转换出来的音频数据也不会太大。

另外因为文本分段了,所以大小虽然变小了,但是数量变多了,所以这一块儿我考虑使用并发的方式来发送,这样速度会更快一些。不过这里面都还有一些细节在里面。(钩子🪝)

至于添加情绪标记,这个前端不太好处理,涉及到自然语言的处理,而 python 是这一块儿的强项,所以当时和后端的同事商量,看他能不能搞定这一块儿。最终他还是搞定了,返回给我的是音频流数据。

我拿到音频流数据后,因为我们这个项目是有 BFF 层的,所以我在前端服务器对拿到了 bytes 数据做了一层转换,转换成 base64 数据,这样更方便页面上的 audio 元素使用。

另外我还做了一层缓存优化,在前端服务器上添加了一个数据库,将转换过的音频数据存储在了 mongodb 里面,这样能够减少重复的转换。(简单阐述了我是如何思考的,以及我根据思考落地下来的方案)

整体的优化方案落地后,响应式时间从之前的接近 1min 减少到几秒以内。(方案落地后的一个效果)你看面试老师您需要我把里面的细节展开来讲一下不?(钩子🪝)

# 知识点叙述

# 1. 文本切割

模拟问题:可以展开讲一讲。你先说一下文本切割这一块儿呢?

问题分析

  1. 简单介绍一下切割的不同方案
  2. 你选择的方案,为什么选择这种方案
  3. 自然引到并发,特别是并发控制这个点

参考答案

文本切割主要就是把一个大文本切割成多个小文本,这样能够加速 TTS 服务的处理数据。切割的时候需要考虑切割的粒度,有两种切割方案:

  1. 按照标点符号断句,然后切割
  2. 固定长度字符进行切割

这个项目里面我选择的是第一种切割方案,因为这样能保证句子完整,不会切断语义,而且也方便后面做情绪标记。(阐述我为什么选择第一种方案)

不过文本切割后会带来文本数量变多的问题,这里我采用的并发的方式来进行处理的,并且并发的时候还做了一些控制,防止服务器过载。这其实也是一个蛮重要的优化点,需要把这个点说一下么?

# 2. 并发控制与请求取消

模拟问题:可以,你说一下你是如何对并发进行控制的

问题分析

在回答的时候将并发控制有哪些关键的点讲出来,然后引出另外一个优化方针:缓存。

参考答案

并发控制这边我主要做了这么几件事情:

  1. 限制并发数量,这样能控制到达服务器的请求数量
  2. 使用队列管理和调度并发请求,确保新的请求在当前并发请求完成后才发出的
  3. 根据服务器和负载情况和网络状态,动态的调整最大并发请求数

查看网络状态这一块儿我之前是没有做的,不过当时因为做这个项目,我刚好也就去看了一些和网络相关的知识、博客、视频,发现这也是一个非常不错的优化点,就加上了。(凸显你自己的一个做事儿风格,并且还能增加真实性)

整套方案下来,就达到了并发发送多个文本的目的,同时又能对并发量进行一个很好的控制。

另外在“发送”这一块儿,我还做了一层优化,就是请求的取消。因为我考虑到这么一种情况,就是用户鼠标先 hover 一段文本,本来要对这段文本进行转换的,但是用户又 hover 到了其他文本,那么第一次的请求就不需要了,这里可以将其取消掉。

这就是整个“发送”这一块儿所做的优化。至于“响应”回来的数据,我则是通过设置缓存来进行优化的。所以整体的优化方案概括起来,就是一去一回,去的时候能做什么样的优化,数据回来后又能做什么优化。

# 3. 请求取消

模拟问题:你能说一下请求取消这一块儿,具体是如何做的么?

问题分析

  1. 简单介绍 AbortController
  2. 结合你的项目是怎么使用的
  3. 暗示面试官“请求”这一块儿的优化就这么多了

参考答案

请求的取消可以使用 AbortController,这是浏览器提供的一个 API,专门用于中止一个或多个 Web 请求。(简单介绍AbortController)

当时在项目里面,我给每一个切割的文本创建了一个 AbortController 实例,然后发请求的时候会将实例的 signal 一起放到请求里面,一旦涉及到需要取消请求,直接调用实例对象的 abort 方法做取消操作就可以了。(介绍项目里面具体是如何使用的)

关于请求这一块儿的优化差不多就是这两个地方,一个并发控制,一个请求取消,这两块儿搞定后,我觉得请求方面的就优化得差不多了,后面就是数据回来后也需要做一些优化。

# 4. 情绪标记

模拟问题:等一下,我对情绪标记这个点比较好奇,你说后端搞定了,他那边是如何搞定的呢?你有问过他么?

问题分析

在回答的时候大致介绍一下即可。

  1. 介绍一下这个技术涉及 XXX 领域
  2. 你们项目是如何处理的

参考答案

这个情绪标记涉及到了对自然语言文字的分析和处理,属于 python 的强项,python 生态中有很多的和自然语言处理相关的库。所以当时我和后端同事聊了一下,他刚好也会一些 python,所以他那边负责搞定了这个问题。

后来他告诉我好像是在服务器中设置了 python 服务,用到了一个 NLTK 的库专门来处理这个情绪标记的问题,具体细节我倒是不太清楚,因为我主要是负责前端这一块儿的 TTS 性能优化。(再次把话题拉回来)

# 5. 缓存

模拟问题:那你最后说一下缓存这一块儿的注意点有哪些呢?

问题分析

遇到这种情况,面试官询问的是注意点,你直接贴着你的项目来讲即可。讲一下项目里面缓存是如何落地的,以及你自己的一个心路历程。

参考答案

当时我在考虑缓存的时候,考虑了两种方案,一种是缓存在客户端,一种是用一个数据库,缓存在服务器端。

缓存在客户端的好处在于获取缓存的速度很快,可以采用 localstorage 来存,值存对应的 base64 数据,键则是对应的文本内容。不过这里有个细节的点要考虑,就是键如果直接用文本的话,可能一句话过长,导致键超出 localstorage 的长度限制,所以需要做一层 MD5 处理。本来都打算这么做了,后来我想了一下,客户端的缓存只能存当前用户转换过的文本,但是一般来讲,用户看完某篇知识文档后,转而就会去看下一篇,不太会一篇文档翻来复去听个十来遍,除非是一篇超高质量、需要反复玩味的文档。(整个这一段是在介绍你是如何思考的,整体的一个心路历程)

所以我改变了策略,决定缓存在前端服务器端,这样只要转换过某个文本,都能缓存起来,方便下一次使用。数据库方面我选择了我熟悉的 MongoDB 数据库。

整套优化方案落地下来,以前的一个长文本平均需要 30s 的转换时间,优化后分段转换,总时间降到几秒以内,而如果是存在缓存的情况下,基本上 1s 上下。(最后对整体的落地方案以及效果进行一个总结)

不过现在回想起这个项目,我认为缓存这一块儿仍然有优化的地方,例如可以设置双层缓存,客户端用 localstorage 缓存一次,客户端找不到,就去前端数据库去找,如果还是找不到,最后再请求 TTS 服务,就有点类似于 DNS 的解析流程一样,不知道我想这种方案面试老师您怎么看?

(完美收官)


-EOF-

Theme by Vdoing | Copyright © 2021-2024 蜀ICP备2024068710号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式