当前位置: 首页 > news >正文

UITableVIew性能优化概述

UITableVIew性能优化概述

文章目录

  • UITableVIew性能优化概述
    • 前言
    • 如何优化
      • 优化的本质
      • 卡顿的原因
    • CPU层级
      • cell复用
        • UITableVIew尽量采用复用
      • 定义cell的种类尽量少,可以多用hidden
      • 缓存cell高度
        • 基础设置
        • 预先设置高度
        • 设置一个预先缓存
      • 异步绘制
      • 滑动按照需加载
      • 尽量显示大小刚好合适的图片资源
      • 图片异步加载
      • 直接设置frame
      • 采用轻量级对象
    • GPU层级
      • 减少透明处理
      • 控制尺寸
      • 减少图层混合操作
      • 避免离屏渲染
        • 为什么要避免离屏渲染?
        • 优化圆角
        • 阴影优化
    • 总结

前言

笔者这段时间把项目也结束了,现在整理一下这段实现学到的东西,以及一些性能优化的内容,这篇主要讲一下iOS开发中比较重要的一个UITableView的优化。

如何优化

UITableView 的优化主要从四个方面入手:
提前计算并缓存好高度(布局),因为 tableView:heightForRowAtIndexPath: 是调用最频繁的方法;
滑动时按需加载,防止卡顿。这个在大量图片展示,网络加载的时候很管用,配合 SDWebImage;
异步绘制,遇到复杂界面,遇到性能瓶颈时,可能就是突破口;
缓存一切可以缓存的,这个在开发的时候,往往是性能优化最多的方向。

大概需要关注的:
cell 复用;
cell 高度的计算;
渲染(混合问题);
减少视图的数目(重写 drawRect:);
减少多余的绘制操作;
不要给 cell 动态添加 subView;
异步化 UI,不要阻塞主线程;
滑动时按需加载对应的内容。

引用自iOS之性能优化·UITableView深度优化

优化的本质

UITableView 的优化本质在于提高滚动性能和减少内存使用,以保证流畅的用户体验,从计算机层面来讲,其核心本质为降低 CPU和GPU 的工作来提升性能

CPU:对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制
GPU:接收提交的纹理和顶点描述、应用变换、混合并渲染、输出到屏幕
引用自【iOS】UITableView性能优化

卡顿的原因

App主线程在CPU中显示计算内容,比如视图的创建,布局的计算,图片解码,文本绘制,然后我们的CPU会将计算好的内容提交到GPU中进行变换,合成,渲染,这其中也包括我们常说的离屏渲染

在开发中,CPUGPU任何一个压力过大都会导致掉帧

引用自【iOS】UITableView性能优化

CPU层级

cell复用

UITableVIew尽量采用复用
  • 首先我们都知道UITableVIew最核心的一个思想就是UITableViewCell的一个复用,也就是一个享元模式的思想,这个方式极大程度上的降低了内存的开销。当要显示某一位置的 Cell 时,会先去集合(或数组)中取,如果有,就直接拿来显示;如果没有,才会创建。

首先我们在很多地方都可以看到对于这两个函数做的一个性能优化:

tableView:cellForRowAtIndexPath: 
tableView:heightForRowAtIndexPath:

某些时候,我们会认为他是先调用height再调用cell方法,但是实际上并非如此,我们可以看下面打印信息

image-20250413203518757

显然这里颠覆了我们的一个普遍认知。

这里笔者找到了一段解释这个原因比较好的话:

我们都知道,UITableView 是继承自 UIScrollView 的,需要先确定它的 contentSize 及每个 Cell 的位置,然后才会把重用的 Cell 放置到对应的位置。所以事实上,UITableView 的回调顺序是先多次调用 tableView:heightForRowAtIndexPath: 以确定 contentSize 及 Cell 的位置,然后才会调用 tableView:cellForRowAtIndexPath:,从而来显示在当前屏幕的 Cell。

所以我们创建一个对应cell标识符的时候,可以采用这种方式:

static NSString *cellId = @"Cell";

这样可以减少我们的一个字符串的开销。

