React Native 复杂列表开发与性能优化全攻略(现在看为时不晚!)


​微信公众号:小武码码码

大家好,上一篇分享了 Flutter复杂列表开发与性能优化全攻略。那接下来这一篇,我想和大家分享一下在 React Native 中开发复杂列表的经验和心得。作为移动开发中最常见的 UI 组件之一,列表几乎出现在每一个应用中。然而,当列表变得复杂起来,包含各种不同的样式和交互时,如何进行高效的开发和优化,就成了一个值得深入探讨的问题。

在本文中,我将从以下几个方面,与大家深入探讨 React Native 复杂列表的开发和优化策略:

  1. React Native 中常见的复杂列表样式及其应用场景
  2. React Native 复杂列表的几种主要开发方式及其优缺点
  3. React Native 复杂列表的高度自适应优化方案及其实现细节
  4. React Native 复杂列表的性能优化策略及其具体实践
  5. React Native 列表与原生列表的差异及其优劣势比较

让我们开始这一场复杂列表开发和优化之旅吧!

一、React Native 中常见的复杂列表样式及其应用场景

在 App 开发中,我们经常会遇到各种复杂的列表需求。这些复杂列表在样式和功能上往往有其特殊性,需要针对性地进行开发和优化。下面,就让我们一起来看看 React Native 中几种常见的复杂列表样式:

  1. 聊天列表。聊天列表是社交类应用中最常见的列表样式之一,主要用于展示用户之间的对话内容。聊天列表具有如下特点:

    • 列表项可以是文本、图片、语音等多种类型的消息。
    • 列表项根据消息的发送者和时间戳,分左右两种不同的排列样式。
    • 列表项可以包含用户昵称、头像等额外信息。
    • 列表往往可以下拉刷新,上拉加载更多消息。
    • 列表需要支持消息发送状态(发送中/发送成功/发送失败)的显示。
  2. Feed 流列表。Feed 流列表是资讯类和社交类应用中最常见的列表样式之一,主要用于向用户展示持续更新的内容。Feed 流列表具有如下特点:

    • 列表项的内容形式多样,可以包含文字、图片、视频、链接等。
    • 列表项的布局千变万化,既有上下滑动,也有左右滑动。
    • 列表项往往可以进行点赞、评论、转发等交互操作。
    • 列表往往可以下拉刷新,上拉加载更多内容。
    • 列表项可以根据内容类型或者互动数据,显示不同的样式。
  3. 电商商品列表。电商商品列表在电商类应用中非常常见,主要用于展示商品的基本信息和销售数据。电商商品列表具有如下特点:

    • 列表项包含商品的图片、名称、价格、评分等关键信息。
    • 列表提供多种排序方式,如按价格、评分、销量等。
    • 列表支持按品牌、型号等条件进行筛选过滤。
    • 列表支持网格和列表两种视图切换。
    • 列表项点击后可以跳转到商品详情页面。
  4. 复杂表格列表。复杂表格列表主要用于展示结构化的数据,如统计报表、订单明细等。复杂表格列表具有如下特点:

    • 表格包含多列,每一列都有其特定的数据类型和格式。
    • 表格需要对列进行自适应,以便在不同尺寸屏幕上都能完整展示。
    • 表格需要固定表头,以便在纵向滚动时仍然能够看到每一列的名称。
    • 表格需要支持横向滚动,以便展示所有的列。
    • 表格往往需要分页展示,并提供跳转控制。

可以看到,复杂列表的样式和需求千差万别,这就要求我们在开发时,既要保证列表的功能完整性,又要兼顾列表的展示效果和性能体验。那么,在 React Native 中,我们到底应该如何实现这些复杂列表呢?接下来,我们就一起来看看。

二、React Native 复杂列表的几种主要开发方式及其优缺点

React Native 为我们提供了多种开发列表的方式,每一种方式都有其独特的优势和局限。下面,我就来介绍几种主要的复杂列表开发方式:

  1. FlatList 组件FlatList 是 React Native 中最基本的列表组件,用于高效地渲染长列表数据。使用 FlatList,我们只需指定列表数据和渲染函数,即可快速生成可滚动的列表视图。
