(React生命周期)前端八股文修炼Day8

news/2024/5/19 15:20:08/文章来源:https://blog.csdn.net/sinat_37168842/article/details/137478290

在这里插入图片描述

一 React的生命周期有哪些

React组件的生命周期可以分为三个主要阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。React类组件的生命周期方法允许你在组件的不同阶段执行代码。

挂载(Mounting)

这个阶段是组件实例被创建并插入DOM中的阶段。它包括以下生命周期方法:

  1. constructor(props):组件的构造函数,最先被执行,用于初始化状态和绑定事件处理器。
  2. static getDerivedStateFromProps(props, state):在组件实例化后和接收新的props之前被调用。它应返回一个对象来更新状态,或者返回null来不更新任何内容。
  3. render():唯一必须实现的方法,读取propsstate,并返回React元素。
  4. componentDidMount():在组件挂载(即插入DOM树中)后立即调用。这是执行副作用操作(如Ajax请求、DOM操作等)的好地方。

更新(Updating)

这个阶段开始于组件的propsstate发生变化时,导致重新渲染。它包括以下生命周期方法:

  1. static getDerivedStateFromProps(props, state):此方法在组件创建时和接收新的props时被调用。
  2. shouldComponentUpdate(nextProps, nextState):在接收到新的propsstate之前立即调用,返回一个布尔值。返回false则不会继续更新过程。
  3. render():在组件更新时被调用,根据propsstate返回一个新的React元素。
  4. getSnapshotBeforeUpdate(prevProps, prevState):在最近一次渲染输出(提交到DOM节点)之前调用。它允许你从DOM捕获一些信息(如滚动位置)。
  5. componentDidUpdate(prevProps, prevState, snapshot):在更新发生后立即被调用。可以在此处执行DOM操作或进行网络请求。

卸载(Unmounting)

这是组件被移除并销毁的阶段。它包括以下生命周期方法:

  1. componentWillUnmount():在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,如无效定时器的清理、取消网络请求等。

错误处理(Error Handling)

React 16引入了错误边界的概念,可以捕获其子组件树中的JavaScript错误,记录这些错误,并显示一个备用UI。

  1. static getDerivedStateFromError(error):当后代组件抛出错误时,用于渲染备用UI。
  2. componentDidCatch(error, info):当后代组件抛出错误时被调用,用于记录错误信息。

上述是React类组件的生命周期方法。需要注意的是,React 16.8引入了Hooks,允许你在函数组件中使用状态和其他React特性,如useStateuseEffect等,从而在很多场景下可以替代传统的类组件及其生命周期方法。

二 React 废弃了哪些生命周期?为什么

React在其更新过程中,为了改进框架的性能和开发体验,已经废弃(或不推荐使用)了一些生命周期方法。主要的变更发生在React 16.3版本引入的新的生命周期方法,并且在React 17中继续保持。主要废弃的生命周期方法包括:

  1. componentWillMount()(已废弃):在React早期版本中,这个方法在组件挂载到DOM之前被调用。React团队发现,这个方法经常被误用,例如在服务器渲染中执行浏览器特定的代码,或者用于数据加载操作,这些操作更适合在componentDidMount()中进行。此外,为了支持异步渲染,即React未来版本中的并发模式,componentWillMount()的调用时机变得不可预测。

  2. componentWillReceiveProps()(已废弃):这个方法在组件接收到新的props之前调用。它经常被用于根据新的props更新组件的状态。React团队发现,这种模式可能导致bug,特别是在异步渲染的环境中。因此,推荐使用static getDerivedStateFromProps()方法代替。

  3. componentWillUpdate()(已废弃):这个方法在接收到新的propsstate,且在渲染之前被调用。它经常被用于准备更新,如获取新的数据。但是,与componentWillReceiveProps()相同,componentWillUpdate()与异步渲染不兼容,因此React团队引入了getSnapshotBeforeUpdate()来替代其部分使用场景。

为什么废弃这些生命周期