这里我们在看一下创建cell的两个函数:

 - (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;  // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one.- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered
  • dequeueReusableCellWithIdentifier:forIndexPath 如果没有注册复用 identifier,执行这句时会崩溃
  • dequeueReusableCellWithIdentifier 如果没有注册复用 identifier,语句返回 nil,继续执行会崩溃
if (!cell) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];}//采用这个可以防止他nil带来的一个问题
  • 为什么需要 forIndexPath:?
  • 因为在返回 cell 之前,会调用委托 tableView:heightForRowAtIndexPath:来确定 cell 尺寸(如果已经定义该函数)。
    我们经常在 tableView:cellForRowAtIndexPath: 中为每一个 cell 绑定数据,实际上在调用 cellForRowAtIndexPath: 的时候 cell 还没有被显示出来,为了提高效率应该把数据绑定的操作放在 cell 显示出来后再执行,可以在 tableView:willDisplayCell:forRowAtIndexPath: 方法中绑定数据。
  • 注意 willDisplayCell 中 cell 在 tableview 展示之前就会调用,此时 cell 实例已经生成,所以不能更改 cell 的结构,只能是改动 cell 上的 UI 的一些属性,如 label 的内容、控件的隐藏等。

所以我们千万不要去放弃UITableView的一个复用,倘若放弃了就会浪费跟多内容。

定义cell的种类尽量少,可以多用hidden

分析 Cell 结构,尽可能的将相同内容的抽取到一种样式 Cell 中,这样可以尽量少的创建cell的,尽管存在复用,但是如果cell种类过多还是会造成较大的内存开销。

可以这么理解,倘若一个屏幕的cell有M个,但是复用池会创建M+C个,但是如果有多个cell那么就会创建N*(M + C)个cell,那么这样一对比就会发现浪费内存。

既然只定义一种 Cell,那么需要把所有不同类型的 view 都定义好,放在 Cell 里面,通过 hidden 属性控制,来显示不同类型的内容。毕竟,在用户快速滑动中,只是单纯的显示/隐藏 subview 比实时创建要快得多。
尽量少用 [cell addSubview:] 动态添加 View,可以初始化时就添加,然后通过 hidden 属性来控制。

缓存cell高度

基础设置

这里是最经典的一个优化方式:

self.tableView.rowHeight = 88; //倘如所有cell都一个高度,可以直接采用这个方法,来解决那个函数多次调用的问题

另一种则是我们更加常用的一个UITableView的方法

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {NSLog(@"对应的一个高度调用次序");return 100;
}
预先设置高度

后面有iOS推出了一个:estimatedRowHeight这个可以预估高度的属性

UITableView 是个 UIScrollView,就像平时使用 UIScrollView 一样,加载时指定 contentSize 后它才能根据自己的 bounds、contentInset、contentOffset 等属性共同决定是否可以滑动以及滚动条的长度。而 UITableView 在一开始并不知道自己会被填充多少内容,于是询问 data source 个数和创建 cell,同时询问 delegate 这些 cell 应该显示的高度,这就造成它在加载的时候浪费了多余的计算在屏幕外边的 cell 上。

这个属性可以让我们更加迅速的加载,也更适合我们平时的一个自适应行高的内容,但是他也会带来一些缺点:

  • 可能会导致滚动条出现一个跳动的问题影响用户体验

因此,tableView:estimatedHeightForRowAtIndexPath: -> tableView:heightForRowAtIndexPath: 获取每个 Cell 即将显示的高度,从而确定表格视图的布局,实际是要获取滚动视图的 contentSize,然后调用 tableView:cellForRowAtIndexPath:,获取每个 Cell,进行赋值。如果有很多个 Cell 要显示,那么方法会执行很多次。
所以我们可以采用一个缓存高度数组的方式来解决这个问题。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {NSLog(@"对应的一个高度调用次序");return heightAry[indexPath.row];
}
设置一个预先缓存

这里笔者看到一个开源库,这里他采用了一个预先计算高度的内容:预缓存机制将在 UITableView 没有滑动的空闲时刻执行,计算和缓存那些还没有显示到屏幕中的 cell,整个缓存过程完全没有感知,这使得完整列表的高度计算既没有发生在加载时,又没有发生在滑动时,同时保证了加载速度和滑动流畅性。

UITableView+FDTemplateLayoutCell 开源库之后笔者有时间去简单阅读源码,之后会对这一块内容做一个补充

异步绘制

遇到比较复杂的界面时(复杂点的图文混排),上面缓存行高的方式可能就不能满足要求。绘制的各个信息都是根据之前算好的布局进行绘制的,那么就需要异步绘制。这里笔者还不是很清楚这部分内容,之后会补充,主要还是对于GCD的内容不够熟练

