跳至主要內容

聚合搜索平台

holic-x...大约 30 分钟项目聚合搜索平台

聚合搜索平台项目总结

​ 根据自身项目丰富度、以及对于项目的理解情况有选择地去写。如果还没有实现项目或者不理解,先吃透项目再写到简历上!此外,这个项目的聚合搜索、数据抓取、数据同步等功能,其实是可以集成到做的其他项目中的,可以把该项目的部分亮点和之前的项目进行整合迭代

项目收获

​ 自主把控项目学习、项目实践、项目扩展、项目反思的时间计划及安排(快速突击分配25h+,稳扎稳打预计分配40h+)

1.掌握做项目的完整流程,能独立开发上线项目

2.学会企业主流前后端开发技术的应用(如Spring Boot、Vue 3、Elastic Stack等)以及快速开发前后端全栈项目的技巧

3.学到数据爬虫、数据同步、接口优化、多种设计模式、Elastic Stack、 压力测试等一系列重要知识

4.学到对比方案的方法,帮你开拓思路,提升系统设计能力

5.学到项目开发、调试和优化技巧,如开发工具技巧、抽象封装、问题定位、性能优化等

6.学会自助掌握阅读官方文档的方法技巧,提高自学能力

7.学会分析解决项目中的问题,提升自主解决问题的能力

项目介绍

【1】专业技能

后端

  • 熟悉 Java 知识(如集合类、异常处理),能熟练运用 Lambda、Hutool、HttpClient、Apache Utils 编程
  • 熟悉 SSM + Spring Boot 开发框架,能够使用 MyBatis Plus + MyBatis X 自动生成基础 CRUD 代码
  • 熟悉 MySQL 数据库及库表设计,能够通过创建索引、Explain 分析等方式优化性能
  • 熟悉常见的业务开发场景:比如 jsoup 爬虫、分词搜索功能、数据同步、多数据源管理等
  • 熟悉并实践过多种设计模式,比如门面模式、适配器模式、注册器模式
  • 熟悉 Elastic Stack 技术栈,能用 Elasticsearch 实现分词搜索、用 Kibana 实现 ES 数据看板搭建
  • 能够使用 Canal、Logstash、定时任务、双写等方式实现 Elasticsearch 和 MySQL 的同步
  • 熟练使用 Git、IDEA、Swagger、Navicat 等工具提高开发协作效率,使用 JMeter 压测系统。

前端

  • 熟悉前端 Vue 3 开发,能熟练运用 Vue Router、Ant Design Vue 等组件完成响应式页面开发
  • 熟悉前端代码规范,并能够使用 ESLint + Prettier + TypeScript 等技术保证前端项目质量
  • 能够使用 Vue-CLI 脚手架、VS Code、WebStorm IDE 等开发工具快速开发前端项目

【2】项目经历

项目名称:XX 聚合搜索平台

建议想个有区分度的名字,其他名称参考:

  • XX 搜索平台
  • XX 信息聚合平台
  • XX 搜索
  • XX 信息墙
  • XX 聚合网
  • XX 聚合搜索中台

在线访问:xxx(建议部署一下,提供可访问的、简短的线上地址)、GitHub:xxx(建议把项目放到代码仓库中,并且在主页文档里补充项目信息)

【3】主要工作