主要有两个原因:

  1. 改善异步渲染的兼容性:为了支持React的并发模式(Concurrent Mode),这需要改变组件生命周期的调用时机。并发模式允许React中断渲染工作,以优先响应更高优先级的工作。废弃的生命周期方法在这种模式下可能会被多次调用或在不预期的时机被调用,从而引入bug。

  2. 促进更好的开发习惯:通过引导开发者避免使用一些容易导致bug的模式(如在构造函数外修改状态,或在组件更新前后进行不必要的操作),React团队希望促进更健壮、可预测的组件开发实践。

作为替代,React引入了新的生命周期方法(如static getDerivedStateFromProps()getSnapshotBeforeUpdate()),并推荐使用Hooks(在函数组件中)来替代这些废弃的生命周期方法,这些新引入的APIs和机制更加适合异步渲染的需求,并鼓励采用更好的开发模式。

三 Hooks与生命周期的关系

React Hooks是在React 16.8版本中引入的,它们允许你在不编写类组件的情况下使用state和其他React特性。Hooks的引入部分是为了解决类组件中存在的问题,包括复杂组件难以理解和重用、难以理解的生命周期方法、以及逻辑难以分离等。Hooks提供了一种更简单、更直观的方式来共享和管理状态逻辑,同时也保留了React的声明式编程模型。

Hooks与生命周期方法的对应关系

虽然Hooks并不直接对应类组件的生命周期方法,但是你可以用Hooks实现相同的生命周期功能。下面是一些常用的React Hooks,以及它们如何与类组件的生命周期方法相关联:

  1. useState: 提供函数组件内部状态的能力,它不直接对应到任何生命周期方法,但你可以将其视为this.statethis.setState方法的替代。

  2. useEffect: 这个Hook功能强大,它可以用来模拟类组件中几乎所有的生命周期方法。通过不同的使用方式,useEffect可以实现componentDidMountcomponentDidUpdatecomponentWillUnmount的功能。

    • 模拟componentDidMount: 传递一个空数组[]作为useEffect的第二个参数(依赖数组),这样useEffect中的回调函数就只会在组件挂载后执行一次。
    • 模拟componentDidUpdate: 通过在依赖数组中指定变量,你可以让useEffect仅在这些变量改变时执行。
    • 模拟componentWillUnmount: 在useEffect的回调函数中返回一个清理函数,这个清理函数会在组件卸载时执行。
  3. useContext: 允许你在函数组件中访问React的Context对象,用于共享状态或方法等,这不直接对应于生命周期方法,但提供了一种在组件间共享数据的方式,类似于在类组件中使用静态contextType属性或<Consumer>组件。

  4. useMemouseCallback: 这两个Hooks用于优化性能,通过记忆计算结果或回调函数,从而避免在每次渲染时都进行重计算或重新创建函数。虽然它们不直接对应生命周期方法,但它们帮助管理因组件更新而引发的性能问题。

总的来说,Hooks提供了一种更灵活的方式来复用逻辑、管理状态、以及与组件的生命周期等同步,与类组件的生命周期方法相比,Hooks使得组件逻辑更容易组织和理解,同时也更容易测试。通过使用Hooks,开发者可以更加集中地关注组件的逻辑,而不是管理生命周期方法的复杂性。

四 React 16.X 中 props 改变后在哪个生命周期中处理

在React 16.x中,当组件的props发生变化时,主要在下列生命周期方法中处理这些变更:

  1. static getDerivedStateFromProps(props, state): 这个方法在props传入后,以及在任何state变化时,都会被调用。它返回一个对象来更新state,或者返回null来表明新的props不需要更新state。这是一个静态方法,意味着你无法在其中使用this。这个方法适用于根据props的变化来更新state的情况。

    static getDerivedStateFromProps(nextProps, prevState) {if (nextProps.someValue !== prevState.someValue) {return { someState: nextProps.someValue };}return null;
    }
    
  2. componentDidUpdate(prevProps, prevState, snapshot): 这个方法在组件完成更新后立即调用,但不会在初次渲染时调用。它允许你在组件更新后进行DOM操作或执行某些后续处理。如果你的组件依赖于props的变化来执行副作用操作(例如,数据提取、手动变更DOM等),这是一个合适的地方。

    componentDidUpdate(prevProps) {if (this.props.userID !== prevProps.userID) {this.fetchData(this.props.userID);}
    }
    

