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

游戏引擎学习第54天

仓库: https://gitee.com/mrxiao_com/2d_game

回顾

我们现在正专注于在游戏世界中放置小实体来代表所有的墙。这些实体围绕着世界的每个边缘。我们有活跃的实体,这些实体位于玩家的视野中,频繁更新,而那些离玩家较远的实体则以较低的频率运行,以减少计算资源消耗。我们需要开始优化我们的碰撞检测系统,以便处理这些实体更高效地。例如,即使它们在屏幕外,其他实体也会与它们碰撞。我们正在逐步实现这个系统,尽量减少错误,确保游戏体验流畅。

移除休眠实体的理由

我们开始制作系统,以便当摄像机移动时,我们能够动态地调整实体residence的位置。我们移除了不再需要的高频实体。与此同时,低频实体不再包括在我们模型中,因为它们没有必要的更新频率。我们现在只专注于高频实体,并删除所有休眠实体,简化了我们的实体管理系统。我们认为,这种调整能够减少复杂性,并使我们的系统更加高效。整体上,我们做出的改变使得游戏逻辑更加直观且不需要多余的管理。
在这里插入图片描述

在这里插入图片描述

关于解耦低实体和高实体数组的想法

我们现在有了一种添加实体的方法,这些实体可以从低状态开始,然后移动到高状态。这意味着大多数实体在世界生成时都是低状态的,而只有少数实体才会转移到高状态。这种分类方法帮助管理实体的活动和模拟,从而提高效率和性能。

我们开始考虑如何更好地划分实体集。一个有趣的思路是,高实体集只包含离玩家最近的有限数量的实体,而低实体则包含更多的远离玩家的实体。这种方式有助于将实体按需要移动到高集,从而优化性能。

另外,我们讨论了在高实体中是否包含低实体的问题。一种方法是复制低实体数据到高实体中,但这可能会增加内存开销。因此,前向和后向指针的方式可能更为合适,即记录低实体是否在高实体中,从而避免过度复制和不必要的内存访问。

总体而言,我们在思考如何管理实体时,正在寻找一种既能保持游戏性能,又能简化实体管理的方法。
在这里插入图片描述

默认情况下只在低实体列表中创建对象

我们现在只专注于在低频理想环境中创造一些东西,并开始处理列表中的项目。我们会有一个金融列表,包含高频和低频账户。基本上,我们保持低状态,并且只把低频的数据提升到高频时才使用。为了防止错误,我们需要确保所有索引都是正确的类型。我们应该确保代码路径总是有效,避免在运行时引入错误。如果高频表的空间不足,我们可以降级所有数据至低频。最终,所有操作的目的是将实体从低频提升至高频,确保代码的稳定性和正确性。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

关于高实体数组内存的备注

我们在代码中处理了将实体从低频状态转换为高频状态的问题。具体来说:

  1. 映射到相机空间
    我们首先将实体的位置从世界坐标系中的瓷砖空间映射到相机空间。通过计算瓷砖空间与相机位置的差值,我们可以将实体在世界坐标系的位置转换为相机坐标系中的位置。

  2. 性能限制
    我们需要为高频实体设置一个固定的性能预算,不能无限制地增加高频实体的数量。高频实体的数量受每帧CPU可处理的时间限制,意味着这个列表必须是有限的。我们将确保这个限制能够满足实时处理的需求。

  3. 高频实体的管理

    • 转换为高频实体
      如果实体没有高频索引,我们将其添加到高频实体列表中,并记录其新位置、速度和其他属性。同时,在低频实体数据中保存其对应的高频索引。
    • 处理高频实体列表
      高频实体列表是有限的,并且用于管理当前活动、接近玩家的实体。我们根据性能预算决定能够容纳多少个高频实体。
  4. 处理低频转换
    如果需要将实体从高频状态恢复为低频状态,我们会将其从高频列表中移除:

    • 列表管理
      如果高频实体位于列表的末尾,我们只需将高频实体数量减一即可。
      如果实体不在列表的末尾,我们需要将列表中的最后一个实体移动到被移除的实体位置,以填补空白,确保列表连续。
    • 性能优化
      为了保证常数时间的操作,我们考虑直接标记被移除的实体,而不留下空白。我们也可能使用一个“空闲列表”(free list)来管理被回收的位置。
  5. 处理逻辑
    我们在编写逻辑时特别关注以下几点:

    • 确保实体状态转换操作是高效的,避免在高频状态管理中出现性能瓶颈。
    • 确保列表操作不会留下空白,从而导致处理时间增加。
    • 未来的内存管理优化将主要围绕如何更高效地维护高频实体列表以及内存回收问题。
  6. 整体策略

    • 高频实体的管理:固定大小的列表,用于保存当前需要高频处理的实体。
    • 低频实体:主要用于存储不需要实时处理的实体,节约性能开销。
    • 性能预算:根据CPU时间限制,动态调整高频实体数量,确保游戏性能稳定。