后端

  • 基于自己二次开发的 Spring Boot 初始化模板 + MyBatis X 插件,快速生成基本数据源的增删改查(比如用户、文章)。

  • 数据源获取:

    • 使用 HttpClient 请求 离线 获取外部网站的文章,并使用 Hutool 的 JSONUtil 解析和预处理文章,最终入库。
    • 使用 jsoup 实时 请求 bing 搜索接口获取图片,并使用 CSS Selector 语法解析和预处理图片信息,最终返回给前端。
  • 为实现多类数据源的整体搜索,使用 门面模式 在后端对各类数据源的搜索结果进行聚合,统一返回给前端,减少了前端请求次数(N 次到 1 次)以及前端开发复杂度。并通过 CompletableFuture 并发搜索各数据源进一步提升搜索接口性能,实测整体响应时长 由 300ms 减少为 xx ms (一定要自己测试,如果效果不明显,可以加大数据量)。

  • 为提高聚合搜索接口的通用性,首先通过定义数据源接口来实现统一的数据源接入标准(比如新数据源必须支持分页);当新数据源(比如视频)要接入时,只需使用适配器模式对其数据查询接口进行封装、以适配数据源接口,无须修改原有代码,提高了系统的可扩展性。

  • 为减少代码的圈复杂度,使用注册器模式代替 if else 来管理多个数据源对象,调用方可根据名称轻松获取对象,(使用 IDEA MetricReloaded 插件)实测圈复杂度由 XX 减少为 XX。

  • 为解决文章搜不出的问题,自主搭建 Elasticsearch 来代替 MySQL 的模糊查询,并通过为索引绑定 ik 分词器实现了更灵活的分词搜索,且使用 JMeter 测试后发现搜索性能提升 xx%(xx qps 到 xx qps)。

  • 构建 ES 文章索引时,采用动静分离的策略,只在 ES 中存储要检索的、修改不频繁字段(比如文章)用于检索,而修改频繁的字段(比如点赞数)从数据库中关联查出,从而减少了 ES 数据更新和同步的成本、保证数据一致性。

  • 为了更方便地管理 Elasticsearch 中的数据,自主搭建 Kibana 并配置 index pattern 和看板,实现对文章数据的可视化管理。

  • 开发搜索功能时,使用 Kibana DevTools + DSL 调试 ES 的搜索效果,并使用 Spring Data Elasticsearch 的 QueryBuilder 组合查询条件,实现对 ES 内文章的灵活查询(比如查询同时查询标题和文章中带有指定关键字的内容)。

    以下 2 选 1:

    使用 Spring Scheduler 定时同步近 5 分钟内发生更新的 MySQL 的文章数据到 ES,通过唯一 id 来保证每条数据同步的准确性。

    自主搭建 Logstash 实现每分钟同步 MySQL 的文章数据到 ES,并通过指定 tracking_column 为更新时间字段解决重复更新的问题。

    其他:使用 Knife4j + Swagger 自动生成后端接口文档,并通过编写 ApiOperation 等注解补充接口注释,避免了人工编写维护文档的麻烦。

前端

  • 基于 Vue 3 + Ant Design Vue 实现响应式页面开发,使用 Tab 组件 + Vue Router 动态路由实现统一页面布局,通过用户点击 Tab 时更改路由来切换各类数据(文章、图片、用户)的搜索结果,并选用不同的组件进行展示。
  • 为解决刷新页面后搜索结果丢失的问题,定义 searchParams 响应式变量来集中保存当前的搜索条件(比如关键词、搜索类别、分页),并通过 Vue Router 的 query 参数将搜索条件同步到 url 的 querystring 中。
  • 使用 TypeScript + ESLint + Prettier + Husky 保证项目编码和提交规范,提高项目的质量。(虽然是由脚手架自动帮你整合了,但你要知道这些技术各自的作用)

【4】扩展思路(项目优化点)

后端

  • 可以使用 Canal 监听 MySQL,并将数据实时同步到 Elasticsearch(一定要能突出实时同步的必要性,比如要搜索的数据频繁改动)
  • 可以使用 Redis 对查询数据进行缓存,并测试下缓存命中率和性能提升的效果
  • 可以记录并统计用户的搜索词,从而实现热搜、词云图、看板分析等功能。
  • 为 Elasticsearch 的 ik 插件自定义词典,实现系统内一些关键词的灵活分词查询。(词典如何生成也是需要考虑的问题,可以从热搜词下手)
  • 使用 Elasticsearch 的 highlight 语法实现搜索词高亮。
  • 使用 Elasticsearch 的 suggest 语法实现搜索建议。
  • 聚合搜索接口中,可以使用自定义线程池来实现并发,线程池的参数配置为 IO 密集型,即线程数多一些。
  • 可以使用 Guava Retrying 重试库来保证调用第三方接口的稳定性,可以实测一下接口可用性有几个
  • 可以使用定时任务定期去做离线文章爬虫

