Unity优化——加速物理引擎1
大家好,这里是七七,今天开始更新物理引擎相关的优化部分了,本文介绍的是物理引擎内部工作情况。
Unity技术有两种不同的物理引擎:用于3D物理的Nvidia的PhysX和用于2D物理的开源项目Box2D。然而,Unity对它们的实现是高度抽象的,从通过主Unity引擎配置的更高级别Unity API的角度来看,两个物理引擎解决方案以功能相同的方式运行。
无论是哪种情况,对Unity的物理引擎了解的越多,就越能理解可能的性能增强。本文将介绍一些关于Unity如何实现这些系统的理论。
一、物理和时间
物理引擎通常是在时间按固定值前进的假设下运行的,Unity的两个物理引擎也都以这种方式运行。每个迭代称为时间步长。物理引擎将只使用特定时间值来处理每个时间步长,这与渲染上一帧所花费的时间无关。该时间步长在Unity中称为固定更新的时间步长,默认值为20ms。
注意:由于体系结构(浮点值的表示方式)的不同以及客户端之间的延迟,如果物理引擎使用可变的时间步长,就很难在两台不同的计算机之间产生一致的碰撞和力的结果。这样物理引擎往往会在多人的客户端之间或录制的重播期间生成不一致的结果。
固定的更新在物理引擎执行自己的更新之前处理,而这两者之间的联系是不可分割的。这个过程开始于确定是否已经过了足够的时间来开始下一个固定的更新。一旦确定了这一点,则结果将有所不同,这取决于自上次固定更新以来经过的时间。
如果经过了足够的时间,则固定更新的处理将调用在场景中所有激活的MonoBehaviour中定义的FixedUpdate()回调,接着处理与固定更新相关的任何协程(特别是那些生成WaitForFixedUpdate的协程)。注意,对于在这两个过程中调用的方法,没有执行顺序的保证,所以不应该在这个假设下编写代码。一旦这些任务完成,物理引擎就可以开始处理当前的时间步长,并调回任何必要的触发器和碰撞器。
相反,如果上次固定更新以来经过的时间太短(小于20ms),则跳过当前的固定更新,并且之前列出的所有任务不会再当前迭代期间处理。此时,输入、游戏逻辑和渲染将正常进行。完成此活动后,Unity将检查是否需要处理下一个固定更新。
在高帧率下,渲染更新可能会在物理引擎获得自身更新机会之前完成多次更新。这个过程在运行时不断重复,使固定的更新和物理引擎比渲染具有更高的优先级,同时也强制物理模拟具有固定的帧率。
提示:为了确保对象在固定更新之间平稳移动,物理引擎根据下一次固定更新之前的剩余时间,在处理当前状态之后,在上一个状态和应处于的状态之间对每个对象的可见位置进行插值。这种插值可以确保对象的移动非常平稳,尽管它们的物理位置、速度等更新的频率低于渲染帧率。
FixedUpdate()回调适用于任何期望独立于帧率的游戏行为。AI通常在固定的更新中计算,因为如果假设一个固定更新的频率,会更容易开发。
1.1 最大允许的时间步长
需要注意的是,如果自上次固定更新(例如游戏暂时卡顿)以来已经过了很长时间,那么固定更新将继续在相同的固定更新循环中计算,直到物理引擎赶上当前时间。如果上一帧画了100ms用于渲染(例如,一个突然的CPU峰值导致主线程阻塞了很长时间),那么物理引擎将需要更新5次。由于默认固定更新的时间步长为20ms,在再次调用Update()之前还需要调用5次FixedUpdate()。当然,如果在这5次固定更新时有很多物理活动需要处理,例如总共花费了超过20ms处理它们,那么物理引擎将继续调用第6次更新。
因此,在物理活动较多时,物理引擎处理固定更新的时间可能比模拟的时间要长。例如,如果用30ms来处理一个固定的更新,模拟20ms的游戏,它就已经落后了,需要它处理更多的时间步长来尝试和跟上,但这可能会导致它落后得更远,需要它处理更多的时间步长,等等。在这些情况下,物理引擎永远无法摆脱固定的更新循环,并允许另一帧进行渲染,这个问题通常称为死亡螺旋。但是,为了防止物理引擎在这些时刻锁定游戏,存在允许物理引擎处理每个固定更新循环的最长时间,则它将停止并放弃进一步的处理,直到下一次渲染更新完成。这种设计允许渲染管线至少将当前状态进行渲染,并允许用户输入以及游戏逻辑在物理引擎出现异常的罕见时刻做出一些决策。
该设置可以通过Edit|Project Settings|Time|Maximum Alowed Timestep来访问。
1.2 物理更新和运行时的变化
当物理引擎以给定的时间步长处理时,它必须移动激活的刚体对象,检测新的碰撞,并调用相应对象的碰撞回调。Unity文档明确指出,应该在FixedUpdate()和其他物理回调中处理对刚体对象的更改,原因正是如此。这些方法与物理引擎的更新频率紧密耦合,而不是游戏循环的其他部分,如Update()。
这意味着,诸如FixedUpdate()和OnTriggerEnter()的回调函数能够安全更改Rigidbody的位置,而诸如Update()和对WaitForSeconds或WaitForEndOfFrame的协程却不能。忽略这一建议可能会导致意想不到的物理行为,因为在物理引擎有机会捕获和处理所有这些对象之前,可能会对同一个对象进行多次更改。
对Update()回调中的对象应用力或脉冲而不考虑这些调用的频率是非常危险的。例如,在玩家按住一个键时,给Update功能应用10牛顿的力,会导致两个不同设备之间的合成速度完全不同于在固定更新中执行相同的操作。事实上,不能依赖Update()调用的次数是一致的。但是,在FixedUpdat()回调中这样做会更加一致。因此,必须确保在适当的回调中处理所有与物理引擎相关的行为,否则就可能引入一些令人困惑,很难重现的游戏漏洞。
从逻辑上讲,在任何给定的固定更新迭代中花费的时间越多,在下一次游戏逻辑和渲染过程中花费的时间就越少。由于物理引擎几乎没有任何工作要做,而且FixedUpdate()回调有很多时间来完成它们的工作,因此大多数情况下这会导致一些小的、不明显的后台处理任务。然而,在某些游戏中,物理引擎可能在每次固定更新期间执行大量计算。这种物理处理时间上的瓶颈会影响帧率,导致它在当物理引擎负担越来越大的工作负载时,帧率急剧下降。基本上,渲染管线将尝试正常进行,但每当需要进行固定更新时(物理引擎处理时间很长),渲染管线在帧结束之前几乎没有时间生成画面,会导致突然停顿。物理引擎达到允许的最大时间步长,会导致过早停止的视觉效果。所有这些加在一起会产生非常糟糕的用户体验。
因此,为了保持平滑、一致的帧率,需要通过最小化物理引擎处理任何给定时间步长所需的时间,来为渲染释放尽可能多的时间,这适用于最佳情况(没有移动)和最坏情况(所有对象同时与其它对象发生碰撞)。可以在物理引擎中调整一些与事件相关的特征和值,以避免这些性能缺陷。
二、静态碰撞器和动态碰撞器
在Unity中,术语"静态"和"动态"又一个相当极端的命名空间冲突。静态通常意味着所讨论的对象或处理不移动、保持不变或只存在于一个位置,而动态则意味着相反,对象或处理倾向于改变或移动。然而要记住,术语"静态"和"动态"的用法在每种情况下都不同。
动态碰撞器只意味着GameObject包含Collider组件和Rigidbody组件。通过将Rigidbody添加到Collider所附加的相同对象上,物理引擎会将该碰撞器视为带有包围物理对象的立体对象,它会对外部的力和与其他Rigidbody的碰撞体作出反应。如果一个动态碰撞器与另一个动态碰撞器发生碰撞,它们都会基于牛顿运动定律做出反应。
也可以使用没有附加Rigidbody组件的碰撞器,这种称为静态碰撞器。这种碰撞器有效地起到了无形屏障的作用,动态碰撞器可以撞到这些屏障,但是静态碰撞器不会做出响应。从另一个角度来看,就是把没有Rigidbody组件的物体想象成具有无穷大的质量。因此,静态碰撞器非常适合用作全局屏障和其他不能移动的障碍物。
物理引擎自动将动态碰撞器和静态碰撞器分为两种不同的数据结构,每种结构都经过优化以处理现有碰撞器的类型。这有助于简化未来的任务,例如,解析两个静态碰撞器之间的碰撞和脉冲。
三、碰撞检测
Unity中的碰撞检测有3种设置,可以在Rigidbody组件的Collision Detection属性中设置Discrete(离散)、Continuous(连续)和ContinuousDynamic(连续动态)。
Discrete设置可以实现离散碰撞检测,有效地根据物体的速度和经过的时间,在某个时间步长将对象传送一小段距离。一旦所有对象都被移动了,物理引擎就会对所有重叠执行便捷进行立体检查,将它们视为碰撞,并根据它们的物理属性和重叠方式来处理它们。如果小对象移动得太快,此方法可能会有丢失碰撞的风险。
其余的两个设置都将启用连续碰撞检测,其工作方式是从当前时间步长的起始和结束位置,并见哈这个时间段中是否有任何碰撞。这降低了错过碰撞的风险,生成了更景区的模拟,但代价是CPU的开销显著高于离散碰撞检测。
Continuous设置尽在给定碰撞器和静态碰撞器之间用连续碰撞检测。同一碰撞器与动态碰撞器之间的碰撞仍将使用离散碰撞检测。
同时,ContinuousDynamic设置使碰撞器能够与所有静态和动态碰撞器进行连续碰撞检测,其在资源消耗方面最大。
四、碰撞器类型
Unity中有4种不同类型的3D碰撞器,其性能成本从最小到最大依次为球体(Sphere)、胶囊体(Capsule)、立方体(Box)、网格(Mesh)。
前三个碰撞器类型通常称为基础类型。包含非常特殊的形状,尽管它们通常可以在不同方向缩放以满足某些要求。网格碰撞器可以根据指定的网格自定义为特定形状。还有3种类型的二维碰撞器:圆(Circle)、方框(Box)和多边形(Polygon),在功能上分别与球形、立方体和网格碰撞器相似。以下所有信息基本上都可以转换为等效的二维形状。
提示:也可以在Unity中生成3D圆柱体,但这只是它的图形表现。自动生成的圆柱体使用胶囊体碰撞器表示其物理保卫面积,这可能不会产生预期的物理行为。
另外,有两种不同的网格碰撞器:Convex(凸的)和Concave(凹的)。两者的不同之处在于,凹形形状至少具有一个大于180度的内角,如图所示:
提示:区分凹形和凸形的一个简单方法是凹形至少有一个凹陷。
两种网格碰撞器类型都使用相同的组件(MeshCollider组件),这种网格碰撞器类型是通过切换Convex复选框选项生成的。启用此选项将允许对象与所有基本形状(球形、长方体等)以及其他启用Convex的网格碰撞器碰撞
此外,如果为凹形的网格碰撞器启用了Convex复选框,则物理引擎将自动简化该网格碰撞器,生成的碰撞器具有能将其包围的最接近的凸形。
在上图中,如果导入右侧的凹形网格并启用Convex复选框,它将生成一个更接近左侧凸形形状的碰撞器。在这两种情况下,物理引擎都将尝试生成一个碰撞器,该碰撞器与附加的网格的形状匹配,上限为255个顶点。如果目标网格的顶点数超过此值,则在网格生成过程中会引发错误。
碰撞器组件还包含IsTrigger属性,允许将他们视为非物理对象,但当其他碰撞器进入或离开它们时仍调用物理时间。这些称为触发体积。通常,当一个碰撞器接触、保持接触、或停止接触时,分别会调用OnCollosionEnter()等三个回调,但当碰撞器用作出发体积时,将调用OnTriggerEnter()等三个回调。
注意:由于处理物体间碰撞的复杂性,凹形网格碰撞器不能是动态碰撞器,只能用作静态碰撞器或触发体积。如果试图将Rigidbody组件添加到凹形网格碰撞器中,Unity将完全忽略它。
提示:如果真的需要将凹形网格碰撞器作为Rigidbody组件,则解决方案是将对象分割成独立的凸形网格碰撞器的组合。例如,想利用两个凸形来组合一个L形刚体。不幸的是,因为这是一个微妙的决定,所以没有自动的方法来实现,需要手动执行这样的分解。
五、碰撞矩阵
物理引擎具有一个碰撞矩阵,该矩阵定义允许哪些对象与哪些对象发生碰撞。当处理边界体积重叠和碰撞时,物理引擎家那个自动忽略不适合此矩阵的对象。这节省了碰撞检测阶段的物理处理,还允许对象彼此移动而不发生任何碰撞。
碰撞矩阵可以通过Edit | Project Settings | (Physics/Physice2D) | Layers Collision Matrix访问。
碰撞矩阵系统通过Unity的层(Layer)系统工作。矩阵表示层与层之间的组合,启用复选框意味着在碰撞检测阶段将检查这两个层中的碰撞器。
要注意的是,对于整个项目,总共只能有32个层。
六、Rigidbody激活和休眠状态
每一个现代物理引擎都有一个共同的优化技术,即静止物体的内部状态从活动变为休眠。当Rigidbody处于休眠状态时,在固定的更新过程中,处理器几乎没有时间来更新对象,直到它被外力或碰撞事件唤醒。
用于确定静止状态的测量值,在不同的物理引擎中往往会有所不同,可以使用Rigidbody的线速度和角速度、动能、栋梁或其他一些物理属性来计算。Unity的两个物理引擎都是通过评估物体的质量归一化动能来工作的,这基本上可以取决于物体速度平方的大小。
如果物体的速度在短时间内没有超过某个阈值,那么物理引擎将假设物体在经历新的碰撞或施加新的力之前不再需要再次移动。在此之前,休眠对象将保持其当前位置。可以在Edit | Project Settings | Physice | Sleep Threshold下修改阈值,还可以从Profiler窗口的Physics Area中获取活动Rigidbody对象的总数。
七、射线和对象投射
物理引擎的另一个常见特征是能够将射线从一个点投射到另一个点,并用路径中的一个或多个对象生成碰撞信息,这就是所谓的射线投射。通过射线投射来实现一些游戏机制是很常见的,比如射击,其实现方式通常是执行从玩家到目标位置的射线投射,并在其路径中找到任何符合要求的目标。
还可以通过Physics.OverlapSphere()检查在空间中固定点的有限距离内获得的目标列表,这通常用于实现效果区域的游戏功能,如手榴弹爆炸,甚至可以用Physics.SphereCast()和Physics.CapsuleCast()在空间中向前投射整个对象。这些方法通常用来模拟宽激光束,或者只是确定什么东西在移动角色的路径中。
八、调试物理
物理错误通常分为两类:本来不应该碰撞的一对对象碰撞了;本来应该碰撞的没碰撞,在碰撞发生之后,发生了意想不到的事情。前一种情况往往更容易调试,通常是由于碰撞矩阵中的错误,射线投射中使用的层不正确,或者对象碰撞器的大小或形状错误。后一种情况往往更难解决,因为要获得以下3条消息:
- 确定哪个碰撞对象导致了问题
- 在解决之前确定碰撞条件
- 重现碰撞
获得了这3条信息中的任何一条都会使解决方案更容易,但这些信息在某些情况下都很难获得。
Profiler在Physics和Physics(2D)区域提供了一些测量信息,这是相当有用的,可以得到CPU活动在不通过类型隔离的所有刚体和刚体组上花费的量,这些类型包括动态碰撞器、静态碰撞器、运动对象、触发体积、约束和触点。
Physics 2D区域包含了更多的信息,比如睡眠和活动刚体的数量,以及处理时间步长的时间。在这两种情况下,详细的细分试图提供了更多的信息。这些信息有助于关注物理性能,但它并不能指出在物理行为中出现错误时发生了什么。
一个更适合帮助调试物理问题的工具是Physics Debugger,它可以通过Window | Physics Debugger打开。这个工具有助于从Scene窗口中过滤出不同类型的碰撞器,从而更好地了解哪些对象相互碰撞。当然,这对确定问题的条件和复现问题没有太大帮助。
相关文章:

Unity优化——加速物理引擎1
大家好,这里是七七,今天开始更新物理引擎相关的优化部分了,本文介绍的是物理引擎内部工作情况。 Unity技术有两种不同的物理引擎:用于3D物理的Nvidia的PhysX和用于2D物理的开源项目Box2D。然而,Unity对它们的实现是高…...
PHP的最新版本是多少?有什么新特性?
截至日期(2022年1月),PHP的最新稳定版本是PHP 8.0。以下是PHP 8.0的一些主要新特性: JIT 编译器: 引入了即时编译(Just-In-Time,JIT)引擎,提升了PHP脚本的执行性能。 命…...

漏洞复现-云安宝-云匣子Fastjson命令执行(附漏洞检测脚本)
免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…...
oh-my-zsh 安装和配置
安装zsh sudo apt update sudo apt install zsh安装oh-my-zsh sh -c "$(curl -fsSL https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh)"配置~/.zshrc sudo vim ~/.zshrc添加以下内容 ZSH_THEME"steeef" HISTFILE~/.zsh_history HISTS…...
LinuxBasicsForHackers笔记 -- 日志系统
日志文件存储有关操作系统和应用程序运行时发生的事件的信息,包括任何错误和安全警报。 rsyslog 日志守护进程 Linux 使用名为 syslogd 的守护进程自动记录计算机上的事件。 rsyslog 配置文件 与 Linux 中的几乎所有应用程序一样,rsyslog 由位于 /et…...