最终,我们需要通过实时测试确定高频实体的具体上限,以及最优的列表管理策略。

在这里插入图片描述

思考使用空闲列表来代替压缩数组

我们在处理实体时,存在一个固定的预算限制,能够处理的实体数量是有限的。例如,如果我们最多只能处理256个实体,那么在迭代这些实体时,我们可以跳过那些被标记为“已处理”的实体。即使跳过它们会造成一定的性能损失,但我们并不关心,因为只要所有实体都已填满,我们就必须在预算内完成处理。

一种合理的方案是维护一个空闲列表,用来追踪已经被移除或不再活跃的实体。当一个高频实体被移除时,我们将它的索引添加到空闲列表中。这样,当需要分配一个新的位置时,只需从空闲列表中取出一个索引即可。这种方法简单明了,且符合实际需求。

另外一种方法是在移除某个实体时,将数组中的最后一个实体移动到当前被移除的位置,然后将实体计数减1。这种方法可以确保数组在内存中保持紧凑,避免留下“空洞”。但这种操作需要执行一次实体数据的复制,并且需要更新指向被移动实体的引用,确保所有引用都正确指向新位置。

两种方法各有优缺点:

  1. 使用空闲列表:无需移动数据,操作简单,适合场景中不需要数组紧凑的情况,因为我们已经限定了数组大小,确保了处理能力能够覆盖最大需求。
  2. 移动数组元素:保持数组的紧凑性,但需要进行数据复制和引用调整。

考虑到我们已经有了固定的预算,数组的大小也早已受限,因此保持数组的紧凑性并非必要。从性能和操作的简便性出发,维护一个空闲列表似乎是更合适的选择。

实现数组压缩

我们决定在当前情况下保持数组的紧凑性,以确保数据的完整性和可管理性。

当移除一个实体时,处理流程可以分为两种情况:

  1. 移除的是数组中的最后一个实体
    这种情况下操作非常简单,直接将计数减1,即可完成移除。

  2. 移除的不是最后一个实体
    这种情况下,我们需要进行重新映射,通过将数组中的最后一个实体移动到被移除的位置,确保数组不出现空隙。

具体的处理步骤如下:

  • 首先,确定数组中被移除的目标实体。
  • 如果被移除的实体不是最后一个实体,我们将数组中的最后一个实体移动到当前被移除的位置。
  • 移动之后,需要更新对应的索引信息:
    • 被移动实体的索引(高实体索引)需要指向新位置。
    • 所有引用到该实体的低级实体也需要更新,确保它们指向移动后的新位置。

这一流程可以确保数组的整体紧凑性,同时保持所有索引和指向引用的正确性。

此外,当我们将高频实体转换为低频实体时,需要将高频索引清除。这是因为该实体已经被标记为低频,失去了对应的高频索引。在所有情况下,操作完成后,都会确保高实体数据和低实体索引的一致性。

整体来看,这种方法既能保持数组的紧凑性,又能确保所有实体的引用关系正确更新,避免了出现“悬空引用”或数据不一致的问题。

在这里插入图片描述

将 GetEntity 更改为 GetLowEntity 和 GetHighEntity

这段内容探讨了实体管理的实现思路以及操作过程,特别关注“低频实体”和“高频实体”之间的转换与调用逻辑。主要内容总结如下:

  1. 实体的获取与调用
    实体管理的核心是通过方法获取“低频实体”,而不太关注“高频实体”的获取调用。整体设计假定大部分操作是针对低频实体的,“获取高频实体”可能不需要单独实现。这简化了整体逻辑。

  2. 返回结果的处理
    获取实体的方法需要有一个清晰的返回值逻辑:

    • 如果实体存在,则返回对应实体;
    • 如果不存在,则返回默认值,例如 0。
      这种方式确保调用方可以根据返回结果判断实体是否有效。
  3. 索引与结果管理
    在管理实体索引时,特别是处理“第一个有效位置”和“最后一个位置”时,需要考虑如何返回正确结果。通过明确地返回索引或者 0,可以简化实体的映射管理。

  4. 方法的对称性
    设计时确保获取低频实体和高频实体的方法是对称的,即两个方法在逻辑上可以互相补充。例如,低频实体的调用与高频实体的调用应该有一致的接口和返回方式,保持设计的简洁性与可维护性。

  5. 实体状态转换

    • 低频实体可以被提升为高频实体。
    • 在某些情况下,低频实体可能会替代或填补高频实体的位置。
      这种状态转换是实体管理的重要部分,确保资源得到有效利用,并避免无效的操作或重复占用。
  6. 简化与重构
    整体上强调逻辑的简化,移除了不必要的情况和复杂处理。通过“低频到高频”的设计,避免过度关心无关部分,使得管理过程更加清晰明了。

  7. 灵活性与可扩展性
    保留设计的灵活性,允许未来根据需求添加或扩展功能,例如同时提供“低频实体”和“高频实体”的获取方法。当前逻辑确保最基本的需求得到满足,同时具备一定的可扩展性。