前端

  • 为解决用户频繁输入带来的搜索请求性能浪费,使用 Lodash 库实现搜索功能的防抖。
  • 可以尝试使用 umi 的 one-api 插件,根据后端的 swagger 接口文档自动生成请求代码。
  • 对于各类数据的查询请求,可以使用懒加载或骨架屏来优化用户体验。
  • 可以尝试实现文章和图片的无限滚动列表,并解决数据量过大带来的性能问题。
  • 可以在前端使用 Vuex 或 Pinia 等状态管理工具实现搜索记录功能。

【5】个人评价

有较强的文档阅读能力,曾阅读 Elastic Stack、Spring Data Elasticesarch 等官方文档自主学习,并能够运用到项目中。

有较强的问题解决能力,能够利用 GitHub Issues 区、AI 工具、搜索引擎、Stack Overflow 等自主解决问题

常见问题

通用

1.请介绍一下本项目的完整业务流程?

​ 用户可以在前端通过一个搜索框集中搜索出不同来源的数据,比如通过离线爬虫提前获取到的文章数据、通过 Bing 接口实时获取到的图片数据、以及业务内部数据库的用户数据。

2.在开发过程中,你遇到过比较复杂的技术问题或挑战吗?如果有,请谈谈你是如何解决这些问题的?

​ 可以从以上任意一道主观的面试题出发去讲,比如你在进行 MySQL 和 Elasticsearch 文章数据同步时,是否有发现数据丢失未同步、或者文章重复插入的情况?然后通过一些策略解决重复更新或插入的问题。

后端

1.你的项目中使用了哪些技术栈?请分别介绍一下 Spring Boot、Elastic Stack 在项目中的作用。

​ 项目技术栈:SSM + Spring Boot、Elastic Stack、MySQL、MyBatis-Plus、Jsoup、Hutool 工具库。

Spring Boot:用于快速构建基础的后端项目,只需要修改配置文件,就能轻松整合 SSM、MySQL、Elasticsearch 等依赖。

Elastic Stack:包括 Elasticsearch 搜索引擎、Kibana 可视化看板、Logstash 数据传输(ELK)

  • Elasticsearch:存储文章数据,提高根据关键词搜索文章内容的灵活性
  • Kibana:可视化 Elasticsearch 存储的数据,并能通过 Dev Tools 对 Elasticsearch 进行操作调试
  • Logstash:将文章数据定时从 MySQL 同步到 Elasticsearch

2.你提到自己二次开发了 Spring Boot 初始化模板,这个模板有哪些功能?

​ 因为自己做过多个项目,每次开发新项目时都要先复制粘贴老项目的可复用代码,所以干脆抽象了一些独立于业务的公共代码为 Spring Boot 初始化模板。

主要功能如下:

  • 整合常用的组件依赖,比如 MySQL、Redis、Elasticsearch、Hutool 等
  • Spring Session Redis 分布式登录
  • 全局请求响应拦截器
  • 全局异常处理器
  • 自定义错误码
  • 封装通用响应类
  • Swagger + Knife4j 接口文档
  • 自定义权限注解 + 全局校验
  • 全局跨域处理
  • 长整数丢失精度解决
  • 用户相关业务:用户登录、注册、注销、更新、检索、权限管理
  • 帖子相关业务:帖子创建、删除、编辑、更新、数据库检索、ES 灵活检索
  • 文件上传

3.什么是 HttpClient?如何使用 HttpClient 来抓取外部网站的文章?请简述整个过程

​ Apache HttpClient 是用于发送 HTTP 请求并处理 HTTP 响应的工具库,类似的还有 Hutool 的 HttpRequest、OKHttp 等。 ​ 首先我通过 F12 控制台捕获到了目标网站加载文章数据的 HTTP 请求,然后使用 HttpClient 在 Java 代码中构造请求,比如指定请求类型、请求头、携带查询文章的请求参数等。发送请求后,判断响应状态码,如果响应正常,则将响应的 JSON 字符串转换为响应实体类,对数据进行一定的处理后写入到业务数据库中。