WPS Office JS宏实现批量处理Word中的标题和正文的样式
该篇讲解下word文档中的标题和正文批量修改样式,如下图: 前面一篇已讲解了WPS Office宏编辑器操作方法,这里不细讲了,如有不清楚可以查看该篇:https://blog.csdn.net/jiciqiang/article/details/134653657?spm1001.20…...

论文怎么改才能降低重复率
一、引言:智能工具助力,轻松降低论文重复率 论文的重复率是学术写作中的重要问题,如何有效降低重复率成为了许多研究者的关注焦点。如今,智能工具的发展为我们提供了更多选择。本文将介绍几种实用的智能工具,包括快码…...

【从零开始学习JVM | 第六篇】快速了解 直接内存
前言: 当谈及Java虚拟机(JVM)的内存管理时,我们通常会想到堆内存和栈内存。然而,还有一种被称为"直接内存"的特殊内存区域,它在Java应用程序中起着重要的作用。直接内存提供了一种与Java堆内存和…...

Wireshark中的http协议包分析
Wireshark可以跟踪网络协议的通讯过程,本节通过http协议,在了解Wireshark使用的基础上,重温http协议的通讯过程。 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于 字节流…...

ubuntu如何远程ssh登录Windows环境并执行测试命令
ubuntu如何远程ssh登录Windows环境并执行测试命令 1 paramiko模块简介1.1 安装paramiko1.2 paramiko基本用法1.2.1 创建SSHClient实例1.2.2 设置主机密钥策略1.2.3 连接SSH服务器1.2.4 执行命令1.2.5 关闭SSH连接1.2.6 异常处理 2 windows的配置2.1 启动OpenSSH服务2.2 配置防火…...
人工智能应用专栏----专栏介绍
文章目录 本专栏主要记录人工智能的应用方面的内容,包括chatGPT、AI绘图等等; 订阅后可私聊我获取 《从零注册并登录使用ChatGPT》 《从零开始使用chatGPT的API;通过chatgpt-next-web部署自己chatGPT web网页;无需翻墙,…...