image-20250413213215142

- (void)draw {// 异步绘制dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{});
}/** *  @brief  重写 drawRect: 方法 */
- (void)drawRect:(CGRect)rect {// 不需要用 GCD 异步线程,因为 drawRect: 本来就是异步绘制的
}

滑动按照需加载

现在iOS其实引入了两个与加载函数:

- (void)tableView:(UITableView *)tableView prefetchRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
- (void)tableView:(UITableView *)tableView cancelPrefetchingForRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths; //继承UITableViewDataSourcePrefetching协议

这两个函数支持一个与加载数据的内容,这里笔者可以分享一篇博客:

iOS 优雅的处理网络数据,你真的会吗?不如看看这篇.

笔者认为他讲的比较透彻就不多赘述了,感兴趣的可以去看这篇博客

尽量显示大小刚好合适的图片资源

这里我们加载图片尽量采用大小合适的图片,避免大量的图片缩放、颜色渐变等。

图片异步加载

这个内容比较重要,我们都会采用SDWebImage来异步加载图片资源。

  • 使用异步子线程处理,然后再返回主线程操作;
  • 图片缓存处理,避免多次处理操作;
  • 图片圆角处理时,设置 layer 的 shouldRasterize 属性为 YES,可以将负载转移给 CPU;

这部分代码我会在学习SDWebImage后继续补充

直接设置frame

对于一些不用自使用高度的,我们可以直接给cell设置一个frame来减小CPU压力,使用Masonry布局的时候会增加CPU运算负担

采用轻量级对象

在某些情况下,我们可以采用CALyaer来代替我们的一个UIView:

同时实际上每一个UIView都有一个CALayer的属性,其实我们可以把UIView理解为CALayer的高级封装,他们的本质区别在于是否能响应事件,这也是CALayer性能优于UIView的主要原因。

可以说CALayer只负责一个绘制,而且更接近底层,我们采用CALayer可以降低CPU消耗

GPU层级

减少透明处理

减少透明的视图,不透明的就设置opaque = YES

控制尺寸

GPU能处理的最大纹理尺寸是4096x4096,超过这个尺寸就会占用CPU资源进行处理,所以纹理尽量不要超过这个尺寸。

纹理(Texture)就是贴在模型或 UI 元素上的图片,比如游戏里的人物皮肤、按钮背景图,都是纹理。

减少图层混合操作

当多个视图叠加,放在上面的视图是半透明的,那么这个时候GPU就要进行混合,把透明的颜色加上放在下面的视图的颜色混合之后得出一个颜色再显示在屏幕上,这一步是消耗GPU资源

  • UIViewbackgroundColor不要设置为clearColor,最好设置和superViewbackgroundColor颜色一样
  • 图片避免使用带alpha通道的图片

避免离屏渲染

笔者不是很了解什么是离屏渲染。所以笔者查询资料了解到:

渲染类型说明
屏幕内渲染(On-Screen Rendering)图层直接渲染在屏幕帧缓存中
离屏渲染(Off-Screen Rendering)图层需要先渲染到一个缓冲区(off-screen buffer),渲染完成后再复制到屏幕上
为什么要避免离屏渲染?
问题描述
性能开销大多了一次 offscreen buffer 的创建、上下文切换,浪费 GPU 资源
内存增加离屏缓存占用额外内存,尤其在大量视图中(如 tableview cell)更严重
卡顿掉帧渲染帧率下降,导致页面滑动不流畅(尤其是 60fps 要求下)

下面操作会导致离屏渲染

  • 光栅化,layer.shouldRasterize = YES

  • 遮罩,layer.mask

  • 圆角,同时设置 layer.masksToBounds = YESlayer.cornerRadius > 0

  • 阴影,layer.shadow

  • layer.allowsGroupOpacity = YESlayer.opacity != 1

这里笔者还不是很清楚原理,仅仅了解到这些操作会造成一个大量的性能开销,之后笔者会单独写一篇有关于离屏渲染的博客

优化圆角