<FlatList
  data={data}
  renderItem={({item}) => <Item title={item.title} />}
  keyExtractor={item => item.id}
/>

FlatList 的优点在于:

  • 开箱即用,使用简单。
  • 支持下拉刷新、上拉加载等常见交互。
  • 支持 onEndReached 等事件回调。
  • 支持 ListHeaderComponentListFooterComponent 等自定义组件。

然而,FlatList 也存在一些局限性:

  • 不支持 section 分组和 sticky header。
  • 对于复杂的列表项布局,需要自行控制高度和复用。
  • 对于异构列表数据,需要自行处理数据源和渲染逻辑。
  1. SectionList 组件SectionList 是 React Native 中用于渲染分组列表的组件,可以将列表数据按照一定的逻辑分成若干个 section,每个 section 包含一个 header 和若干个 item。
<SectionList
  sections={[
    {title: 'Title1', data: [...]},
    {title: 'Title2', data: [...]},
    {title: 'Title3', data: [...]},
  ]}
  renderItem={({item}) => <Item title={item.title} />}
  renderSectionHeader={({section}) => <Header title={section.title} />}
    keyExtractor={(item, index) => item + index}
/>

SectionList 的优点在于:

  • 支持 section 分组和 sticky header。
  • 对于需要分组展示的列表数据,逻辑更加清晰。
  • 可以对不同 section 的 header 和 item 分别定制样式和逻辑。

然而,SectionList 也存在一些局限性:

  • 只支持纵向滚动,不支持横向滚动。
  • 对于 section 内部的列表项,复用逻辑需要自行控制。
  • 在 section 数量较多时,sticky header 的定位和样式需要细心调试。
  1. ScrollView + 自定义布局。对于一些对样式和交互有特殊需求的列表,我们还可以直接使用 ScrollView 组件,结合自定义的布局来实现。
<ScrollView>
  <View style={styles.item}>
    <Text>{item1.title}</Text>
  </View>
  <View style={styles.item}>
    <Text>{item2.title}</Text>
    <Image source={item2.image} />
  </View>
  <CustomItem data={item3} />
  ...
</ScrollView>

ScrollView + 自定义布局的优点在于:

  • 可以完全自由地控制列表的展示样式和交互逻辑。
  • 可以实现一些非常规的列表布局,如瀑布流、双向滚动等。
  • 可以方便地引入各种自定义组件,提高列表的灵活性。

然而,ScrollView + 自定义布局也存在一些局限性:

  • 需要自行处理列表项的渲染和复用,容易引入性能问题。
  • 需要自行实现下拉刷新、上拉加载等交互逻辑。
  • 对于超长列表,需要考虑分页加载等优化策略。
  1. VirtualizedList 组件VirtualizedList 是 React Native 中最复杂、最灵活的列表组件,它不仅支持常见的列表功能,还提供了一整套完整的列表优化方案。