4.什么是 Jsoup?它和 HttpClient 有什么区别?

​ 二者是截然不同的两个 Java 库! ​ Jsoup 是一个解析和操作 HTML 文档的工具库,可用于网络爬虫,能够从网页上抓取特定信息并从中取出特定的信息,通常需要配合 HttpClient 等请求库来获取 HTML 页面。 ​ HttpClient 是用于发送 HTTP 请求和处理 HTTP 响应的工具库,并不具备 HTML 解析和操作功能。

5.什么是 CompletableFuture?你在项目中如何使用它实现并发搜索?

​ CompletableFuture 是 Java 中用于支持异步编程和并发操作的类(在 JUC 并发包中)。 ​ 不仅可以通过 CompletableFuture 处理异步任务,还能编排和构建复杂的异步操作流水线,比如一个任务执行完后再触发另一个任务、等待任务都完成后再进行操作等。 ​ 本项目中,我将用户搜索、文章搜索、图片搜索分别封装为 CompletableFuture 任务,然后使用 CompletableFuture.allOf 组合这些任务、并发执行,并通过 join 方法开启阻塞等待。等所有数据源搜索都完成后,才会执行后续的操作,返回数据给前端。

6.你使用了门面模式来对各类数据源的搜索结果进行聚合,请介绍门面模式的概念、作用和实现方式?

​ 门面模式的主要目的是提供一个 统一的 接口,用于访问一组子系统的功能。

​ 使用门面模式可以简化接口,降低调用方的使用和理解成本;它封装了子系统的复杂性,使客户端可以更轻松地与子系统交互,而不需要了解子系统内部的工作细节,降低了客户端和子系统的耦合度。

(门面模式图示)

​ 在本项目中,使用门面模式来对多个数据源的搜索结果进行聚合,让前端通过给同一个搜索接口传递不同的参数来灵活地获取数据。

​ 具体实现方式: 1.定义门面类:创建一个门面类,该类充当客户端和多个子系统之间的中介。门面类包含了对多个子系统的引用,并提供了封装接口,供客户端使用。 2.封装操作:在门面类中,根据输入参数,选择调用不同的数据源搜索服务来搜索数据,并将其结果进行合并、转换处理,以生成最终统一的聚合结果。 3.提供简化接口:前端通过与门面类交互来执行搜索操作,而不需要了解每个数据源具体的搜索过程。

7.使用了适配器模式来实现新数据源的接入,请介绍适配器模式的概念、作用和实现方式?

​ 适配器模式的主要目的是将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作,就像是手机充电器的转接头一样。 适配器模式的主要作用: 1接口转换:适配器模式允许将一个类的接口转换成另一个类所期望的接口,使得两个类可以协同工作,而无需修改它们的源代码。 2解耦合:适配器模式可以帮助解耦合不兼容的接口,使得客户端与适配器之间的接口保持一致,降低了代码的依赖性。 3复用性:适配器模式可以将现有的类用于新的应用场景,增加了代码的复用性。

在本项目中,定制了统一的数据源接入规范(数据源接口),比如任何接入聚合搜索系统的数据,必须要能够根据关键词搜索、并且支持分页搜索。 在这个前提下,对于有些想要接入系统的数据源,如果原有的搜索方法参数和接口的定义不一致,又不能改造接口以及对方原本的搜索方法,这时就需要使用适配器模式。 比如搜索文章数据源,有一个现成的 searchFromEs 的方法,但接受的搜索参数是一个对象而不是 searchText 字符串,就需要使用适配器模式进行转换,对请求参数进行封装。(参考示例代码PostDataSource)

8.使用了注册器模式来管理多个数据源对象,请介绍注册器模式的概念、作用和实现方式?