在早期版本的React中,componentWillReceiveProps(nextProps)生命周期方法被用于props变化时的处理。然而,从React 16.3版开始,componentWillReceiveProps已被标记为即将废弃(不推荐使用),并在React 17中被彻底移除。React团队推荐使用getDerivedStateFromProps来代替componentWillReceiveProps进行基于props变化的state更新,以及使用componentDidUpdate来处理props变化后的逻辑。

需要注意的是,如果你在处理props变化时发现自己需要执行副作用(如API调用等),则应考虑使用componentDidUpdate。如果需要根据props的变化来更新组件的内部状态,则应使用getDerivedStateFromProps

五 React 性能优化在哪个生命周期?它优化的原理是什么

在React中,性能优化可以在多个生命周期方法中进行,但最关键的生命周期方法是shouldComponentUpdate。此外,在React 16.3及以后的版本中,引入了React.PureComponentReact.memo作为性能优化的工具。

shouldComponentUpdate

shouldComponentUpdate方法允许组件在接收到新的props或state之前决定是否重新渲染。它的默认行为是每次在接收新的props或state时返回true,导致组件重新渲染。如果你知道在某些情况下组件的更新是不必要的,可以在shouldComponentUpdate中返回false来避免重新渲染,从而优化性能。

shouldComponentUpdate(nextProps, nextState) {// 检查是否真的需要更新组件return nextProps.id !== this.props.id;
}

React.PureComponent

React.PureComponentComponent相似,但PureComponent通过对props和state的浅比较来自动实现了shouldComponentUpdate方法。如果组件的props和state在浅层级上都没有变化,则不会重新渲染。这可以在某些情况下提高性能,特别是当组件的渲染输出仅依赖于浅层props和state时。

React.memo

React.memo是一个高阶组件,它类似于PureComponent,但用于函数组件。它可以阻止组件的不必要渲染,通过对组件的props进行浅比较来实现。

const MyComponent = React.memo(function MyComponent(props) {/* 渲染逻辑 */
});

优化原理

上述方法的核心优化原理基于避免不必要的渲染。React的渲染过程包括创建虚拟DOM、与上一次的虚拟DOM进行比较(diffing)、并根据比较结果更新实际DOM。这个过程可以是昂贵的,特别是当组件树很大时。如果能够减少渲染次数,或减少需要进行diffing的组件数量,就可以显著提高应用性能。

通过shouldComponentUpdateReact.PureComponentReact.memo,我们可以控制哪些组件应当进行更新,哪些可以跳过更新过程。通过减少不必要的更新,我们减少了diffing和重新渲染的需要,从而提高了应用的性能。

综上所述,性能优化主要是通过减少不必要的组件渲染和diff计算来实现的,而shouldComponentUpdateReact.PureComponentReact.memo是实现这一目标的主要工具。

六 state 和 props 触发更新的生命周期分别有什么区别

在React中,stateprops的更新都能触发组件的重新渲染,但它们在触发更新时涉及的生命周期方法有所不同。理解这些差异有助于更有效地管理组件的行为和性能。以下是基于类组件的生命周期方法的讨论,因为它们在生命周期管理方面提供了明确的钩子。

props更新时

  1. getDerivedStateFromProps(props, state): 当组件实例化及接收新的props时被调用。它可以用来根据props的变化来更新state

  2. shouldComponentUpdate(nextProps, nextState): 在接收新的propsstate后,紧接着getDerivedStateFromProps执行。它决定了组件是否应该更新。如果此方法返回false,则不会继续更新流程(render, componentDidUpdate等不会被调用)。

  3. render: 如果shouldComponentUpdate返回true,则render方法会被调用来重新渲染界面。

  4. componentDidUpdate(prevProps, prevState, snapshot): 在组件更新后被调用。可以在这里执行依赖于DOM的操作或进行网络请求等异步操作,但应当小心不要引起无限更新循环。

state更新时

  1. shouldComponentUpdate(nextProps, nextState): 当通过setState触发state更新时,该方法同样被调用。它允许组件在更新之前决定是否需要重新渲染。

  2. render: 如果shouldComponentUpdate返回true,则render方法会被调用来重新渲染界面。

  3. componentDidUpdate(prevProps, prevState, snapshot): 在组件更新后被调用,同样适用于state更新。