采用贝塞尔曲线来绘制圆形:

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(10, 10)];
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
layer.frame = self.bounds;
layer.path = path.CGPath;
CAShapeLayer *borderLayer = [CAShapeLayer layer];
borderLayer.path = path.CGPath;
borderLayer.lineWidth = 1.0;
borderLayer.strokeColor = [UIColor lightGrayColor].CGColor;
borderLayer.fillColor = [UIColor clearColor].CGColor;
阴影优化
imageView.layer.shadowColor = [UIColor grayColor].CGColor;
imageView.layer.shadowOpacity = 1.0;
imageView.layer.shadowRadius = 2.0;
UIBezierPath *path = [UIBezierPath bezierPathWithRect:imageView.frame];
imageView.layer.shadowPath = path.CGPath;

总结

  • 采用UITablecell的一个复用机制,减少对于cell种类的一个创建,多采用直接访问的方法。
  • 高度缓存数组的使用。
  • 预缓存高度。
  • 图片异步加载,采用SDWebImage库来实现一个异步加载。
  • 减少离屏渲染,这部分比较重要之后在做一篇博客的总结
  • 按照需要加载数据,根据UITableVIew的新推出的一些协议方法

参考博客:

【iOS】UITableView性能优化

[iOS开发]UITableView的性能优化

UITableViewCell复用机制及踩坑总结

相关文章:

UITableVIew性能优化概述

UITableVIew性能优化概述 文章目录 UITableVIew性能优化概述前言如何优化优化的本质卡顿的原因 CPU层级cell复用UITableVIew尽量采用复用 定义cell的种类尽量少&#xff0c;可以多用hidden缓存cell高度基础设置预先设置高度设置一个预先缓存 异步绘制滑动按照需加载尽量显示大小…...

【Linux网络与网络编程】09.传输层协议TCP

前言 TCP 即 传输控制协议 (Transmission Control Protocol)&#xff0c;该协议要对数据的传输进行一个详细的控制&#xff08;数据传输时什么时候传输&#xff0c;一次发多少&#xff0c;怎么发&#xff0c;出错了怎么办……&#xff09; 本篇博客将从下面这张TCP协议格式图…...

08.unity 游戏开发-unity编辑器资源的导入导出分享

08.unity 游戏开发-unity编辑器资源的导入导出分享 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是Python基础语法。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性&#xff0c;希望对您有用~ unity简介…...

Docker Swarm 集群

Docker Swarm 集群 本文档介绍了 Docker Swarm 集群的基本概念、工作原理以及相关命令使用示例&#xff0c;包括如何在服务调度中使用自定义标签。本文档适用于需要管理和扩展 Docker 容器化应用程序的生产环境场景。 1. 什么是 Docker Swarm Docker Swarm 是用于管理 Docker…...

数据中台、数据湖和数据仓库 区别

1. 核心定义与定位 数据仓库&#xff08;Data Warehouse&#xff09; 定义&#xff1a;面向主题的、集成的、历史性且稳定的结构化数据集合&#xff0c;主要用于支持管理决策和深度分析。定位&#xff1a;服务于管理层和数据分析师&#xff0c;通过历史数据生成报表和商业智能…...

【CodeMirror】系列(二)官网示例(五)可撤销操作、拆分视图、斑马条纹

一、可撤销操作 默认情况下&#xff0c;history 历史记录扩展仅跟踪文档和选择的更改&#xff0c;撤销操作只会回滚这些更改&#xff0c;而不会影响编辑器状态的其他部分。 不过你也可以将其他的操作定义成可撤销的。如果把这些操作看作状态效果&#xff0c;就可以把相关功能整…...

SpringBoot 动态路由菜单 权限系统开发 菜单权限 数据库设计 不同角色对应不同权限

介绍 系统中的路由配置可以根据用户的身份、角色或其他权限信息动态生成&#xff0c;而不是固定在系统中。不同的用户根据其权限会看到不同的路由&#xff0c;访问不同的页面。对应各部门不同的权限。 效果 [{"id": 1,"menuName": "用户管理"…...

scikit-learn 开源框架在机器学习中的应用

文章目录 scikit-learn 开源框架介绍1. 框架概述1.1 基本介绍1.2 版本信息 2. 核心功能模块2.1 监督学习2.2 无监督学习2.3 数据处理 3. 关键设计理念3.1 统一API设计3.2 流水线(Pipeline) 4. 重要辅助功能4.1 模型选择4.2 评估指标 5. 性能优化技巧5.1 并行计算5.2 内存优化 6…...

GPT-4、Grok 3与Gemini 2.0 Pro:三大AI模型的语气、风格与能力深度对比