注册器模式的主要目的是在应用程序中全局注册一些对象,便于被其他对象发现和使用,常用于管理和维护一组单例的全局对象。 使用注册器模式后,不仅能更方便地集中查找和获取全局对象,还避免了反复初始化的内存和时间开销。 具体的实现方式如下: 1定义注册器类:将注册器类标识为一个 Bean,并且在类中添加一个 HashMap 属性,用于存放全局对象。 2对象注册:通过 @PostConstruct 注解,在注册器 Bean 加载时初始化 HashMap 并且向其中插入新创建的数据源对象。 3对象获取:提供一个根据 key(数据源类型)查找对象的方法,返回获取到的对象。

9.什么是代码的圈复杂度?为什么要关注代码的圈复杂度?

圈复杂度是一种衡量软件代码复杂性的度量指标。它用于评估代码中的决策路径数量,即代码中分支语句(如 if、switch、while 等)的数量。 一般来说,圈复杂度越高,代码的复杂性越高。

关注代码的圈复杂度,是为了消除代码中混乱的逻辑,让代码结构更清晰易懂,从而更好地维护代码。

在 IDEA IDE 中,可以使用 Metrics Reload 插件检测项目代码的圈复杂度,对于圈复杂度 > 10 的代码,我会分析能否通过设计模式、抽象复用方法的方式降低复杂度,提高项目的代码质量。

10.什么是 Elasticsearch?Elasticsearch 和 MySQL 分别有哪些应用场景和优缺点?

Elasticsearch 是一个开源的分布式搜索引擎,提供了强大的全文搜索和复杂查询功能。 1)Elasticsearch 主要的应用场景:全文搜索、日志分析 优点:搜索性能高、能够实现灵活的全文搜索、实时性强、支持分布式扩容 缺点:部署运维成本较大,且查询操作学习成本较高

2)MySQL 主要的应用场景:关系型数据存储、事务和数据一致性支持(比如财务系统) 优点:支持事务、成熟稳定 缺点:实时搜索性能和灵活性较差,不利于大数据量的扩展

在实际业务中,可以结合使用这两种数据库,把需要全文检索功能的数据同步到 Elasticsearch 上(比如文章数据);而其他无需检索的关系型数据(比如用户数据)存储在 MySQL 中。

11.Elasticsearch 为什么能实现更灵活的查询?

这题有 2 种回答方式,比较推荐的一种是把重点放在 Elasticsearch 的倒排索引和分词原理,请阅读这篇文章:搜索引擎工作原理 。 另外一种是从相对较广的角度回答,Elasticsearch 实现灵活查询的几个原因: 1)强大的查询DSL:Elasticsearch 提供了丰富的查询 DSL(领域特定语言),允许用户以更高级别的抽象方式构建查询。DSL支持多种查询类型,包括全文搜索、精确匹配、范围查询、布尔查询、嵌套查询、通配符查询、模糊查询等。这些查询类型可以根据不同的搜索需求组合和嵌套,以构建复杂的查询条件。 2)全文搜索能力:Elasticsearch以全文搜索为基础,具有出色的文本搜索功能。它使用分析器和标记化技术来处理文本数据,支持词干分析、停用词过滤、同义词处理等,从而能够实现高效的文本搜索和相关性排名。 3)倒排索引:Elasticsearch使用倒排索引来加速搜索。倒排索引是一种反向映射,将每个词汇与其出现在文档中的位置建立关联。这允许Elasticsearch在非常快的时间内查找到包含特定词汇的文档。 4)分布式架构:Elasticsearch采用分布式架构,数据分片和复制到多个节点上。这意味着查询可以并行执行,并且可以在多个节点上分散负载,以提高性能和可伸缩性。这对于处理大规模数据和高并发查询非常重要。 5)动态映射:Elasticsearch 具有动态映射功能,可以根据文档中的字段自动推断其数据类型。这意味着您可以灵活地插入文档,而不需要事先定义模式。这种灵活性允许您存储各种不同结构的文档,并以多种方式查询它们。 6)插件和定制性:Elasticsearch具有丰富的插件生态系统,可以轻松扩展其功能。您可以选择性地添加插件以满足特定需求,例如地理位置搜索、词汇推荐等。此外,Elasticsearch允许您自定义分析器、标记化器和过滤器,以适应不同的数据类型和语言。