总之,这段内容围绕实体的获取、索引管理与状态转换展开,强调逻辑的简洁性和对称性,同时保证返回结果的合理性,最终形成高效的实体管理方案。

在这里插入图片描述

将 AddEntity 更改为 AddLowEntity,并更新 AddWall

我们需要实现的是实体的添加操作,现在我们决定始终添加一个低频实体。这意味着,所有的实体都会首先以低频形式存在。在进行实体的添加时,我们需要确保所添加的实体始终符合一定的条件,例如索引范围需要在合法的低熵数组大小以内。

在添加新实体的过程中,首先我们进行断言,验证当前的索引值小于低熵数组的大小,以确保不会越界。接下来,我们对该实体进行初始化操作,确保它处于正确的初始状态。

虽然索引曾经是一个重要的标识,但现在低频实体的索引逐渐显得不那么重要了。在大多数情况下,实体索引对逻辑的作用变弱了,因为我们有了更加统一和抽象的管理方式。这使得外部调用者无需过多关心实体的具体索引,而只需要通过逻辑接口进行访问即可。

然而,仍然有一些情况下,我们需要知道索引的范围,尤其是在处理指针前后引用等操作时。这种情况下,索引信息仍然不可或缺。总体上,这里的实体操作都是基于低频实体进行的,这一层的抽象结构使得实体的管理更加流畅和有序。

我们也在考虑实体访问的效率问题。虽然目前实现的逻辑已经可以正常工作,但我们感觉在某些场景中,返回实体指针而不是索引可能会更加高效。然而,这种小的优化并不会对整体系统造成太大影响,所以暂时保持现状也是可以接受的。

综上所述,我们完成了低频实体的添加操作,确保了索引的有效性和实体的初始化。同时,我们也逐步淡化了索引在高层逻辑中的作用,进一步简化了实体管理的复杂性。
在这里插入图片描述

关于重构/重写代码的说明

在开发和编写代码的过程中,我们经常会多次反复地重写代码。这是一种常见且必要的工作方式,就像塑造黏土一样,我们需要不断调整和修改,直到最终形成理想的形态。在最初的阶段,我们并不追求完美的结果,而是通过多次尝试来逐步接近最终目标。

我们习惯于先快速地将代码写出来,然后根据实际需求和效果进行修改和重构。这种反复的过程是代码质量提升的关键。我们不会害怕重新编写代码,因为快速的重写不会耗费太多时间,也不会带来额外的成本。相反,这样的反复修改能够帮助我们发现更好的解决方案,并最终产出更高质量的结果。

我们需要保持灵活的态度,不断尝试不同的实现方式,直到代码的表现和逻辑让我们感到满意。这种方法不仅能够让代码更加完善,还能在实践中锻炼我们的思维和解决问题的能力。通过快速地迭代和调整,我们能够避免僵化地坚持某个不成熟的设计,而是始终保持代码的灵活性和可维护性。

在这样的过程中,代码重写并不是浪费时间的行为,而是追求高质量成果的必经之路。只有通过反复地打磨和优化,我们才能最终形成真正符合需求的代码,实现稳定和高效的功能。

更新 AddPlayer 和 MovePlayer

在编写代码时,我们常常需要不断调整和优化代码的各个部分。在处理不同的实体和索引时,我们必须仔细考虑如何优化和提高性能。对于添加的每个实体,我们首先不关心任何内部细节,只需确保这些实体能够正确地进行交互。

我们使用循环来遍历高和低的索引,确保每个实体都能准确地落入其预定位置。这个过程就是为了能够处理碰撞检测、任务执行等实际需求。我们需要对每个索引进行检查,以确保它们是独立的,不会与自己发生碰撞。

此外,代码中的一些部分已经经过了多次优化,例如将高索引与低索引组合在一起,以提高代码的执行效率。这些调整让代码更易于维护和扩展,从而产生更高质量的结果。尽管过程可能反复且繁琐,但这种反复的工作能够最终提升代码的性能和可读性。

最终,确保代码能够根据实际需求调整,并尽可能减少无效操作,这是提高开发效率的关键。通过反复地优化和调整,我们可以在不增加性能开销的情况下,确保代码的质量和稳定性。

在这里插入图片描述

在这里插入图片描述

更新 SetCamera,将residence地从高频转移到低频实体