更新后的完整CSDN博客文章 以下是基于您的要求&#xff0c;包含修正后的幻觉率部分并保留原始信息的完整CSDN博客风格文章。幻觉率已调整为更符合逻辑的描述&#xff0c;其他部分保持不变。 GPT-4、Grok 3与Gemini 2.0 Pro&#xff1a;三大AI模型的语气、风格与能力深度对比 …...

Cyber Weekly #51

赛博新闻 1、英伟达开源新模型&#xff0c;性能直逼DeepSeek-R1 本周&#xff0c;英伟达开源了基于Meta早期Llama-3.1-405B-Instruct模型开发的Llama-3.1-Nemotron-Ultra-253B-v1大语言模型&#xff0c;该模型拥有2530亿参数&#xff0c;在多项基准测试中展现出与6710亿参数的…...

QT聊天项目开发DAY02

1.添加输入密码的保密性 LoginWidget::LoginWidget(QDialog*parent): QDialog(parent) {ui.setupUi(this);ui.PassWord_Edit->setEchoMode(QLineEdit::Password);BindSlots(); }2.添加密码的验证提示 3.修复内存泄漏&#xff0c;并嵌套UI子窗口到主窗口里面 之前并没有设置…...

Spring AI高级RAG功能查询重写和查询翻译

1、创建查询重写转换器 // 创建查询重写转换器queryTransformer RewriteQueryTransformer.builder().chatClientBuilder(openAiChatClient.mutate()).build(); 查询重写是RAG系统中的一个重要优化技术&#xff0c;它能够将用户的原始查询转换成更加结构化和明确的形式。这种转…...

速盾:高防CDN的原理和高防IP一样吗?

随着互联网的发展&#xff0c;网络安全威胁日益严重&#xff0c;尤其是DDoS攻击、CC攻击等恶意行为&#xff0c;给企业带来了巨大的风险。为了应对这些挑战&#xff0c;许多企业开始采用高防CDN&#xff08;内容分发网络&#xff09;和高防IP作为防御措施。尽管两者都能提供一定…...

SQLite-Web:一个轻量级的SQLite数据库管理工具

SQLite-Web 是一个基于 Web 浏览器的轻量级 SQLite 数据库管理工具。它基于 Python 开发&#xff0c;免费开源&#xff0c;无需复杂的安装或配置&#xff0c;适合快速搭建本地或内网的 SQLite 管理和开发环境。 SQLite-Web 支持常见的 SQLite 数据库管理和开发任务&#xff0c;…...

数智读书笔记系列028 《奇点更近》

一、引言 在科技飞速发展的今天&#xff0c;我们对未来的好奇与日俱增。科技将如何改变我们的生活、社会乃至人类本身&#xff1f;雷・库兹韦尔的《奇点更近》为我们提供了深刻的见解和大胆的预测&#xff0c;让我们得以一窥未来几十年的科技蓝图。这本书不仅是对未来科技趋势…...

深入理解linux操作系统---第4讲 用户、组和密码管理

4.1 UNIX系统的用户和组 4.1.1 用户与UID UID定义&#xff1a;用户身份唯一标识符&#xff0c;16位或32位整数&#xff0c;范围0-65535。系统用户UID为0&#xff08;root&#xff09;、1-999&#xff08;系统服务&#xff09;&#xff0c;普通用户从1000开始分配特殊UID&…...

系统设计模块之安全架构设计(常见攻击防御(SQL注入、XSS、CSRF、DDoS))

一、SQL注入攻击防御 SQL注入是通过恶意输入篡改数据库查询逻辑的攻击方式&#xff0c;可能导致数据泄露或数据库破坏。防御核心在于隔离用户输入与SQL代码&#xff0c;具体措施包括&#xff1a; 参数化查询&#xff08;预编译语句&#xff09; 原理&#xff1a;将SQL语句与用…...

redission锁释放失败处理

redission锁释放失败处理 https://www.jianshu.com/p/055ae798547a 就是可以删除 锁的key 这样锁就释放了&#xff0c;但是 还是要结合业务&#xff0c;这种是 非正规的处理方式&#xff0c;还是要在代码层面进行处理。...

Visual Studio Code 在.S汇编文件中添加调试断点及功能简介