【lesson11】表的约束(4)
文章目录 表的约束的介绍唯一键约束测试建表插入测试建表插入测试建表插入测试修改表插入测试 表的约束的介绍 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保…...

将单体应用程序迁移到微服务
多年来,我处理过多个单体应用,并将其中一些迁移到了微服务架构。我打算写下我所学到的东西以及我从经验中用到的策略,以实现成功的迁移。在这篇文章中,我将以AWS为例,但基本原则保持不变,可用于任何类型的基…...

Python读取.dat格式数据并转为.png,.jpg,.bmp等可视化格式(附代码)
.dat文件的命名规则没有统一的规定,但通常以.dat为扩展名。 目录 一、 .dat格式数据1.1 .dat数据用途1.2 常见的.dat文件格式1.3 .dat文件示例 二、读取.dat格式数据2.1 单个.dat文件读取并转换2.1.1 代码2.1.2 查看数据2.1.3 输出查看8Bit图片 2.2 批量.dat文件读取…...

matplotlib 默认属性和绘图风格
matplotlib 默认属性 一、绘图风格1. 绘制叠加折线图2. Solarize_Light23. _classic_test_patch4. _mpl-gallery5. _mpl-gallery-nogrid6. bmh7. classic8. fivethirtyeight9. ggplot10. grayscale11. seaborn12. seaborn-bright13. seaborn-colorblind14. seaborn-dark15. sea…...
ip地址怎么转化为十进制
IP地址是在计算机网络中广泛使用的一种标识符,它用于唯一地标识网络上的设备。在网络通信过程中,IP地址扮演着非常重要的角色。但是,对于一些非专业人士来说,IP地址可能是一个陌生的概念。为了更好地理解IP地址,本文…...