12.提到采用动静分离的策略存储文章信息,请解释一下动静分离的概念,以及它在本项目中具体的实现方式。

动静分离是一种常见的架构设计策略,是指将一个应用程序的动态数据(通常是经常变化的数据,如点赞数)与静态数据(通常是不经常变化的数据,如文章正文)分别存储在不同的存储引擎(或表)中,从而优化性能、降低负载等。 本项目中,我将文章的内容(静态数据)存储到 Elasticsearch 中用于实现检索,而文章的点赞数等动态数据存储到 MySQL 中。 在用户根据关键词搜索文章时,会先从 Elasticsearch 分词搜索出文章的 id 获取到静态数据,然后根据 id 在数据库内查找对应的文章,从而获取到最新的动态数据。 这样做可以减轻 MySQL 的负载,同时实现快速的全文搜索和数据展示。

13.请简要介绍一下 Kibana 的作用和它的基本功能,你在项目中使用了 Kibana 的哪些功能?

Kibana 是一个开源的数据可视化平台,主要用于对 Elasticsearch 中的数据进行搜索、分析和可视化展示。 基本功能包括:数据查询搜索、数据可视化看板、日志分析、Elasticsearch 操作调试 在项目中,我在 Kibana 上搭建了 Elasticsearch 文章总数看板,用于观测 MySQL 成功同步到 Elasticsearch 的数据量。此外,在开发 Elasticsearch 文章搜索功能时,我使用 Kibana 的 DevTools 编写 DSL 代码来调试 Elasticsearch 的复杂查询条件,提高了开发效率。

14.请简单介绍如何使用 Kibana DevTools + DSL 调试 ES 的搜索效果,你是怎么操作的?

由于 Elasticsearch 的查询语法复杂多样,为了保证业务代码中指定的搜索条件的正确性,我先把可能的搜索条件以 DSL 的方式在 Kibana DevTools 中执行验证。掌握了 Elasticsearch 的常用操作语法后,再去编写代码,提高了整体的开发效率。 Kibana DevTools 提供了一个界面,可以通过编写 DSL 代码来操作 Elasticsearch。 比如要搜索文章,可以使用以下 DSL:

GET post/_search
{
  "query": {
    "match_all": { }
  },
  "sort": [
    {
      "@timestamp": "desc"
    }
  ]
}

15.你在项目中使用了 Spring Data Elasticsearch 的 QueryBuilder 组合查询条件,请解释一下 QueryBuilder 的作用,以及你具体用它组合了哪些查询条件?

QueryBuilder 是 Spring Data Elasticsearch 提供的、用于构建复杂查询条件的工具(有点类似 MyBatis Plus 的 QueryWrapper)。 在项目中,我使用 boolQueryBuilder 组合多个子查询条件,比如同时根据 userId 和 id 来过滤;使用 matchQuery 实现全文检索,比如根据关键词搜索文章内容;使用 termQuery 实现精确匹配查询,比如根据标签搜索文章。

16.你在项目中提到了定时同步 MySQL 的文章数据到 Elasticsearch,还有使用 Logstash 实现每分钟同步数据,请分别解释一下这两种方式的实现原理和优缺点?

两种方式本质上都是定时同步,只不过前者是在项目代码中编程实现,后者是通过在 Logstash 编写配置实现。 1)定时同步 MySQL 的文章数据到 Elasticsearch: 实现原理:通过 Spring Scheduler + Crontab 表达式指定每分钟执行一次同步任务,查询 MySQL 数据库中近 5 分钟内 updateTime 发生变化的数据,然后将这些数据传输到 Elasticsearch 进行索引更新或插入操作。 优点:简单灵活,不需要依赖其他中间件,且可以自由指定取数据和同步数据的逻辑 缺点:分布式场景下,需要考虑定时任务并发执行冲突的问题;数据量如果比较大,可能会占用大量资源、影响应用程序的运行。