目录 一、VS Code汇编文件添加断点二、VS Code断点调试功能简介1. 设置断点(1) 单行断点(2) 条件断点(3) 日志断点 2. 查看断点列表3. 调试时的断点控制4. 禁用/启用断点5. 删除断点6. 条件断点的使用7. 多线程调试8. 远程调试9. 调试配置文件 一、VS Code汇编文件添加断点 最…...

计算视觉与数学结构及AI拓展

在快速发展的计算视觉领域&#xff0c;算法、图像处理、神经网络和数学结构的交叉融合&#xff0c;在提升我们对视觉感知和分析的理解与能力方面发挥着关键作用。本文探讨了支撑计算视觉的基本概念和框架&#xff0c;强调了数学结构在开发鲁棒的算法和模型中的重要性。 AI拓展…...

Vue2 老项目升级 Vue3 深度解析教程

Vue2 老项目升级 Vue3 深度解析教程 摘要 Vue3 带来了诸多改进和新特性&#xff0c;如性能提升、组合式 API、更好的 TypeScript 支持等&#xff0c;将 Vue2 老项目升级到 Vue3 可以让项目获得这些优势。本文将深入解析升级过程&#xff0c;涵盖升级前的准备工作、具体升级步骤…...

器件封装-2025.4.13

1.器件网格设置要与原理图一致&#xff0c;同时器件符号要与数据手册一致 2.或者通过向导进行编辑&#xff0c;同时电机高级符号向导进行修改符号名称 2.封装一般尺寸大小要比数据手册大2倍到1.5倍 焊盘是在顶层绘制&#xff0c;每个焊盘距离要用智能尺子测量是否跟数据手册一…...

Python 基础语法汇总

Python 语法 │ ├── 基本结构 │ ├── 语句&#xff08;Statements&#xff09; │ │ ├── 表达式语句&#xff08;如赋值、算术运算&#xff09; │ │ ├── 控制流语句&#xff08;if, for, while&#xff09; │ │ ├── 定义语句&#xff08;def…...

Java函数式编程魔法:Stream API的10种妙用

在Java 8中引入的Stream API为函数式编程提供了一种全新的方式。它允许我们以声明式的方式处理数据集合&#xff0c;使代码更加简洁、易读且易于维护。本文将介绍Stream API的10种妙用&#xff0c;帮助你更好地理解和应用这一强大的工具。 1. 过滤操作&#xff1a;筛选符合条件…...

【力扣hot100题】(094)编辑距离

记得最初做这题完全没思路&#xff0c;这次凭印象随便写了一版居然对了。 感觉这题真的有点为出题而出题的意思&#xff0c;谁拿到这题会往动态规划方向想啊jpg 也算是总结出规律了&#xff0c;凡是遇到这种比较俩字符串的十有八九是动态规划&#xff0c;而且是二维动态规划&…...

穿透三层内网VPC2

网络拓扑 目标出网web地址&#xff1a;192.168.139.4 信息收集端口扫描&#xff1a; 打开8080端口是一个tomcat的服务 版本是Apache Tomcat/7.0.92 很熟悉了&#xff0c;可能存在弱口令 tomcat/tomcat 成功登录 用哥斯拉生成马子&#xff0c;上传war包&#xff0c;进入后台 C…...

AI数字消费第一股,重构商业版图的新物种

伍易德带领团队发布“天天送AI数字商业引擎”&#xff0c;重新定义流量与消费的关系 【2025年4月&#xff0c;深圳】在人工智能浪潮席卷全球之际&#xff0c;深圳天天送网络科技有限公司于深圳大中华喜来登酒店重磅召开“AI数字消费第一股”发布盛典。公司创始人伍易德首次系统…...

Unity 基于navMesh的怪物追踪惯性系统

今天做项目适合 策划想要实现一个在现有的怪物追踪系统上实现怪物拥有惯性功能 以下是解决方案分享&#xff1a; 怪物基类代码&#xff1a; ​ using UnityEngine; using UnityEngine.AI;[RequireComponent(typeof(NavMeshAgent))] [RequireComponent(typeof(AudioSource))] …...

【OpenCV】【XTerminal】talk程序运用和linux进程之间通信程序编写,opencv图像库编程联系

目录 一、talk程序的运用&Linux进程间通信程序的编写 1.1使用talk程序和其他用户交流 1.2用c语言写一个linux进程之间通信&#xff08;聊天&#xff09;的简单程序 1.服务器端程序socket_server.c编写 2.客户端程序socket_client.c编写 3.程序编译与使用 二、编写一个…...