【Spring进阶系列丨第五篇】详解Spring中的依赖注入
文章目录 一、说明二、构造函数注入2.1、方式一【index索引方式】2.1.1、定义Bean2.1.2、主配置文件中配置Bean2.1.3、测试 2.2、方式二【indextype组合方式】2.2.1、定义Bean2.2.2、主配置文件配置Bean2.2.3、测试2.2.4、解决方案 2.3、方式三【name方式】2.3.1、定义Bean2.3.…...

DAP数据集成与算法模型如何结合使用
企业信息化建设会越来越完善,越来越体系化,当今数据时代背景下更加强调、重视数据的价值,以数据说话,通过数据为企业提升渠道转化率、改善企业产品、实现精准运营,为企业打造自助模式的数据分析成果,以数据…...
大数据监控
HBase 监控 {name“RegionServer”,sub“Server”,} irate(hadoop_hbase_totalrequestcount[5m]) irate(hadoop_hbase_totalrequestcount{instanceName“hacluster4”}[2m]) https://blog.csdn.net/Samooyou/article/details/129275640 https://www.tencentcloud.com/zh/doc…...

【C语言】数据结构——小堆实例探究
💗个人主页💗 ⭐个人专栏——数据结构学习⭐ 💫点击关注🤩一起学习C语言💯💫 导读: 我们在前面学习了单链表和顺序表,以及栈和队列。 今天我们来学习小堆。 关注博主或是订阅专栏&a…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...