2)使用 Logstash 实现每分钟同步数据: 实现原理:编写 Logstash 配置文件,填写一句查库的 SQL 语句和最新同步的数据 id,由 Logstash 定时触发数据的同步。 优点:无需编写代码,且 Logstash 提供了很多内置的数据处理插件;独立运行同步任务,不影响应用程序。 缺点:需要引入额外的中间件,且无法灵活定制取数据的逻辑。

17.在 MySQL 和 Elasticsearch 的数据同步过程中,你如何解决重复更新或插入的问题?

1)使用唯一标识符:同一篇文章数据,在 MySQL 和 Elasticsearch 中的 id(索引)是相同且唯一的。在同步数据时,可以使用主键来确保每个文档只被索引一次;如果文档已存在于 Elasticsearch 中,可以使用主键来更新它,否则将其插入为新文档。 2)确保同步操作幂等:即多次执行相同的操作不会产生不同的结果,即使重复执行同步操作,结果也应该和不重复执行保持一致。 3)数据变更监听:使用 Canal 同步数据,保证每个数据库变更事件只捕获并处理一次,如果处理失败,通过日志或者 DB 记录异常信息,通过补偿机制回写数据。

18.什么是 Canal?它有什么作用?请简述它的核心实现原理?

​ Canal 是阿里开源的数据库日志监听工具,主要用途是基于 MySQL 数据库增量日志解析,及时捕获数据库的变更操作并传递给下游应用,下游应用可以根据数据库的变更实现各种操作,比如数据同步、缓存更新、实时分析等。 建议阅读官方文档:https://github.com/alibaba/canal

Canal 的核心实现原理:

  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
  • canal 解析 binary log 对象(原始为 byte 流)

19.你在项目中使用了 Swagger + Knife4j 自动生成接口文档,请谈谈 Swagger 和 Knife4j 的作用和它们对项目开发的影响。

​ Swagger 是一个用于自动构建和生成可交互接口文档的工具集。使用 Swagger 接口文档生成工具后,我不需要在开发完项目后手动编写一套接口文档,而是直接交由系统自动根据 Controller 接口层的代码自动生成文档,大幅节省时间。 使用 Swagger 生成的接口文档不仅能够分组查看请求参数和响应,还支持灵活的在线调试,可以直接通过界面发送请求来测试接口,提高开发调试效率。 ​ 此外,引入 Swagger 后,可以得到基于 OpenAPI 规范的接口定义 JSON,可以配合第三方工具来根据 JSON 自动生成前端请求代码、自动生成客户端调用 SDK 等。 ​ Knife4j 是 Swagger 的增强版,能够生成更美观的 API 接口文档,并且提供了离线文档导出、接口分组排序等增强功能。(参考官网:https://doc.xiaominfo.com/docs/features)

前端

1.什么是 Vue 中的响应式变量?

参考

​ 响应式变量是一种特殊的 JavaScript 变量,它与 Vue 的数据绑定系统紧密关联。Vue 会自动监视响应式变量,当响应式变量的值发生变化时,相关的 Vue 组件会自动更新视图以反映这些变化。 ​ 在项目开发中,通常会把后端接口返回的数据存到响应式变量中,从而更方便地驱动页面视图的更新,展示返回的数据。 ​ Vue 2 项目中,通常把响应式变量定义在 Data 属性中;Vue 3 项目中,可以使用 ref 或者 reactive 定义响应式变量。

2.你是如何实现 url 的 querystring 和页面内的响应式变量同步的?

主观回答

采用单向状态同步的策略,只允许通过 url 的改变来改变页面状态,而不允许通过改变页面状态来改变 url 地址。 具体的实现思路: 1用户在执行搜索操作时,修改 url 地址,将搜索关键词作为 querystring 拼接到 url 后 2通过 watchEffect 钩子函数监听 url 的改变,当 url 改变时,更新页面内的数据状态

3.请介绍一下 Vue 3 的新特性和与 Vue 2 相比有哪些变化?

背诵类题目,也可以有主观回答

详细参考官方文档: Vue 3 迁移指南 | Vue 3 迁移指南

1)更快的渲染性能:Vue 3 引入了新的响应式系统(Proxy-based),相比Vue 2的Object.defineProperty,提供了更高效的数据监听和更新机制,从而提高了渲染性能。 2)Composition API:Composition API 是 Vue 3的核心特性之一,它允许开发者更灵活地组织和重用组件逻辑。它将组件的逻辑拆分为可复用的函数式组合,并提供了setup()函数来配置组件。 3)Teleport:Vue 3引入了Teleport组件,可以轻松将内容渲染到DOM中的不同位置,这在处理模态框、对话框等场景时非常有用。 4)Fragments:Vue 3支持Fragments,允许组件返回多个根节点,而无需包裹额外的HTML元素。 需要注意的是,虽然 Vue 3 引入了许多新特性,但它仍然保持了 Vue 2 的核心理念和语法,因此 Vue 2 的开发者可以相对容易地迁移到 Vue 3,并逐步采用新的特性和优化。