我们需要遍历高频实体。这样的做法是完全可以的。我们不需要担心,因为我们知道在高下的所有物体都是高的。我们所做的和之前的操作一样,但是现在我们希望能够在循环中改变人的residence。之所以这么做,是因为这样可以让迭代更加简单,不会那么棘手。我们通过检查这些高实体,如果它们不在特定的矩形区域内,就将它们从集合中移出。这样做的原因是它使迭代非常顺利,不需要使用其他方法来处理它们。整体来看,这个循环非常简单,我们检查矩形区域,找到不在其中的高频实体,并移出它们,同时我们也能从这些高实体中获取低索引。这种方法使得迭代非常简单,并且不会频繁发生。这就是一个很有效率的循环。

一刻的顿悟;描述在变动的数组上迭代时遇到的问题

我们需要处理一个特殊情况,即当某个人走出边界时。这种情况下,我们需要从集合中移除这些人。在实现中,我们希望这两个子例程互相意识到,以保持迭代的简单性。我们担心的是如果只是简单的迭代,会导致数组被改变,因此无法正常工作。因此,我们希望将这些家伙捆绑在一起,使得他们在代码中的意义更大。

首先,我们检查这些高实体,如果它们不在特定的矩形区域内,则将它们从集合中移除。我们不希望直接改变实体索引,而是通过一个有效的函数来完成这项操作。然后,我们会处理低频的实体,在它们的区域内进行类似的操作。这样做的目的是保持高频和低频实体的操作一致,同时避免直接修改数组。我们希望在循环中每个人都能被正确的处理,而不因数组变异而出现问题。这种方法使得迭代变得更为简单且高效。整体来看,这就是我们处理这个问题的方式。

在这里插入图片描述

处理控制实体

我们正在控制实体的方式。当我们添加一个玩家时,我们检查控制器的低索引。如果低索引等于零,那么我们正在开始控制一个玩家。如果它不等于零,则正在处理已经控制的玩家实体。通过调用高亲和力函数,我们可以在高频段中获取和设置实体。为了确保不返回空指针,我们可能需要添加一个断言。这样做的目的是确保只有有效的低索引才会被处理。这种处理方式帮助我们保持游戏状态的有效性和一致性。
在这里插入图片描述

在这里插入图片描述

调试崩溃问题

我们需要清理处理方式并检查边界条件来确保正确创建高频实体。当前在快速移动操作时存在问题,可能是由于未正确处理环绕问题或位置调整不当。这些问题需要在后续的调试中解决,以确保高频实体的生成和位置的准确性。虽然今晚可能无法完全解决这些问题,但明天我们可以继续进行修复工作。
在这里插入图片描述

在这里插入图片描述

调试缺失墙壁和定位问题

我们需要审视代码中出现的问题,例如低频实体和高频实体的管理。发现低频实体计数不正确,可能是因为射线计数操作被重复调用。我们修正了这个问题,并重新分配了实体索引和指针,以确保它们被正确地处理。这样,我们能够使渲染调用更加有效率,改善空间分区,优化整个系统。这些改进使代码结构更为合理,增强了整个引擎的运行效率,使其向更具表现力的状态迈进。尽管还需要一些调整,但整体上的状态正在好转。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

将低频实体和高频实体数组的大小设为2的幂次方有什么优势?

关于实体的模拟,可能需要提前做好准备,确保可以顺利进行交流。这种方法可能会带来一定的优势,例如提高性能或流动性。我们倾向于使用2的幂次,这种方式通常能有效提升性能。

目前尚不确定具体规模的大小,因为这将完全基于性能需求。对于高频实体,我们会评估能支持的数量,预计可能会达到相当高的水平。然而,模拟这些实体的复杂度可能会限制规模,因此实际支持的数量可能会低于预期。相比之下,低频实体的数量预计会非常大,同时它们的属性和存储方式可能会占用游戏内存的大部分。这是我们的初步假设。

总结来看,低阶实体及其相关属性预计将在内存分配中占据主要比例,我们需要重点关注如何优化存储和管理以提升整体性能。

如果这是一个2D横向滚动平台游戏,你会如何设计控制和移动的过程?

这是一个第三人称的游戏。如果这是一个二维横向卷轴平台游戏,控制和移动的创建过程与目前的游戏其实没有太大差别。目前控制部分还没有完成,因此可以等到正式处理这些内容时再讨论。

当前我们只是使用了一个临时的控制机制,可以让角色移动,但这并不是最终的手感。我们计划先完成动画的制作,然后将动画和移动系统结合在一起,确保手感符合预期。

在碰撞检测方面,目前的设置中,重力只在角色起跳时生效。而如果是平台游戏,重力通常会成为一个持续性的问题,需要更精细的处理。除此之外,代码的大部分逻辑是相似的,没有太大的区别。整体流程中,核心逻辑保持一致,只是针对不同类型的游戏需求进行了适当的调整。

你觉得今天的代码会在优化过程中被重写吗?

在优化过程中,当前的内容可能会被重写。现在的主要目标是将所有的系统和逻辑安排好,以便明确规范和设计要求。当前的阶段主要是对代码布局进行整理,确保所有功能模块和接口清晰明了。通过这一阶段的工作,可以为接下来的开发奠定基础。