中断的硬件框架

今天呢&#xff0c;我们来讲讲中断的硬件框架&#xff0c;这里会去举3个开发板&#xff0c;去了解中断的硬件框架&#xff1a; 中断路径上的3个部件&#xff1a; 中断源 中断源多种多样&#xff0c;比如GPIO、定时器、UART、DMA等等。 它们都有自己的寄存器&#xff0c;可以…...

大数据面试问答-Hadoop/Hive/HDFS/Yarn

1. Hadoop 1.1 MapReduce 1.1.1 Hive语句转MapReduce过程 可分为 SQL解析阶段、语义分析阶段、逻辑计划生成阶段、逻辑优化阶段、物理计划生成阶段。 SQL解析阶段 词法分析(Lexical Analysis)&#xff1a;使用Antlr3将SQL字符串拆分为有意义的token序列 语法分析(Syntax An…...

【小沐学GIS】基于C++绘制三维数字地球Earth(QT5、OpenGL、GIS、卫星)第五期

&#x1f37a;三维数字地球系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第二期3【小沐学GIS】…...

初始图形学(3)

昨天休息了一天&#xff0c;今天继续图形学的学习 向场景发射光线 现在我们我们准备做一个光线追踪器。其核心在于&#xff0c;光线追踪程序通过每个像素发送光线。这意味着对于图像中的每个像素点&#xff0c;程序都会计算一天从观察者出发&#xff0c;穿过该像素的光线。并…...

如果想在 bean 创建出来之前和销毁之前做一些自定义操作可以怎么来实现呢?

使用生命周期扩展接口&#xff08;最灵活&#xff09;​ 创建前拦截可以通过实现 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法&#xff0c;在Bean实例化前执行逻辑 在销毁前拦截可以通过实现 DestructionAwareBean 接口的 postProcessBe…...

【甲子光年】DeepSeek开启AI算法变革元年

目录 引言人工智能的发展拐点算力拐点&#xff1a;DeepSeek的突破数据拐点&#xff1a;低参数量模型的兴起算法创新循环算法变革推动AI普惠应用全球AI科技竞争进入G2时代结论 引言 2025年&#xff0c;人工智能的发展已经走到了一个战略拐点。随着技术能力的不断提升&#xff0…...

Go语言--语法基础4--基本数据类型--整数类型

整型是所有编程语言里最基础的数据类型。 Go 语言支持如下所示的这些整型类型。 需要注意的是&#xff0c; int 和 int32 在 Go 语言里被认为是两种不同的类型&#xff0c;编译器也不会帮你自动做类型转换&#xff0c; 比如以下的例子会有编译错误&#xff1a; var value2 in…...

MCP基础学习计划详细总结

MCP基础学习计划详细总结 1.MCP概述与基础 • MCP&#xff08;Model Context Protocol&#xff09;&#xff1a;由Anthropic公司于2024年11月推出&#xff0c;旨在实现大型语言模型&#xff08;LLM&#xff09;与外部数据源和工具的无缝集成。 • 核心功能&#xff1a; • 资…...

大模型到底是怎么产生的?一文揭秘大模型诞生全过程

前言 大模型到底是怎么产生的呢? 本文将从最基础的概念开始,逐步深入,用通俗易懂的语言为大家揭开大模型的神秘面纱。 大家好,我是大 F,深耕AI算法十余年,互联网大厂核心技术岗。 知行合一,不写水文,喜欢可关注,分享AI算法干货、技术心得。 【专栏介绍】: 欢迎关注《…...

Node.js介绍

一、Node.js 核心定义 本质&#xff1a;基于 Chrome V8 引擎构建的 JavaScript 运行时环境&#xff0c;用于在服务器端执行 JavaScript 代码。 定位&#xff1a;非阻塞、事件驱动的 I/O 模型&#xff0c;专为高并发、实时应用设计。 诞生&#xff1a;2009 年由 Ryan Dahl 发布…...

DRABP_NSGA2最新算法神圣宗教算法优化BP做代理模型,NSGA2反求最优因变量和对应的最佳自变量组合,Matlab代码

一、神圣宗教算法&#xff08;DRA&#xff09;优化BP代理模型 1. DRA的核心原理 DRA是一种模拟宗教社会层级互动的元启发式算法&#xff0c;通过“追随者学习”、“传教士传播”和“领导者引导”三种行为模式优化搜索过程。在BP神经网络优化中&#xff0c;DRA通过以下步骤调整…...