区别

  • 更新源头: props更新通常源于父组件向子组件传递新的props,而state更新则是由组件内部的setState方法触发。
  • 生命周期方法: getDerivedStateFromPropsprops更新时会被调用,用于将props的变化映射到state上。而在state更新时,没有专门的生命周期方法在更新前被调用。两者都会触发shouldComponentUpdatecomponentDidUpdate
  • 控制更新: 对于propsstate的更新,都可以通过shouldComponentUpdate来控制组件是否应当更新,进而优化性能。

理解这些区别有助于开发人员更有效地使用React的生命周期方法,从而创建高效的、响应迅速的Web应用。

七 React中发起网络请求应该在哪个生命周期中进行?为什么

在React的类组件中,发起网络请求通常应该放在componentDidMount生命周期方法中。对于函数组件,使用Effect Hook(useEffect)来处理副作用,包括网络请求,是推荐的方式。

类组件中使用componentDidMount

componentDidMount在组件的生命周期中仅被调用一次,这发生在组件被渲染到DOM后。这样做有几个优点:

  • 避免不必要的重新渲染:将网络请求放在componentDidMount中,可以确保数据只在组件首次渲染后获取,从而避免由于组件状态更新导致的额外渲染。
  • 保证组件已挂载:在此生命周期方法中发起网络请求可以确保组件已经被挂载到DOM上,这意味着你可以安全地在请求成功后更新组件的状态,并且能够确保这些状态更新会引起组件的重新渲染。

函数组件中使用useEffect

对于函数组件,React 提供了useEffect Hook 来处理副作用,包括执行网络请求等异步操作。useEffect可以接收一个函数,React将在完成DOM更新后调用这个函数:

useEffect(() => {// 你的网络请求或其他副作用逻辑fetchData();
}, []); // 空数组意味着这个effect仅在组件挂载后运行一次

将空数组[]作为useEffect的第二个参数,可以确保副作用仅在组件挂载和卸载时运行,模拟了componentDidMountcomponentWillUnmount的行为。

为什么不在componentWillMountconstructor中?

  • constructor: 在构造函数中发起网络请求不是个好主意,因为此时组件尚未挂载,且如果构造函数触发重新渲染(例如,通过状态更新),则可能导致多次不必要的请求。
  • componentWillMount(已废弃): 在componentWillMount中发起网络请求也不推荐,因为它可能会在组件挂载前被调用多次(尤其是在未来的React版本中,随着异步渲染的引入)。这可能导致网络请求被不必要地多次执行。

总之,将网络请求置于componentDidMount或使用useEffect Hook 是基于确保组件已经挂载、避免不必要的重复请求以及遵循React的最佳实践的考虑。这样做既保证了数据的正确加载,又优化了组件的性能和可维护性。

八 React 16中新生命周期有哪些

React 16引入了几个新的生命周期钩子,旨在提高组件的可维护性与性能,同时也对一些旧的生命周期方法进行了标记,以在未来的版本中弃用。这些变化主要是为了配合React的异步渲染功能。下面是React 16中引入的一些新的生命周期方法:

static getDerivedStateFromProps(props, state)

这个静态方法在组件创建时和接收新的props时被调用。它应返回一个对象来更新state,或者返回null来表明新的props不需要更新任何state。这个生命周期方法是componentWillReceiveProps的替代品,用于准备更新阶段的state

getSnapshotBeforeUpdate(prevProps, prevState)

这个方法在最近一次渲染输出(提交到DOM节点)之前被调用。它使得组件能够在发生可能的改变之前从DOM中捕获一些信息(例如,滚动位置)。此生命周期返回的任何值都将作为参数传递给componentDidUpdate()

这些方法的添加是为了更好地支持异步渲染模式,使得在React的未来版本中,组件生命周期的管理更加灵活和高效。