<VirtualizedList
  data={data}
  renderItem={({item}) => <Item title={item.title} />}
  getItem={(data, index) => data[index]}
  getItemCount={data => data.length}
  keyExtractor={(item, index) => item.id}
  getItemLayout={(data, index) => (
    {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
  )}
/>

VirtualizedList 的优点在于:

  • 支持大数据量的列表渲染,通过懒渲染和回收机制,保证列表的流畅度。
  • 支持列表项高度的预估和缓存,避免了滚动过程中的大量计算。
  • 支持列表项的叠加和吸顶效果,提供了更加丰富的展示形式。

然而,VirtualizedList 也存在一些局限性:

  • 接口和参数较多,上手成本较高。
  • 需要准确地估算列表项高度,否则可能出现白屏等问题。
  • 在某些场景下,需要自行管理列表项的渲染和回收。

以上就是 React Native 中常见的几种复杂列表开发方式,在实际项目中,我们需要根据列表的具体需求和场景,选择合适的方式来实现。当然,无论选择哪种方式,性能始终是需要关注的重点。那么,对于复杂列表的性能优化,我们又该从哪些方面入手呢?让我们继续往下看。

三、React Native 复杂列表的高度自适应优化方案及其实现细节

在 React Native 中,列表的性能很大程度上取决于列表项的高度计算和布局。如果列表项的高度不固定、不可预估,就可能导致滚动过程中的大量重排和重绘,从而影响列表的流畅度。因此,对于复杂列表的性能优化,首要任务就是要实现列表项高度的自适应。

那么,在 React Native 中,我们如何实现列表项高度的自适应呢?下面,我就来介绍几种常见的方案:

  1. 利用 Flex 布局实现列表项高度自适应。对于一些简单的列表项,我们可以利用 Flex 布局来实现高度自适应。具体来说,就是将列表项的根节点设置为 flex: 1,然后在内部使用 flexDirectionjustifyContentalignItems 等属性来控制子节点的排列方式。
<View style={{flex: 1, flexDirection: 'row', alignItems: 'center'}}>
  <Image style={{width: 50, height: 50}} source={item.avatar} />
  <View style={{flex: 1, marginLeft: 10}}>
    <Text style={{fontSize: 18}}>{item.name}</Text>
    <Text style={{fontSize: 14, color: '#999'}}>{item.subtitle}</Text>
  </View>
</View>

在上面的代码中,我们将列表项分为左右两部分,左边是固定尺寸的头像,右边是自适应的文本。通过将右边的容器设置为 flex: 1,就可以让文本区域自动填充剩余空间,从而实现了列表项整体高度的自适应。

这种方式的优点是简单直观,适用于布局比较规则的列表项。然而,它也存在一些局限性:

  • 对于布局不规则、嵌套层级较深的列表项,Flex 布局可能无法完全实现自适应。
  • 当列表项内部出现异步加载的内容(如网络图片)时,容器的高度可能会发生变化,导致布局错乱。
  1. 使用 onLayout 方法获取列表项的实际高度。对于一些高度不固定,依赖于内容的列表项,我们可以通过 onLayout 方法来获取它们的实际高度,并在渲染时将高度传递给 VirtualizedList 或 FlatList
class Item extends React.Component {
  state = {
    height: 0,
  };

  onLayout = (event) => {
    const { height } = event.nativeEvent.layout;
    this.setState({ height });
    this.props.onItemLayout(this.props.index, height);
  };

  render() {
    return (
      <View onLayout={this.onLayout}>
        <Text>{this.props.item.title}</Text>
        <Image source={this.props.item.image} />
      </View>
    );
  }
}

class MyList extends React.Component {
  itemHeights = [];

  onItemLayout = (index, height) => {
    this.itemHeights[index] = height;
  };

  getItemLayout = (data, index) => {
    return {
      length: this.itemHeights[index] || 0,
      offset: this.itemHeights.slice(0, index).reduce((a, b) => a + b, 0),
      index,
    };
  };

  render() {
    return (
      <VirtualizedList
        data={this.props.data}
        renderItem={({ item, index }) => (
          <Item item={item} index={index} onItemLayout={this.onItemLayout} />
        )}
        getItemCount={(data) => data.length}
        getItem={(data, index) => data[index]}
        getItemLayout={this.getItemLayout}
      />
    );
  }
}

在上面的代码中,我们封装了一个 Item 组件,它会在布局完成后通过 onLayout 方法获取自身的实际高度,并通过 onItemLayout 回调将高度传递给父组件。父组件 MyList 内部维护了一个 itemHeights 数组,用于缓存所有列表项的高度。同时,我们还实现了 getItemLayout 方法,根据 itemHeights 数组计算每个列表项的布局信息。

这种方式的优点是可以精确地获取每个列表项的实际高度,即使列表项高度不固定也能实现完美的自适应。然而,它也存在一些局限性:

  • 由于需要额外的高度计算和缓存,因此在性能上会有一定的开销。
  • 当列表项个数非常多时,itemHeights 数组可能会占用较大的内存空间。
  1. 利用占位组件实现列表项高度的预估。在一些场景下,我们可以预先估算列表项的平均高度,将这个估算高度作为列表项的占位高度,等到列表项真正渲染时再更新为实际高度。这样,即使在初次渲染时,列表项高度也能保持相对准确,不会出现大幅度的跳动。
class MyList extends React.PureComponent {
  state = {
    itemHeights: new Array(this.props.data.length).fill(200),
  };

  onItemLayout = (index, height) => {
    const itemHeights = [...this.state.itemHeights];
    itemHeights[index] = height;
    this.setState({itemHeights});
  }

  getItemLayout = (data, index) => {
    return {
      length: this.state.itemHeights[index],
      offset: this.state.itemHeights.slice(0, index).reduce((a, b) => a + b, 0),
      index,
    };
  }

  render() {
    return (
      <VirtualizedList
        data={this.props.data}
        renderItem={({item, index}) => (
          <Item
            item={item}
            index={index}
            onItemLayout={this.onItemLayout}
            estimatedHeight={this.state.itemHeights[index]}
          />
        )}
        getItemCount={data => data.length}
        getItem={(data, index) => data[index]}
        getItemLayout={this.getItemLayout}
      />
    );
  }
}

class Item extends React.PureComponent {
  render() {
    const {item, estimatedHeight, onItemLayout} = this.props;
    return (
      <View onLayout={({nativeEvent}) => onItemLayout(this.props.index, nativeEvent.layout.height)}>
        <View style={{height: estimatedHeight}}>
          <Text>{item.title}</Text>
          <Image source={item.image} />
        </View>
      </View>
    );
  }
}

在上面的代码中,我们使用一个 200 像素的估算高度来初始化 itemHeights 数组。在渲染列表项时,我们将这个估算高度传递给 Item 组件,作为列表项的占位高度。Item 组件内部渲染一个占位元素,高度等于估算高度,从而在初次渲染时,列表项整体高度能够保持稳定。等到列表项布局完成后,我们再通过 onLayout 方法获取实际高度,并更新 itemHeights 数组。

这种方式的优点是可以显著减少列表项渲染时的跳动,在视觉上给人更加连贯顺滑的感受。同时,它也兼顾了性能,避免了大量的重排重绘。然而,它也存在一些局限性:

  • 估算高度难以做到十分精确,因此在某些场景下,仍然可能出现轻微的跳动。
  • 对于高度差异很大的列表项,该方案的效果可能不太理想。

四、React Native 复杂列表的性能优化策略及其具体实践

除了高度自适应外,React Native 复杂列表的性能优化,还需要从以下几个方面入手:

  1. 使用 PureComponent 和 React.memo 减少不必要的渲染。在 React Native 中,组件的重新渲染是影响性能的主要因素之一。为了避免不必要的渲染,我们可以将列表项组件继承自 PureComponent,或者使用 React.memo 对其进行包装。这样,只有当 props 发生变化时,列表项才会重新渲染。
class Item extends React.PureComponent {
  render() {
    // ...
  }
}

// 或者
const Item = React.memo(function Item(props) {
  // ...
});
  1. 使用唯一且稳定的 key 属性。在渲染列表时,每个列表项都需要一个唯一的 key 属性,以便 React Native 能够准确地识别和复用列表项。如果 key 不唯一或者不稳定,就可能导致大量的重新渲染和重新创建,从而影响性能。因此,我们需要为列表项选择合适的 key,最好是来自数据本身的 id 字段。
<VirtualizedList
  data={this.props.data}
  renderItem={({item}) => <Item item={item} />}
  keyExtractor={item => item.id}
/>
  1. 尽量避免在列表项中使用箭头函数和匿名函数。在列表项中使用箭头函数或匿名函数,会导致每次渲染时都创建新的函数实例,从而触发列表项的重新渲染。为了避免这种情况,我们可以将事件处理函数提取到列表项组件的外部,或者使用类方法来定义事件处理函数。
class Item extends React.PureComponent {
  onPress = () => {
    this.props.onItemPress(this.props.item);
  }

  render() {
    return <TouchableOpacity onPress={this.onPress}>...</TouchableOpacity>;
  }
}
  1. 在列表项中延迟加载或者懒加载非关键渲染路径上的组件和数据。对于一些复杂的列表项,我们可以将其分解为多个部分,关键部分优先渲染,非关键部分延迟加载。这样可以避免一次性渲染大量的内容,从而提高列表的响应速度。常见的延迟加载技术包括:
  2. 渐进式图片加载。在列表项中显示图片时,先展示一个占位图,然后在后台加载真实图片,加载完成后再替换占位图。这样可以避免图片加载阻塞列表渲染。
  3. 懒加载列表项内容。在列表项首次出现在屏幕上时,只渲染关键内容,等列表项完全展示后,再去加载剩余内容。比如 IM 聊天中的语音消息,可以先显示一个语音 icon,等用户点击后再去加载语音内容。
  4. 使用 InteractionManager 将耗时操作移到非关键渲染路径InteractionManager 允许我们在关键交互完成后,再去执行一些耗时操作,从而避免这些操作阻塞用户交互。比如在复杂列表初次渲染后,我们可以在 InteractionManager 的回调中去加载列表数据。

下面是一个渐进式图片加载的示例:

function ProgressiveImage(props) {
  const [loadedSrc, setLoadedSrc] = useState(null);
  const ref = useRef();

  useEffect(() => {
    if (ref.current) {
      ref.current.onload = () => setLoadedSrc(props.src);
    }
  }, [props.src, ref]);

  return (
    <View style={props.style}>
      {loadedSrc ? (
        <Image style={props.style} source={{uri: loadedSrc}} />
      ) : (
        <Image
          ref={ref}
          style={props.style}
          source={props.placeholder}
          blurRadius={1}
        />
      )}
    </View>
  );
}
class MyList extends React.Component {
  state = {
    data: [],
  };

  componentDidMount() {
    InteractionManager.runAfterInteractions(() => {
      fetchData().then(data => this.setState({data}));
    });
  }

  render() {
    return <VirtualizedList data={this.state.data} />;
  }
}

五、React Native 列表与原生列表的差异及其优劣势比较

在 App 开发中,除了使用 React Native 实现列表外,我们还可以选择原生的列表组件,比如 iOS 的 UITableView 和 Android 的 RecyclerView。那么,React Native 列表与原生列表相比,有哪些差异呢?各自的优劣势又是什么?

首先,从开发效率来看,React Native 列表无疑更胜一筹。使用 React Native,我们可以用一套代码同时适配 iOS 和 Android 两端,不仅可以显著减少开发和维护成本,还能保证双端表现的一致性。而使用原生列表,我们就需要分别编写 iOS 和 Android 两套代码,工作量要大很多。

其次,从性能角度来看,原生列表通常会更加流畅和高效。原生列表组件是直接使用平台自带的渲染引擎,能够最大限度地发挥设备的性能。而 React Native 列表是在 JavaScript 线程和原生主线程之间进行通信,这就不可避免地带来了一些性能损耗。特别是在列表项非常复杂,或者数据量非常大时,React Native 列表可能会出现卡顿和掉帧。

再次,从功能扩展性来看,原生列表可以支持更多自定义的功能和交互,比如 iOS 的 UITableViewCell 可以轻松实现左滑删除、右滑编辑等手势操作。而在 React Native 中,实现这些功能就需要额外的开发成本。当然,React Native 也有其独特的优势,比如 React 生态提供了大量优质的第三方组件,使用它们可以快速搭建起复杂的列表页面。

综合来看,React Native 列表与原生列表其实是相辅相成的,我们可以根据实际情况选择合适的技术方案。对于大多数常规的列表需求,使用 React Native 完全可以满足。但是对于对性能和体验要求非常高的场景,比如 IM 聊天、电商首页等,使用原生列表可以获得更好的效果。理想的做法是,将 React Native 与原生列表结合起来,发挥各自的优势:在跨平台的基础上引入原生列表,既提高了开发效率,又兼顾了用户体验。

小结

本文从复杂列表样式、开发方式、高度自适应和性能优化等多个角度,全面探讨了 React Native 复杂列表的开发和优化策略。我们还将 React Native 列表与原生列表进行了对比,分析了彼此的优劣和适用场景。可以看到,React Native 凭借其高效的开发模式和灵活的扩展能力,已经成为移动端列表开发的重要选择。

作为一名 React Native 开发工程师,掌握复杂列表的实现和优化,是非常重要且必要的。我们需要在实践中不断积累经验,研究新的技术方案,力求为用户提供流畅、顺滑的列表体验。这不仅需要扎实的编程功底,还需要多方面的综合素质,比如产品思维、设计理念等。

展望未来,相信 React Native 在列表领域还将不断突破创新,为开发者带来更多惊喜。让我们拭目以待吧!

以上就是我对 React Native 复杂列表开发和优化的一些思考和总结,希望对大家有所帮助。也欢迎大家留言交流,分享你的经验和见解!

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

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

相关文章

Shader for Quest 2: 自定义shader在Unity Editor中可以使用,但是在Quest 2中却不可以

GameObject segment GameObject.Find("DisplayArea_" i); MeshRenderer renderer segment.GetComponent<MeshRenderer>(); Material mat new Material(Shader.Find("Custom/MyShader")); mat.mainTexture option.Image360;上面这份代码&#x…

低代码开发之腾讯云微搭工具

低代码开发之腾讯云微搭工具 微搭简介诞生缘由开发模式如何创建组件模块介绍实例讲解url传参级联联动使用事件其他方法调用数据源方法 callDataSource触发流程 callProcess 引入外部css/js代码编辑器的使用Handler 方法使用介绍Style 用法示例LifeCycle 生命周期介绍 数据模型方…

【1471】java项目进度管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 项目进度管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

测试必备 | 测试工程师必知的Linux命令有哪些?

在日常的测试工作中&#xff0c;涉及到测试环境搭建及通过查看日志来定位相关问题时经常会用到Linux&#xff0c;在测试工程师的面试中也经常会有笔试或面试的题目来考查测试人员对Linux的熟悉程度&#xff0c;这里分享下测试工程师需知的 Linux 命令有哪些。 Linux 作为一种常…

【 书生·浦语大模型实战营】作业(四):XTuner 微调 LLM:1.8B、多模态、Agent

【 书生浦语大模型实战营】作业&#xff08;五&#xff09;&#xff1a;LMDeploy 量化部署 &#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系…

模块四:前缀和——DP35 【模板】二维前缀和

文章目录 题目描述算法原理解法一&#xff1a;暴力模拟&#xff08;时间复杂度为O(n*m*q)&#xff09;解法二&#xff1a;二维前缀和&#xff08;时间复杂度为O(m*n)O(q)) 代码实现解法二&#xff1a;前缀和&#xff08;C)Java 题目描述 题目链接&#xff1a;DP35 【模板】二维…

微信第三方开放平台,实现代公众号保留排版样式和图片发布文章

大家好&#xff0c;我是小悟 要想实现代公众号发布文章的功能&#xff0c;就得接入富文本编辑器&#xff0c;市面上富文本编辑器有很多&#xff0c;轻量的、重量的都有。 从开发者的角度&#xff0c;自然把轻量作为第一选择&#xff0c;因为好对接&#xff0c;怎么方便怎么来…

基于 SpringCloud 的在线交易平台乐优商城的设计与实现(六)

目录 第六章 系统测试 6.1 功能性测试 6.1.1 商家后台功能测试 6.1.2 前台功能测试 6.2 非功能性测试 6.3 本章小结 结束语 参考文献 前面内容请移步 基于 SpringCloud 的在线交易平台乐优商城的设计与实现&#xff08;五&#xff09; 相关免费源码资源 乐优商城…

2024年【制冷与空调设备运行操作】最新解析及制冷与空调设备运行操作免费试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 制冷与空调设备运行操作最新解析是安全生产模拟考试一点通生成的&#xff0c;制冷与空调设备运行操作证模拟考试题库是根据制冷与空调设备运行操作最新版教材汇编出制冷与空调设备运行操作仿真模拟考试。2024年【制冷…

不只有 Spring,这四款Java 基础开发框架同样值得关注!

Java 开发不只有 Spring &#xff0c;今天给大家推荐几个同样优秀的 Java 基础开发框架&#xff0c;为日常项目开发提供更多的选择。答应我&#xff0c;请不要再叫我 Spring 小子了&#xff0c;​好吗&#xff1f; 项目概览&#xff1a; Guice&#xff1a;轻量级依赖注入框架 …

构建本地大语言模型知识库问答系统

MaxKB 2024 年 4 月 12 日&#xff0c;1Panel 开源项目组正式对外介绍了其官方出品的开源子项目 ——MaxKB&#xff08;github.com/1Panel-dev/MaxKB&#xff09;。MaxKB 是一款基于 LLM&#xff08;Large Language Model&#xff09;大语言模型的知识库问答系统。MaxKB 的产品…

Intelij Idea Push失败,出现git Authentication failed(验证失败)

目录 1、出现问题的原因 2、解决之法 1、出现问题的原因 能出现这种问题&#xff0c;最主要的原因是链接对上了&#xff0c;但用户验证失败了&#xff0c;即登录失败。 因为服务器转移或者换了git项目链接&#xff0c;导致你忘记了用户名密码&#xff0c;随意输入之后&…

P44,45 属性预处理,执行后游戏效果回调,附录指定区域内修改变量

这节课主要是怎么对Attribute进行在进行到游戏角色前先进行处理,以及游戏效果如何回调 AuraAttributeSet.h // Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "AttributeSet.h&…

如何禁用WordPress的自动更新(包括主题、插件和核心文件)

这几天发现我的一个网站突然打不开了&#xff0c;提示“此站点遇到了致命错误”,如图&#xff1a; 这个网站一直都是正常运行的&#xff0c;最近也没有过什么更新&#xff0c;按理说不应该会出现问题&#xff0c;我担心可能是主机方面做了什么调整导致&#xff0c;所以联系了Ho…

品鉴中的个人偏好:如何找到适合自己的红酒风格

品鉴红酒时&#xff0c;个人偏好起着至关重要的作用。不同的人对红酒的风格、口感和特点有着不同的喜好和需求。对于云仓酒庄雷盛红酒而言&#xff0c;如何找到适合自己的红酒风格&#xff0c;是品鉴过程中需要关注的问题。 首先&#xff0c;了解自己的口味和喜好是找到适合自己…

spi接口的基本概念、引脚定义及注意事项

目录 基本概念 引脚定义 注意事项 SPI&#xff08;Serial Peripheral Interface&#xff09;是一种同步串行接口技术&#xff0c;广泛应用于微控制器和各种外围设备之间的短距离通信。 基本概念 SPI接口允许微控制器以串行方式与一个或多个外围设备进行通信。它是一种高速、…

B端:销售投入远超研发投入,想让B端漂亮体验好,非常难。

足够的研发费用是确保B端系统研发体验好、品质佳的重要条件之一。在B端系统研发过程中&#xff0c;足够的研发费用可以用于以下方面&#xff1a; 1.人才投入&#xff1a; 招聘高素质的研发团队成员&#xff0c;包括开发工程师、测试工程师、产品设计师、运维工程师等&#xf…

【进程通信】利用管道创建进程池(结合代码)

文章目录 什么叫进程池进程池的优点 创建进程池代码实现&#xff1a; 什么叫进程池 我们知道&#xff0c;一个进程创建子进程通常是为了让这个子进程去为它完成某个任务。例如我们使用的指令&#xff0c;其实就是bash进程创建子进程让子进程去执行的。但是我们需要考虑这样一个…

RLDP协议原理与应用

RLDP概述 l RLDP全称是Rapid Link Detection Protocol&#xff08;快速链路检测协议&#xff09;&#xff0c;是锐捷网络自主开发的&#xff0c;用于快速检测以太网链路故障的链路协议。 l 一般的以太网链路检测机制都只是利用物理连接的状态&#xff0c;通过物理层的自动协…

React | classnames

classnames 这个库在我们的项目中有大量的使用到&#xff0c;它不仅很实用&#xff0c;还非常好用&#xff0c;但还有人不知道这个库&#xff0c;我真的是十分心痛。 通过 classnames&#xff0c;我们可以给组件设置多个 className&#xff0c;还可以根据需要动态设置 classNa…