4.项目前端使用了 Ant Design Vue 组件库,请列举几个你用到的组件并介绍它们的用途?你还会使用哪些组件库?

主观回答

我参照官方文档使用 Ant Design Vue 组件库,项目中用到了: Message 全局提示组件:用于给用户的操作反馈,比如弹出网络错误的提示 Card 卡片组件:更美观地展示用户信息 List 列表组件:自上而下展示文章列表,并开启分页功能 Input.Search 搜索组件:展示搜索框并开启 enter 搜索快捷键

5.什么是前端的组件?针对不同类型的数据,你分别选择哪种组件进行展示?

前半句背诵类题目,后半句主观回答

前端的组件是指可复用的、独立的 UI 元素,组件通常封装了特定功能或视图,可以在项目中被多次使用。组件化也是一种重要的开发模式,适当地封装和复用组件,有助于提高代码的可维护性、可扩展性和重用性。 在本项目中,我使用 Ant Design Vue 提供的 List 组件展示文章信息列表,使用 List + Card 组件展示图片列表,使用 List + Card 组件展示用户信息卡片列表。

6.什么是 Vue Router 的动态路由?你在项目中如何使用动态路由实现不同页面切换?

Vue Router 的动态路由是指在路由配置中使用动态的路径参数来匹配和渲染不同的页面。在页面中可以根据不同的输入参数动态加载不同的数据,通常用于展示类似于用户个人资料、文章详情、商品详情等需要根据不同的参数显示不同内容的情况。

参考 Vue Router 官方文档:https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html

本项目中,我定义了一个以数据类型作为参数的动态路由(/:category),在主页面(搜索页面)中获取动态路由参数并且同步到 tab 栏的选中状态;当用户点击 tab 栏切换数据类型时,会同步改变 url。

7.什么是响应式页面开发?如何实现响应式页面开发?

响应式页面开发是指开发能够适应不同设备和屏幕尺寸的网页。这意味着网页的布局、内容和功能会根据用户使用的设备(如台式电脑、平板电脑、手机等)自动调整,以提供更好的用户体验,而不需要为每个设备单独创建不同版本的网页。

常见的响应式页面开发方法有: 1)CSS3 的媒体查询,针对不同的屏幕尺寸编写样式 2)CSS 的弹性盒子布局 3)使用第三方组件库。比如本项目中用到的 Ant Design Vue,自带了栅格系统,可以轻松实现响应式布局。

8.项目是否有上线?你是如何实现前端页面部署的?

项目有实际上线。我是通过本地打包 + Nginx 实现了前端页面部署。 具体过程如下: 1购买云服务器 2安装和初始化宝塔 Linux 面板,会自动安装 Nginx 服务器 3在宝塔上创建一个网站 4本地使用 npm run build 命令打包项目,得到 dist 网站静态文件目录 5上传本地打包好的 dist 目录到服务器,然后配置 Nginx 指向文件目录路径,即可访问前端静态文件 还有其他的部署方式,比如使用 Vercel 等 Serverless 服务一键部署到第三方托管服务器,但由于本人有服务器、并且想实践下 Nginx 配置,所以没有选择这种方式。

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3