弃用的生命周期方法(在React 16.x中标记为不安全)

  • componentWillMount(在React 17.x中被重命名为UNSAFE_componentWillMount
  • componentWillReceiveProps(在React 17.x中被重命名为UNSAFE_componentWillReceiveProps
  • componentWillUpdate(在React 17.x中被重命名为UNSAFE_componentWillUpdate

这些方法在React 16中仍然可用,但在开发者控制台中会生成警告,建议使用新的生命周期方法或其他替代方案。

推荐的模式

React团队鼓励开发者使用新的生命周期方法替代旧的将要被弃用的方法,并在可能的情况下,利用函数组件与Hooks,这些都是在React 16.8版本中引入的概念,以支持使用更现代的、更简洁的方式来编写组件与管理状态。

请注意,随着React版本的更新,推荐的最佳实践可能会发生变化,因此建议定期查阅React官方文档来获取最新的指导。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1045418.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法打卡day41|动态规划篇09| Leetcode198.打家劫舍、213.打家劫舍II、337.打家劫舍 III

算法题 Leetcode 198.打家劫舍 题目链接:198.打家劫舍 大佬视频讲解&#xff1a;198.打家劫舍视频讲解 个人思路 偷还是偷&#xff0c;这取决于前一个和前两个房是否被偷了&#xff0c;这种存在依赖关系的题目可以用动态规划解决。 解法 动态规划 动规五部曲&#xff1a;…

[Java基础揉碎]System类

1) exit 退出当前程序 2) arraycopy: 复制数组元素&#xff0c;比较适合底层调用&#xff0c;一般使用 Arrays.copyOf完成复制数组(Arrays.copyOf其实底层也是用的System.arraycopy, 本质是一样的) int[] src{1,2,3}; int[] dest new int[3]; System.arraycopy(src, 0, des…

14届蓝桥杯省赛 C/C++ B组 T8 整数删除(双向链表,堆)

瞬间定位一个数的左边或者右边&#xff0c;需要用到双向链表。 在过程中不断维护最小值&#xff0c;需要用到堆。 所以定义一个pair类型优先队列&#xff0c;每次取出堆顶进行删除&#xff0c;并且同时让删除元素的左右元素加上其值。 同时需要注意&#xff0c;在删除元素之后…

C++——栈和队列容器

前言&#xff1a;这篇文章我们将栈和队列两个容器放在一起进行分享&#xff0c;因为这两个要分享的知识较少&#xff0c;而且两者在结构上有很多相似之处&#xff0c;比如栈只能在栈顶操作&#xff0c;队列只能在队头和队尾操作。 不同于前边所分享的三种容器&#xff0c;这篇…

vue2实现wangEditor富文本便捷器的封装使用--真实项目

基于wangEditor 5实现一个简单的富文本编辑器组件&#xff0c;实现自定义上传图片。 官网地址&#xff1a;https://www.wangeditor.com/v5/for-frame.html#%E9%85%8D%E7%BD%AE 1. 安装依赖包&#xff1a; npm i wangeditor/editor --save npm i wangeditor/editor-for-vue --…

HarmonyOS 开发-数据库版本升级案例

介绍 本示例介绍使用关系型数据库的接口来进行数据库升降级场景实现 效果预览图 使用说明 加载完成后有版本升级以及版本恢复两种按钮点击版本升级下的”升级至V2“按钮&#xff0c;则数据库版本会从V1升级至V2&#xff0c;且在表格处显示V1和V2版本表格字段对比。点击版本升…

CNN-Transformer时间序列预测

部分代码&#xff1a; # CNN-Transformer class CNNTransformerEncoder(nn.Module):def __init__(self, input_features, transformer_encoder_heads,embedding_features, cnn_kernel_size, dim_feedforward_enc, n_encoder_layer):super(CNNTransformerEncoder, self).__init…

AcWing [875]快速幂(C++)

给定 n 组 ai,bi,pi&#xff0c;对于每组数据&#xff0c;求出 ai^bi mod pi 的值。 输入格式 第一行包含整数 n。 接下来 n行&#xff0c;每行包含三个整数 ai,bi,pi。 输出格式 对于每组数据&#xff0c;输出一个结果&#xff0c;表示 ai^bi mod pi 的值。 每个结果占一…

提升Terraform工作流程最佳实践

Terraform 是管理基础设施及代码&#xff08;IaC&#xff09;最常用的工具之一&#xff0c;它能使我们安全且可预测地对基础设施应用更改。刚开始上手 Terraform 可能会感觉有些不容易&#xff0c;但很快就能对该工具有基本的了解&#xff0c;随之可以开始运行命令、创建和重构…

python爬虫 爬取网页图片

http://t.csdnimg.cn/iQgHw //爬虫爬取图片其实是很简单的&#xff0c;但是大多数同学&#xff0c;可能对 url的设置一直有困惑&#xff08;这点本人也在研究&#xff09;&#xff0c;而本篇文章&#xff0c;对于想要爬取图片的小白简直是福利。你只需要将文章代码运行即可&am…

详细分析Vuex中的mapGetters

目录 1. 基本知识2. Demo13. Demo2 1. 基本知识 优势和用途 简化代码&#xff1a;用 mapGetters 和 mapState&#xff0c;可以简化组件中对于 Vuex 中状态和 getter 的映射工作&#xff0c;减少了重复的代码书写更易读&#xff1a;组件中直接使用映射的计算属性&#xff0c;使…

基于SSM+Jsp+Mysql的快递管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

h5页面弹窗

div <div v-if"isShowQR" class"QRAlert"><div class"QR-container"><div class"QR-code-bg"><div class"title" v-if"isApp">{{selectedItem.title}}APP下载</div><div class…

JUC:实现一个简易的数据库连接池(享元模式)

主要是学习享元模式。 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;旨在通过共享尽可能多的对象来最小化内存使用和提高性能。在该模式中&#xff0c;对象被分为两种状态&#xff1a;内部状态和外部状态。 内部状态&#xff08;Intr…

烤羊肉串引来的思考--命令模式

1.1 吃羊肉串&#xff01; 烧烤摊旁边等着拿肉串的人七嘴八舌地叫开了。场面有些混乱&#xff0c;由于人实在太多&#xff0c;烤羊肉串的老板已经分不清谁是谁&#xff0c;造成分发错误&#xff0c;收钱错误&#xff0c;烤肉质量不过关等。 外面打游击烤羊肉串和这种开门店做烤…

FIR滤波器(汉宁窗设计)的MATLAB代码

FIR滤波器&#xff0c;即有限脉冲响应滤波器&#xff08;Finite Impulse Response Filter&#xff09;&#xff0c;是数字信号处理中的一种滤波器。它的特点在于&#xff0c;滤波器的单位冲激响应是有限长度的&#xff0c;这意味着当给定一个输入信号后&#xff0c;输出信号只会…

自动驾驶传感器:传感的本质

自动驾驶传感器&#xff1a;传感的本质 附赠自动驾驶学习资料和量产经验&#xff1a;链接 0. 前言 这个系列的背景是&#xff1a;工作时候需要攒一台数据采集车辆&#xff0c;那段时间需要熟悉感知硬件&#xff0c;写了不少笔记&#xff0c;都是些冗长的文章&#xff0c;感兴…

【电路笔记】-逻辑非门

逻辑非门 文章目录 逻辑非门1、概述2、晶体管逻辑非门3、六角施密特反相器逻辑非门是所有逻辑门中最基本的,通常称为反相缓冲器或简称为反相器。 1、概述 反相非门是单输入器件,其输出电平通常为逻辑电平“1”,当其单个输入为逻辑电平“1”时,输出电平变为“低”至逻辑电平…

意得辑意得辑

你是否也曾遇到过在发表论文时英语写作水平不尽如人意的困境&#xff1f;审稿意见总是指出语言表达不够好&#xff0c;需要找英语母语者修改&#xff1f;不用担心&#xff0c;我和你一样&#xff0c;也曾历经这样的挑战。但是&#xff0c;我找到了一家值得信赖的专业润色机构—…

读书笔记之人生算法(7)

孤独、爆仓与迷信 跨越出身和运气&#xff0c;实现富足与自由&#xff0c;用概率思维做好决策 13 孤独 孤独&#xff1a;获得好姻缘的算法 姻缘是奇妙的东西&#xff0c;体现了世界的随机性&#xff1a;即使是最理性的人&#xff0c;也可能需要靠运气寻找另一半。 中国有句古话…