Android Studio 在 Windows 上的完整安装与使用指南

Android Studio 在 Windows 上的完整安装与使用指南—目录 一、Android Studio 简介二、下载与安装1. 下载 Android Studio2. 安装前的依赖准备3. 安装步骤 三、基础使用指南1. 首次启动配置2. 创建第一个项目3. 运行应用4. 核心功能 四、进阶功能配置1. 配置 SDK 和工具2. 自定…...

Matlab学习笔记五十:循环语句和条件语句的用法

1.说明 循环语句&#xff1a;for…end&#xff0c;while…end 条件语句&#xff1a;if…end&#xff0c;switch…case…end 其中if语句语法还可以是&#xff1a;for…else…end&#xff0c;for…elseif…else…end 2.简单for程序实例 for x1:5 %循环遍历1~5 yx5 end [1…...

大漠流光:科技牧歌的未来-内蒙古鄂尔多斯

故事背景 故事发生在中国内蒙古鄂尔多斯&#xff0c;这里是蒙古族文化的摇篮&#xff0c;也是科技与自然交织的未来舞台。在这片广袤的土地上&#xff0c;蒙古族少女、老牧人和工程师们共同谱写着一曲科技与传统共生的赞歌。未来的鄂尔多斯&#xff0c;不再是单一的沙漠或草原…...

MySQL与Oracle深度对比

MySQL与Oracle深度对比&#xff1a;数据类型与SQL差异 一、数据类型差异 1. 数值类型对比 数据类型MySQLOracle整数TINYINT, SMALLINT, MEDIUMINT, INT, BIGINTNUMBER(精度) 或直接INT(内部仍为NUMBER)小数DECIMAL(p,s), FLOAT, DOUBLENUMBER(p,s), FLOAT, BINARY_FLOAT, BI…...

GESP2023年12月认证C++七级( 第一部分选择题(6-10))

选择题第八题&#xff1a; #include <iostream> #include <cstring> #include <algorithm> using namespace std;const int MAXN 1005; // 假设字符串长度不超过1000 char s1[MAXN], s2[MAXN]; int dp[MAXN]; // 一维DP数组int main() {while (cin >>…...

腾势品牌欧洲市场冲锋,科技豪华席卷米兰

在时尚与艺术的交汇点&#xff0c;米兰设计周的舞台上&#xff0c;一场汽车界的超级风暴正在酝酿&#xff0c;腾势品牌如一头勇猛无畏的雄狮&#xff0c;以雷霆万钧之势正式向欧洲市场发起了冲锋。其最新力作——腾势Z9GT的登场&#xff0c;仿佛是一道闪电划破夜空&#xff0c;…...

双指针、滑动窗口

一、双指针 双指针是指在算法中使用两个指针&#xff08;通常是索引或迭代器&#xff09;来解决问题&#xff0c;通过移动这两个指针来扫描数据结构&#xff08;如数组或链表&#xff09;&#xff0c;从而达到高效的目的。双指针的核心思想是利用两个指针的相对位置或移动方式…...

《数据密集型应用系统设计》读书笔记:第二章

我们继续拆解 第2章&#xff1a;数据模型与查询语言。这章讲的是如何组织数据、如何访问数据&#xff0c;也是你选择数据库种类的根本依据。 第2章&#xff1a;数据模型与查询语言 一、为何数据模型重要&#xff1f; Martin 开篇就强调&#xff0c;数据模型影响&#xff1a; …...

ubuntu24.04LTS安装向日葵解决方案

去向日葵官方下载ubuntu使用的deb包 向日葵 输入如下命令安装&#xff0c;将具体版本修改成自己下载的版本 andrew in ~/下载 λ sudo dpkg -i SunloginClient_15.2.0.63064_amd64.deb 正在选中未选择的软件包 sunloginclient。 (正在读取数据库 ... 系统当前共安装有 290947…...

Python基础语法1

目录 1、认识Python 1.1、计算机 1.2、编程 1.3、编程语言的类别 1.4、Python背景 1.5、Python的应用场景 1.6、Python的优缺点 1.7、Python前景 1.8、Python 环境 2、常量和表达式 3、变量和类型 3.1、定义变量 3.2、使用变量 3.3、变量的类型 3.3.1、整形 3.3…...