最终的解决方案和系统将基于当前的工作进行构建。在最初的几周内,主要任务是搭建框架并确认所有系统如何协同工作。如果没有一个基础框架,单独开发系统可能会导致它们在集成时难以很好地配合,甚至会出现重大问题。因此,首先创建一个能够合理融合的基础版本是关键。

接下来,在这个基础版本上对各个系统进行逐步迭代和优化,最终将它们调整到理想状态。通过这种方式,可以确保所有模块在开发和优化过程中始终能够保持一致,并最终形成一个完整、协调的整体系统。

难道不应该更容易保持一个空实体插槽列表来在其中添加实体,而不是总是移动和更改其中一个指针吗?

关于如何构建这些系统,有一种建议是使用一个包含固定大的结构,通过一个空槽列表来管理空位,将新元素添加到空槽中,而不是总是移动条目和修改指针。这种方法可能会更容易维护。

在选择具体方法时,对于两种方式的优劣尚未有明确的偏好。我们认为两者在本质上是相似的,并没有哪一种明显优于另一种。之所以选择当前的方法,是因为它的复杂性较低。具体来说,不需要为实体定义“空”的概念,因此在遍历实体时,不需要频繁检查当前槽位是否实际包含实体。

这种设计将复杂性集中在删除代码中,而不是将复杂性分散到整个系统的其他部分。这种方法能够更好地控制复杂性传播,因而被认为是一个更优的选择。不过,具体效果还需要在实际应用中进行验证和调整。

你是否了解游戏对象存储中的插槽映射(slot maps)?你是否会在这个项目中使用它们?我们在我们的引擎中使用它们。

关于slot maps的使用,目前对这个术语不太熟悉,需要进一步描述才能明确。如果能详细描述slot maps的定义和功能,就可以更确定地回答是否会在这个项目中使用它们。

slot maps的讨论涉及到游戏对象的存储管理,但由于对具体概念的理解尚不明确,所以暂时无法确认是否适合当前的项目。不过,如果slot maps能够提供更高效的对象管理方案,尤其是在复杂对象结构中可能产生优势的话,它确实值得考虑。

目前,需要更多关于slot maps的细节说明,以便更好地评估它们在系统中的潜在应用价值和适用性。这种方法的选择最终还是要看它是否能为项目的架构和性能带来实际的优化。

相关文章:

游戏引擎学习第54天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾 我们现在正专注于在游戏世界中放置小实体来代表所有的墙。这些实体围绕着世界的每个边缘。我们有活跃的实体,这些实体位于玩家的视野中,频繁更新,而那些离玩家较远的实体则以较低的频率运…...

QT绘制同心扇形

void ChartForm::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿painter.save();// 设置无边框(不需要设置QPen,因为默认是不绘制边框的)QPen pen(Qt::NoPen);// QPen pen…...

梳理你的思路(从OOP到架构设计)_浅尝架构师的滋味02

目录 1、 App开发者的职责:买主提供需求知识,App开发者帮他写代码 撰写的代码 撰写代码,将装配(扩充)到 2、 从生活中体会 基於軟硬整合觀點“两种知识” ​编辑 1、 App开发者的职责:买主提供需求知识,App开发者帮…...

使用VLC 搭建 RTSP 服务器

第一步:打开 VLC ,媒体--->流 第二步:添加一个选择本地的文件,然后点击选择"串流" 第三步:确认你选择的文件,然后点击下一个 第四步: 配置 选择的视频文件使用哪种 流输出&#xf…...

什么是大型语言模型

大型语言模型简介 大型语言模型 (LLM) 是一种深度学习算法,可以使用非常大的数据集识别、总结、翻译、预测和生成内容。 NVIDIA 开发者计划 想要了解有关 NIM 的更多信息?加入 NVIDIA 开发者计划,即可免费访问任何基础设施云、数据中心或个…...

游卡,科锐国际,蓝禾,汤臣倍健,顺丰,途游游戏25秋招内推

游卡,科锐国际,蓝禾,汤臣倍健,顺丰,途游游戏25秋招内推 ①科锐国际25届秋招补录 人力资源类岗位,补录城市:上海,苏州,锦州;全日制公办本科及以上 25届应届毕业…...

Linux -- 线程控制相关的函数

目录 pthread_create -- 创建线程 参数 返回值 代码 -- 不传 args: 编译时带 -lpthread 运行结果 为什么输出混杂? 如何证明两个线程属于同一个进程? 如何证明是两个执行流? 什么是LWP? 代码 -- 传 args&a…...

【Linux】Linux内核启动流程分析

Linux 内核的启动流程要比 uboot 复杂的多,涉及到的内容也更多,因此我们大致的了解一下Linux 内核的启动流程即可。 Linux启动流程 启动过程可以分为以下几个主要步骤: 1.引导加载程序(Bootloader)阶段 Linux 内核的…...

【uniapp蓝牙】基于native.js链接ble和非ble蓝牙

【uniapp蓝牙】基于native.js链接ble和非ble蓝牙 uniapp不是仅支持低功耗蓝牙(基础蓝牙通讯不支持),有些可能需要基础蓝牙。我现在同步我的手机蓝牙列表低功耗,基础蓝牙都支持 /*** author wzj* 通用蓝牙模块封装* 搜索 ble 和非…...

OpenGL ES 03 加载3张图片并做混合处理

OpenGL ES 02 加载3张图片并做混合处理 什么是纹理单元纹理单元的作用使用纹理单元的步骤详细解释加载图片并绑定到到GPU纹理单元采样器的设置1.设置采样器变量的纹理单元编号,目的是为了告诉纹理采样器,从哪个纹理单元采集数据2.如果你没有显式地设置采…...

c++数据结构算法复习基础--13--基数算法

基数排序 - 桶排序 时间复杂度 O(n*d) – d为数据的长度 每次比较一位(个位、十位。。。),所以取值范围就为0-9。 根据该特点,设计桶的概念 – 0号桶、1号桶… 1、思想 1)找出最长的数字,确定要处理的…...

基于YOLOv5的行人与帽子检测与识别说明文档

基于YOLOv5的行人与帽子检测与识别说明文档 1. 任务的内容和目标 1.1 任务目标 在计算机视觉领域,头盔检测至关重要,主要用于判定图像或视频里的人是否佩戴头盔。于工业生产、建筑工地、交通出行(如摩托车与自行车骑行)等高危场…...

Mybatis——(2)

2.2 Mybatis 工具类(了解) 为了简化MyBatis的开发,可将MyBatis进一步封装。 import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apa…...

QT笔记- QSystemTrayIcon系统托盘功能完整示例

1. 创建托盘对象 // 创建托盘图标QSystemTrayIcon * trayIcon new QSystemTrayIcon(this);QIcon icon("://icon/test.png");trayIcon->setIcon(icon);trayIcon->show();trayIcon->connect(trayIcon, &QSystemTrayIcon::activated,this, &MainWindo…...

ElasticSearch08-分析器详解

零、文章目录 ElasticSearch08-分析器详解 1、分析器原理 Elasticsearch的分词器(Analyzer)是全文搜索的核心组件,它负责将文本转换为一系列单词(term/token)的过程,也叫分词。 (1&#xff…...

指针的深入讲解

本章重点: 字符指针数组指针指针数组数组传参和指针传参函数指针函数指针数组指向函数指针数组的指针回调函数 我们在指针的初阶的时候主要讲了: 1.指针就是变量,用来存放地址,地址唯一标识一块内存空间 2.指针的大小是固定4个…...

王佩丰24节Excel学习笔记——第十二讲:match + index

【以 Excel2010 系列学习,用 Office LTSC 专业增强版 2021 实践】 【本章小技巧】 vlookup与match,index 相结合使用match,index 结合,快速取得引用的值扩展功能,使用match/index函数,结合照相机工具获取照片 一、回顾…...

概率论得学习和整理28:用EXCEL画折线图,X轴数据也被当成曲线的解决办法

目录 1 折线图和散点图,对数据的处理差别 1.1 EXCEL画图的一些默认设置 1.2 多于2列的数据,也是如此 2 如果我们非要以第1列数据为X轴,做一个折线图呢?也能 2.1 首先,把第1列,想当成X轴的数据&#xf…...

387. 字符串中的第一个唯一字符

1,题目 给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。 2,代码 class Solution { public:int firstUniqChar(string s) {//记数排序int coutArr[26] {0};//统计字符出现…...

Oracle RAC最佳实践-优化私网连接

在 Oracle RAC 环境中,私网(Interconnect) 是节点之间通信和数据传输的关键部分。一直有个误解,认为私网(心跳网)只要能通随便什么交换机都可以,甚至有直连的,实际上私网的性能至关重要&#xf…...

[bug] StarRocks borker load意向之外的bug

意向之外,又清理之中 背景: StarRocks各方面碾压相同类型的数据库,最近我们要从生成HIVE导历史数据(ORC格式)到StarRocks,前期小测一下,在测试是没问题,上生产先导2个月的数据&…...

游戏AI实现-寻路算法(Dijkstra)

戴克斯特拉算法(英语:Dijkstras algorithm),又称迪杰斯特拉算法、Dijkstra算法,是由荷兰计算机科学家艾兹赫尔戴克斯特拉在1956年发现的算法。 算法过程: 1.首先设置开始节点的成本值为0,并将…...

9 OOM和JVM退出。OOM后JVM一定会退出吗?

首先我们把两个概念讲清楚 OOM是线程在申请堆内存,发现堆内存空间不足时候抛出的异常。 JVM退出的条件如下: java虚拟机在没有守护线程的时候会退出。守护线程是启动JVM的线程,服务于用户线程。 我们简单说下守护线程的功能: 1.日志的记录…...

Linux 端口操作

安装netstat yum -y install net-tools 检测端口占用 netstat -npl | grep "端口" 安装lsof lsof yum -y install lsof 检测端口占用 lsof -i :端口号 安装nc yum -y install nc 查看对方端口是否开放 nc -vz 对方ip 对方端口 安装telnet telnet yum -y in…...

【USB-HID】“自动化键盘“ - 模拟键盘输入

目录 【USB-HID】"自动化键盘" - 模拟键盘输入1. 前言2. 模拟键盘2.1 STM32CubeMX 配置2.2 修改代码配置2.3 发送按键信息 3. 接收主机Setup数据3.1 获取PC下发的数据 4. 总结 【USB-HID】“自动化键盘” - 模拟键盘输入 1. 前言 对于模拟键盘的实现,网…...

基于Spring Boot+Vue 的高校运动会管理系统

目录 1 绪论1.1研究背景1.2 研究意义1.3 相关开发技术简介1.3.1 Vue.js1.3.2 Spring Boot1.3.3 MySQL 2 系统分析2.1 需求分析2.1.1 功能需求2.1.2 非功能需求 2.2 系统可行性分析2.2.1 经济可行性2.2.2 技术可行性2.2.3 操作可行性 3 系统概要设计系统功能描述业务流程分析 4 …...

Linux应用程序中终止进程的几种方法

目录 1、正常退出进程的方法 1.1、exit(int status) 函数 1.2、_exit(int status) 函数 1.3、_Exit(int status) 函数 2、异常退出进程的方法 3、何时使用这些方法? 在 Linux 应用程序中,终止进程的方式有多种,通常取决于进程是否需要进…...

电脑文档损坏:原因剖析和修复方法

在使用电脑的过程中,许多用户可能会遇到文档突然提示损坏、无法打开的情况。这种情况的发生往往让人感到困惑,特别是当并未进行任何明显错误操作时。以下是一些常见的原因以及应对方法。 一、文档损坏的常见原因 1、非人为的异常操作: 在编…...

了解ARM的千兆以太网——RK3588

1. 简介 本文并不重点讲解调试内容,重点了解以太网在ARM设计中的框架以及在设备树以及驱动的一个整体框架。了解作为一个驱动开发人员当拿到一款未开发过的ARM板卡应该怎么去把网卡配置使用起来。 2. 基础知识介绍 在嵌入式ARM中实现以太网的解决方案通常有以下两种…...

【Nginx-4】Nginx负载均衡策略详解

在现代Web应用中,随着用户访问量的增加,单台服务器往往难以承受巨大的流量压力。为了解决这一问题,负载均衡技术应运而生。Nginx作为一款高性能的Web服务器和反向代理服务器,提供了多种负载均衡策略,能够有效地将请求分…...

低级计算机网络知识总结

1 应用层 1.1 HTTP(TCP) 浏览器访问WWW服务器过程:首先进行域名解析,然后通过TCP向服务器发送连接请求 HTTP本身是无连接,无状态的。无状态特性使服务器能够支持大量的并发HTTP请求。实际应用中,通常使用Cookie加数据库跟踪用户…...

linux sysrq的使用举例

在menuconfig中选择m和 *的区别: *: 模块驱动编译到内核中,启动时自动加载 M:标识作为内核模块编译 空格:表示该功能不编译到内核中,即新的内核将不支持该功能。 m:模块会被编译,但是不会被编译到内核中,只…...

数字IC后端设计实现篇之TSMC 12nm TCD cell(Dummy TCD Cell)应该怎么加?

TSMC 12nm A72项目我们需要按照foundary的要求提前在floorplan阶段加好TCD Cell。这个cell是用来做工艺校准的。这个dummy TCD Cell也可以等后续Calibre 插dummy自动插。但咱们项目要求提前在floorplan阶段就先预先规划好位置。 TSCM12nm 1P9M的metal stack结构图如下图所示。…...

Oracle 适配 OpenGauss 数据库差异语法汇总

背景 国产化进程中,需要将某项目的数据库从 Oracle 转为 OpenGauss ,项目初期也是规划了适配不同数据库的,MyBatis 配置加载路径设计的是根据数据库类型加载指定文件夹的 xml 文件。 后面由于固定了数据库类型为 Oracle 后,只写…...

【记录】Django解决与VUE跨域问题

1 梗概 这里记录Django与VUE的跨域问题解决方法,主要修改内容是在 Django 中。当然其他的前端项目 Django 也可以这样处理。 2 安装辅助包 pip install django-cors-headers3 配置 settings.py INSTALLED_APPS [ # ... corsheaders, # ... ] 为了响应…...

Yolov10本地部署,torch找不到GPU问题解决

在本地部署跑Yolov10的模型.具体分为以下几步,也是踩了一些坑: 1.YoloV10 代码拉取 2.安装CUDA 1.查看CUDA支持版本 2.下载安装CUDA 3.下载CUDNN 3.创建python虚拟环境 Anaconda下载安装 虚拟环境安装配置 4.运行 1.yoloV10代码拉取 源码地址: GitHub - THU-MIG/yolov10: YOLO…...

el-upload 上传文件 入参格式为form-data格式,入参字段为code、name、type、file(文件)的形式,如何实现?

el-upload 是 Element UI 中用于文件上传的组件。如果你需要上传文件并将其封装为 form-data 格式,并且包含字段如 code、name、type 和 file,你可以通过自定义 before-upload 或 action 进行处理。 1. el-upload 的基本用法 Element UI 的 el-upload …...

VUE组件插槽使用示例,弹窗样式

在Vue.js中,插槽(slots)是一种非常强大的功能,它允许你在父组件中向子组件传递内容。插槽主要有三种类型:默认插槽、具名插槽和作用域插槽。下面是一些示例来展示如何使用这些插槽。 默认插槽 默认插槽是最简单的插槽…...

ARM嵌入式学习--第八天(PWM)

PWM -PWM介绍 PWM(pulse Width Modulation)简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在测量,通信,工控等方面 PWM的频率 是指在1秒钟内,信号从…...

新能源汽车大屏可视化第三次数据存储

任务: 将数据存放到temp.csv 链接: 1.排行页面 https://www.dongchedi.com/sales 2.参数页面 https://www.dongchedi.com/auto/params-carIds-x-9824 完善打印: 1. [{‘series_id’: 5952, ‘series_name’: ‘海鸥’, ‘image’: ‘https://…...

linux 替换yum源镜像

1. 备份源镜像 sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak 2. 下载国内镜像阿里云 如果没有wget可以用curl 代替 sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 清华大学 sudo wget -…...

SAP:如何修改已释放的请求

SAP:如何修改已释放的请求 QQ出了一个新功能,把10年前的旧日志推给自己。这个10年前的日志,是用户反映在SE10中把请求释放后发现漏了内容,想修改已释放的请求。经调查写了一个小程序,实现用户的需求。 *&-------------------…...

js的?. 和??和||有什么区别

let a 0; let b null; let c Hello;console.log(a ?? default); // 0 console.log(b ?? default); // "default" console.log(c ?? default); // "Hello"console.log(a || default); // "default" (因为 0 是假值) console.log(b |…...

clickhouse 分布式表创建、增加、更新、删除、查询

创建分布式表 --先创建本地表 设置自动过期时间3天 CREATE TABLE IF NOT EXISTS ck_database.ck_databaseon cluster default(cluster name) (table_id String COMMENT id,item_id String COMMENT 业务id,desc Int64 COMMENT 描述,time DateTime DEFAULT now() COMMENT 数据…...

推送本地仓库到远程git仓库

目录 推送本地仓库到远程git仓库1.1修改本地仓库用户名1.2 push 命令1.3远程分支查看 推送本地仓库到远程git仓库 删除之前的仓库中的所有内容,从新建库,同时创建一个 A.txt 文件 清空原有的远程仓库内容,重新创建一个新的仓库,…...

LSTM长短期记忆网络

LSTM(长短期记忆网络)数学原理 LSTM(Long Short-Term Memory)是一种特殊的递归神经网络(RNN),解决了标准RNN中存在的梯度消失(Vanishing Gradient) 和**梯度爆炸&#x…...

ABAP SQL 取日期+时间最新的一条数据

我们在系统对接的时候,外部系统可能会推送多个数据给到我们。 我们 SAP 系统的表数据中日期和时间是作为主键的,那么如果通过 ABAP SQL 取到最新日期的最新时间呢。 解决方案: 方式 1:SELECT MAX 可以通过两个 SELECT MAX 来取…...

SAST静态应用安全测试常见的编码规则

行业优先级难易度标准标准名称数量 军工12易GJB 5369:2005GJB_5369(国家军用标准航天型号软件C语言可靠性编程规范)138军工行业最早的C语言编码标准,强制性4易GJB 8114:2013GJB_8114(国家军用标准C/C语言可靠性编程规范&#xff…...

AI相关专业名词汇总解释

1.SFT Supervised fine-tuning,“有监督微调”意味着使用有标签的数据来调整一个已预训练好的语言模型(LLM),使其更适应某一特定任务。通常LLM的预训练是无监督的,但微调过程往往是有监督的。 详解:https:/…...

【C语言】指针数组和数组指针

前言 指针数组和数组指针是C语言中经常混淆的两个概念,虽然他们的名字相似,但其含义却完全不同。 指针数组 指针数组本质是一个数组,特点是数组中的元素均为指针,其定义形式为: 数据类型 *指针名[长度] 例如 int *…...