游戏开发实战(二):Python复刻「崩坏星穹铁道」嗷呜嗷呜事务所---源码级解析该小游戏背后的算法与设计模式【纯原创】
文章目录
- 奇美拉和队列
- 奇美拉被动技能
- 多对多观察者关系实现
- 自定义元类
- 奇美拉基类
- 管理奇美拉的队列
- 奇美拉队列类
- 心得体会
- 扩展
- 规则定义
- 工作相关
- 奇美拉相关
- 奇美拉属性
在本篇博文,我将介绍本项目的整体框架,以及“编码规则”,这些规则保证了本项目的结果和游戏中的实际结果的一致性。
关于游戏规则和奇美拉档案见:
游戏开发实战(一):Python复刻「崩坏星穹铁道」嗷呜嗷呜事务所—源码级解析该小游戏背后的算法与设计模式【纯原创】-CSDN博客‘
后续见:
游戏开发实战(三):Python复刻「崩坏星穹铁道」嗷呜嗷呜事务所—源码级解析该小游戏背后的算法与设计模式【纯原创】-CSDN博客
项目githu地址 https://github.com/Hanachirusat/Chimeras
奇美拉和队列
奇美拉被动技能
奇美拉的技能可以抽象为一种形式:满足条件,触发技能。因此我们可以非常自然的采用观察者模式来实现被动技能方法的自动调用。奇美拉行动后,如果某个条件得到满足,则通知该奇美拉的所有观察者。由于每个奇美拉行动后都有可能使得某个可以触发其他奇美拉被动技能的条件得到满足,因此每个奇美拉是subject,也是observer,这是一个多对多的观察关系。
通过对奇美拉的技能触发条件进行分析,我们可以把技能分成两类:自身触发和队友触发。自身触发条件中包含生命值降低这种属性(变化)触发,也包含同伴工作或追加工作这种动作触发,此外还有登场技能和回合技。队友触发条件同理。因此从代码实现层面,技能触发可以分为属性触发和动作触发。
属性触发很简单,如果奇美拉的属性发生了变化,则同时他的所有观察者,由观察者判断该属性的变化是否会触发自身的技能。而动作触发反映在代码层面可能是奇美拉执行完某个方法后,通知他所有的观察者。人都是喜欢偷懒的,那么有没有把所有触发条件统一起来的方法呢?
答案显而易见,我们可以把动作触发转变为属性触发,例如同伴工作时触发的技能,我们可以对奇美拉增加一个属性:工作次数,当奇美拉工作后,该工作次数+1。这样就可以把工作触发(动作触发)转变为属性触发。同时我们把工作逻辑剥离出来(后续将解释为什么),把每个奇美拉抽象为一个只有被动技能方法(用eval表示)的类(最终实现版本还是有其他方法的,在后面我们将一一介绍why,what以及how),并且该被动技能是自动触发的。
最后,我们继续简化,不同奇美拉的技能触发条件不同,这是不是意味着观察者模式的实现很复杂?实则不然,我们可以让奇美拉监控所有的属性,然后在eval方法中判断变化的属性是否符合奇美拉技能触发的条件。
多对多观察者关系实现
基于上一小结的介绍,在本小节,我们将详细描述如何利用元类来实现多对多的观察者关系。
自定义元类
由于我们把所有的触发条件都转换为了属性触发,那么当奇美拉的任意属性(可能触发其他奇美拉被动的属性)发生变化时,都应该通知观察该奇美拉的观察者。换句话说,我们需要控制每个属性的set过程。自然而然的方法就是property装饰器。我们在元类中遍历所有的属性,处理这些属性get和set时的逻辑。即set时将通知所有的观察者,属性发生了变化。
class ObservableMeta(type):"""元类用于自动创建属性观察逻辑"""def __new__(cls, name, bases, dct):# 自动为可能触发其他奇美拉技能的属性创建观察逻辑if '__observed_attrs__' in dct:attrs = dct['__observed_attrs__']for attr in attrs:# 为每个被观察属性生成属性描述符private_attr = f"_{name}__{attr}"#下面的操作相当于对继承该元类的类的私有属性设置@property和@attr.setter(def getter(self, name=private_attr):return getattr(self, name)def setter(self, value, name=private_attr, attr=attr):old_value = getattr(self, name)if old_value != value:setattr(self, name, value)#修改属性的时候,调用类的notify_observers方法# 通知所有的观察者属性发生了变化self.notify_observers(attr, old_value, value)dct[attr] = property(getter, setter)return super().__new__(cls, name, bases, dct)
在上述代码中,由于我们把奇美拉的属性定义为了私有属性,因此我们需要修改访问私有属性的形式private_attr = f"_{name}__{attr}"
其中attr是私有属性,private_attr是可以直接访问私有属性的形式(注:python中没有真正意义上的私有属性,私有属性只不过实际换了个名字存储而已,有兴趣的可以详细了解下)。我们在修改属性值的时候,会记录变化的属性,旧值和新值。然后把这些值传递给观察者。
奇美拉基类
接下来我们实现所有奇美拉的基类,在该基类中我们定义了增加和移除观察者的方法,通知观察者的方法以及析构函数
class ChimerasEntity(metaclass=ObservableMeta):"""所有可观察对象的基类"""__observed_attrs__ = () # 需要子类指定要观察的属性def __init__(self, name):self.name = nameself._observers = weakref.WeakSet()self.queue = None # 所属队列的弱引用def add_observer(self, observer):if not isinstance(observer, ChimerasEntity):raise TypeError("观察者必须是ObservedEntity类型")self._observers.add(observer)def remove_observer(self, observer):self._observers.discard(observer)#该方法在setter的时候被自动调用,get和set是所做的特殊操作由元类来实现def notify_observers(self, changed_attr, old_value, new_value):for observer in self._observers:observer.eval(self, changed_attr, old_value, new_value)def eval(self, changed_obj, changed_attr, old_value, new_value):#打印检测信息print(f"[类名:{self.__class__.__name__},实例名:{self.name}] 检测到变化:"f"【{changed_obj.__class__.__name__}】{changed_obj.name} 的"f"{changed_attr} 属性从 {old_value} 变为 {new_value}")def __del__(self):# print(f"执行{self.__class__.__name__}的析构函数")queue_ = getattr(self, 'queue', None)if queue_ is not None:# print("从队列中删除")queue_.remove_member(self)self.queue=None
在上述代码中,我们保存所有观察者的弱引用,这个弱引用是一个集合的形式,无法保证顺序。这可能就是本项目为什么和实际游戏中奇美拉的行动顺序不一致的原因(注意:只是行动顺序不一致,每回合的结果是一致的!后面我们会讲为什么)。基类中的queue属性表示的是奇美拉所属的队列(队列的含义详细请参考上一篇博文:游戏开发实战(一):Python复刻「崩坏星穹铁道」嗷呜嗷呜事务所—源码级解析该小游戏背后的算法与设计模式【纯原创】-CSDN博客,队列的实现我将在后面详细介绍)
在上述代码中eval方法打印的是辅助判断的信息,实际每个奇美拉都会有自己的eval方法(继承重写该方法)。由于后面我们在奇美拉队列类(InteractionQueue)中保存的是所有奇美拉的强引用,因此该析构函数当且仅当该奇美拉已经从队列中移除后才会调用。如果奇美拉队列还保留着当前奇美拉对象的引用,直接del奇美拉对象,python解释器并不会立刻执行该奇美拉对象的析构函数之后销毁该对象。
也就是说,我们最终还是需要手动调用奇美拉队列类的方法,把当前奇美拉对象从队列中移除。我们在析构函数中所做的操作似乎是多余的!是的至少目前为止是多余的,该析构函数的执行只有当该析构函数中的操作都做了之后才会执行。为什么还要这么写?
这是因为我们后续优化的时候需要把queue中的强引用列表和奇美拉基类中的弱引用集合都变为有序弱引用。优化后析构函数中的操作相当于一层保险,如果没有主动调用奇美拉队列中的移除方法,也不会造成内存泄漏(因为奇美拉队列中是弱引用,并不会增加引用计数,del奇美拉对象的时候会正常执行奇美拉对象的析构函数从而从队列中移除该奇美拉)。同时用有序弱引用也可以调整奇美拉行动顺序从而和游戏中的顺序保持一致。
管理奇美拉的队列
奇美拉队列类
我们用一个奇美拉队列来维护当前奇美拉队列,处理不同奇美拉的观察逻辑。当每一个奇美拉入队的时候,根据奇美拉技能触发类型(自身触发还是队友触发),构建这些奇美拉的观察者序列。奇美拉队列中记录了奇美拉在队伍中共的顺序,奇美拉领队和待完成的工作。
- 添加成员方法中将根据当前成员的观察模式(也就是技能触发的类型,观察模式为2代表观察所有包括自己,1代表进观察同伴,0代表仅观察自身),对不同的奇美拉对象添加管擦或者。注意处理完当前待添加的奇美拉对象后,还要处理已有奇美拉对象。
- 移除队列方法遍历当前所有奇美拉对象,并移除双向观察逻辑。
- 清空队列方法,调用移除队列方法清空对象。
- 添加和删除领队和添加和删除奇美拉对象类似。
class InteractionQueue:"""管理相互观察的队列"""#1 观察所有 2#2 观察除了自己外的所有 1#3 只观察自己 0def __init__(self):self.members_list =[]self.leader=Noneself.work=Noneself.episode=0def add_member(self, member):if not isinstance(member, ChimerasEntity):raise TypeError("成员必须是ObservedEntity类型")# 建立新成员和已有成员的相互观察关系。# 判断新成员是否观察已有成员if member.mode>0:for existing_member in self.members_list:#观察其他所有成员,所有要把当前成员添加到其他所有成员的观察者列表中existing_member.add_observer(member)#2和0 判断新成员是否观察自身if member.mode%2==0:# 观察自己和加入队列member.add_observer(member) # 观察自己#如果其他的成员的mode>0则表示其他成员要观察新成员,即新成员的观察者列表中要添加已有的成员for existing_member in self.members_list:if existing_member.mode > 0:member.add_observer(existing_member)self.members_list.append(member)#我们在每个奇美拉对象中记录所在队列的对象,方便后续的技能处理逻辑的实现。member.queue = selfdef remove_member(self, member):"""安全移除成员并清理观察关系"""if member not in self.members_list:return# 清理双向观察关系,# current_member队列中包含所有成员,即包含memberfor existing_member in self.members_list:# 其他成员不再观察被移除者 existing_member.remove_observer(member)# 被移除者不再观察其他成员member.remove_observer(existing_member)member.queue = None # 清除队列引用# # 移除自我观察# member.remove_observer(member)# 从队列中移除self.members_list.remove(member)def clear(self):"""清空整个队列"""for member in list(self.members_list):self.remove_member(member)# # 新成员观察所有现有成员# for existing_member in self.members:# member.add_observer(existing_member)def add_leader(self,leader):if not isinstance(leader, ChimerasEntity):raise TypeError("成员必须是ObservedEntity类型")# 建立新成员和已有成员的相互观察关系。# 判断新成员是否观察已有成员if leader.mode>0:for existing_member in self.members_list:#观察其他所有成员,所有要把当前成员添加到其他所有成员的观察者列表中existing_member.add_observer(leader)#2和0 判断新成员是否观察自身if leader.mode%2==0:# 观察自己和加入队列leader.add_observer(leader) # 观察自己self.leader=leaderleader.queue = selfdef remove_leader(self,leader):"""安全移除成员并清理观察关系"""if self.leader!=leader:print("领队不在当前队列中")returnfor existing_member in self.members_list:# 删除领队的观察者身份(清空队列中其他成员的观察者弱引用)existing_member.remove_observer(leader)leader.queue = None # 清除队列引用# 清空自身观察,因为自身不在member_list中leader.remove_observer(leader)# 从队列中移除self.leader=None
在上述奇美拉队列类中,我们把领队和工作奇美拉分开管理,方便后续奇美拉技能导致的队列变动。
心得体会
用一个类对象来管理奇美拉对象有很多好处,刚开始没考虑到的事情后面可以直接添加到奇美拉队列类中,比如抢功劳奇美拉中需要判断当前工作的进度,而在奇美拉对象中共无法直接获得工作进度。可以选择修改eval函数的接口,修改eval函数的接口就要修改基类的接口,导致需要修改其他已实现的代码。因此我最后选择直接在奇美拉队列类中新增一个属性,保存当前待完成的工作,因为每个奇美拉都保留了当前队列的引用,可以直接获得当前工作的进度。
扩展
用奇美拉队列类来管理奇美拉队列,开始时我们创建奇美拉对象然后添加到奇美拉队列对象中,注意添加顺序,最左面的奇美拉应该先添加。最后当任务完成后,我们需要调用奇美拉队列对象的移除方法移除所有的奇美拉对象,然后del所有的奇美拉对象。对象删除之类的操作在实际生产环境中是非常重要的。而在本项目中,所有奇美拉对象在主程序执行完毕后销毁。
规则定义
这里的很多规则是在实现过程中不断完善的,有了方便读者阅读和理解,在此我先给出所有的规则,之后再给出所有奇美拉类的具体实现。
工作相关
-
采用回合制,第一回合开始的时候统一设置奇美拉登场相关的属性从而触发奇美拉登场技能。后续的每回合都做如下操作:
- 每回合开始时回合数加1,以便触发奇美拉每回合的技能。
- 固定奇美拉攻击力,这点非常重要!!这保证了本项目的结果和游戏结果一致!!因为在实际游戏中,对于攻击力的buff最后才会执行,因此我们固定攻击力快照后,即使增加攻击力的buff提前执行,也并不影响实际的结果!!!
- 第一个奇美拉工作。工作逻辑为先处理工作对象的hp,再处理当前对象的hp,判断当前工作是否已经被完成,工作数量+1。先判断工作是否被完成,再工作数+1是正确绑定工作完成关系的关键。因为当前奇美拉已经完成工作,并且先工作+1,那可能会触发其他奇美拉的追加攻击,导致程序判定触发被动的奇美拉完成工作。(这涉及到后面的规则,为了和游戏结果保持一致,工作已经被完成也会继续追加攻击以便继续加buff)。
- 判断奇美拉hp是否小于1,如果小于1则离场。如果奇美拉的hp小于1并且代表登场的属性为False,则奇美拉也离场(其他奇美拉的技能可能会导致奇美拉hp>0但是直接离场)
奇美拉相关
-
工作已经被完成也会继续追加攻击以便继续加buff
-
奇美拉如果导致其他奇美拉直接离场,并不会修改离场奇美拉的hp,也不会从队列中移除该奇美拉,而是修改该奇美拉对象中表示登场的属性为False
这么做可能会出现一个问题,那就是游戏中奇美拉离场的动作优先级很高,而在本项目实现中,奇美拉离场逻辑在每回合最后才处理。这可能导致奇美拉离场和交换位置相关技能之间的联动和游戏中的结果不一致。因此在本项目中,我们做出一致性规定:奇美拉一定在本回合工作结束,所有技能都触发后才离场。交换位置的技能发动后,奇美拉可以和将要离场但是还未离场的奇美拉交换位置。
做出如上规定后,与交换位置相关的技能的代码逻辑就变得简单多了,我们只需要考虑当前位置即可,不需要考虑当前位置前后的奇美拉是否已经离场。
-
奇美拉技能发动的大前提一定是奇美拉在场!!这点和上面的2有联动。
-
工作已经被完成后,奇美拉会继续追加攻击当前被完成的工作,以便吃到buff加成。
-
奇美拉技能执行期间,如果可能触发其他技能,那应该保证当前需要处理的逻辑处理完成后再修改可能触发技能的属性。由于这种情况很少,因此我用这种简单的方法保证”原子性“(这么说并不准确!!只是方便理解把)。比如如果奇美拉追加攻击后,应该先判断工作是否被完成再增加奇美拉追加工作的次数。因为增加追加工作次数可能触发其他奇美拉的被动(同伴工作或者追加工作触发的被动)
-
奇美拉体力降低到0时不会立刻退场,等到回合结束后统一离场=其他奇美拉技能可以增加hp)。同伴累到的判断条件为奇美拉的hp小于0。因此可能会出现这么一种情况,同伴累到时的触发的被动可能会被同一个奇美拉触发多次,这点是否在游戏中也是如此本人并没有验证,在此指出)
-
在eval中,如果我们操作可能被监控的属性,应该用非下划线的形式,否则不会被监控到。在本项目中,只要属性变化一定会调用观察者的eval,因此我们需要准确处理eval中的逻辑,如果不满足条件应该提前推出eval函数。(在最后的优化讨论中,我将给出优化方向,奇美拉仅监控其他奇美拉会触发技能的属性,而不是监控所有属性)
-
技能对同伴的操作一律不包含自身,例如使得同伴体力全部+8,不包括自身。我并没有验证游戏结果,而是仅从字面意思判断,同伴肯定指的是自己之外的奇美拉。我自己是这么理解的,如果游戏中同伴也包括自身,则对应修改即可,本项目则坚持同伴指的是自己之外的奇美拉。
奇美拉属性
self.name=name #奇美拉名字
self.__atk=1
self.__hp=1
self.__episode=0 #回合数,用于触发回合技
self.__on=False #是否在场,True为登场,刚开始的时候为False
self.__work_num=0 #工作次数,用于触发 【同伴工作后】的技能
self.__append_work_num=0 #追加攻击次数,用于触发 【同伴追加工作后】的技能
self.__mode=0 #监控规则,详情见正文描述
self.__skill=True #奇美拉是否有技能
self.__complete_work_num = 0 #奇美拉完成工作次数,用于触发【同伴完成工作】的技能
self.__fixed_atk=0 #每回合开始奇美拉的攻击快照。保证了本项目结果和游戏结果的一致性。
相关文章:
游戏开发实战(二):Python复刻「崩坏星穹铁道」嗷呜嗷呜事务所---源码级解析该小游戏背后的算法与设计模式【纯原创】
文章目录 奇美拉和队列奇美拉被动技能多对多观察者关系实现自定义元类奇美拉基类 管理奇美拉的队列奇美拉队列类心得体会扩展 规则定义工作相关奇美拉相关 奇美拉属性 在本篇博文,我将介绍本项目的整体框架,以及“编码规则”,这些规则保证了本…...
Python实战:打造一个功能完整的单位转换器(长度/温度/货币)
📚 文章导读 在本文中,我将为大家介绍如何使用Python开发一个实用的单位转换器。这个项目不仅适合Python初学者练手,也能帮助你更好地理解Python的基础语法和函数设计。 🔍 主要特性 ✅ 支持多种长度单位互转(米、千…...
嵌入式学习笔记 D24 :系统编程之i/o操作
系统编程基本概念及一般组成文件的常见i/o操作 一、系统编程基本概念及一般组成 系统编程属于应用程序编程,即在操作系统运行成功的基础上执行程序。其一般包含以下四部分: 1)文件:存储在存储设备上的相关信息集合,是…...
利用朴素贝叶斯对UCI 的 mushroom 数据集进行分类
朴素贝叶斯(Naive Bayes)是一种基于贝叶斯定理的简单而有效的分类算法,特别适合处理文本分类和多类别分类问题。UCI的Mushroom数据集是一个经典的分类数据集,包含蘑菇的特征和类别(可食用或有毒)。 1. 数据…...
Index-AniSora模型论文速读:基于人工反馈的动漫视频生成
Aligning Anime Video Generation with Human Feedback 一、引言 论文开头指出,尽管视频生成模型不断涌现,但动漫视频生成面临动漫数据稀缺和运动模式异常的挑战,导致生成视频存在运动失真和闪烁伪影等问题,难以满足人类偏好。现…...
FineBI 和 Axure工具比较——数据分析VS原型设计
FineBI和Axure是两款定位截然不同的工具,分别服务于数据分析和原型设计领域。以下从核心功能、应用场景、操作门槛等维度进行对比分析: 一、核心功能对比 FineBI 作为商业智能(BI)工具,聚焦于数据整合、清洗、分析及可…...
跟踪AI峰会,给自己提出的两个问题。
踪红杉AI峰会全纪录:AI打开万亿美元市场,卖的不是工具,而是收益。 原文链接: 红杉AI峰会全记录:AI打开万亿美元市场,卖的不是工具,而是收益(全文)_腾讯新闻 自己的学习…...
分布式ID生成器:原理、对比与WorkerID实战
一、为什么需要分布式ID? 在微服务架构下,单机自增ID无法满足跨服务唯一性需求,且存在: • 单点瓶颈:数据库自增ID依赖单表写入 • 全局唯一性:跨服务生成可能重复 • 扩展性差:分库分表后ID规…...
AR 开启昆虫学习新视界,解锁奇妙微观宇宙
在传统昆虫学习中,课堂教学是主要方式,老师通过板书、PPT 传授知识,但学生被动接受,书本静态图片无法展现昆虫真实比例、立体形态,学生难以直观感受复杂身体结构。博物馆的昆虫标本也是学习途径,不过标本放…...
WPF技巧-常用的Converter集合(更新ing)
文章目录 [toc]🧩 示例 1:BooleanToVisibilityConverter🧩 示例 2:InvertedBooleanToVisibilityConverter🧩 示例 3:StringToColorConverter🧩 示例 4:StringToBrushConverter&#…...
PostGIS栅格数据类型解析【raster】
PostGIS 栅格数据类型解析:结构、转换与应用 一、栅格数据类型概述 在 PostGIS 中,raster 是用于存储和处理栅格数据的核心类型,支持从多种格式(如 JPEG、GeoTIFF、PNG、DEM)导入的数据。每个栅格由一个或多个波段&a…...
985,成立人工智能学院
5月17日,北京理工大学AI变革与科教创新论坛暨人工智能学院成立大会在中关村校区举行。 北京理工大学校长姜澜介绍了学校近年来高质量发展取得的成绩。他表示,北京理工大学对人工智能高度重视、提前布局,具备扎实基础。学校将通过“一零一一”…...
使用 ARCore 和 Kotlin 开发 Android 增强现实应用入门指南
环境准备 1. 工具与设备要求 Android Studio:Arctic Fox 或更高版本设备:支持 ARCore 的 Android 设备(查看支持列表)依赖库:// build.gradle (Module级) dependencies {implementation com.google.ar:core:1.35.0im…...
房贷利率计算前端小程序
利率计算前端小程序 视图效果展示如下: 在这里插入代码片 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&qu…...
剧本杀小程序:指尖上的沉浸式推理宇宙
在推理热潮席卷社交圈的当下,你是否渴望随时随地开启一场烧脑又刺激的冒险?我们的剧本杀小程序,就是你掌心的“推理魔法盒”,一键解锁无限精彩! 海量剧本库,满足多元口味:小程序汇聚了从古风权…...
shp2pgsql 导入 Shp 到 PostGIS 空间数据库
前言 ❝ shp2pgsql是PostGIS自带的命令行工具,用于将Shapefile文件声称SQL脚本导入到PostGIS空间数据库。 1. 安装 PostGIS 通过Application Stack Builder或者下载单独的PostGIS包进行安装。而shp2pgsql则是与PostGIS工具集成在一起,无需单独下载。该命…...
什么是 ERP、MES、PLM,生产制造中如何应用
生产制造领域数字化转型加速背景下,ERP、MES、PLM 系统的应用成为企业提升竞争力的关键。然而,部分企业因对三者功能认知模糊、系统搭配不当、实施流程缺失,导致生产计划混乱、库存失衡、质量管控失效等问题频发。明晰系统功能定位与协同逻辑…...
Android Edge-to-Edge
Android Edge-to-Edge显示:开发者综合指南 一、什么是Android Edge-to-Edge Android Edge-to-Edge是一种先进的用户界面(UI)设计理念,旨在最大化利用设备的显示区域。它允许应用程序的内容延伸至屏幕的各个边缘,包…...
Java期末总复习 编程题(偏基础)
71. ①编写一个含 2 个属性的类,并为其设计有参构造方法,再设计一个用于显示属性值的方法。②编写该类的一个子类,除继承父类的 2 个属性外再增加一个属性,并创建有参构造方法对 3个属性初始化,重写显示属性的方法用于…...
进阶知识:自动化框架开发之有参的函数装饰器@wraps()和无参之间的对比
进阶知识:自动化框架开发之有参的函数装饰器wraps() 一、核心代码解析 1.1 有参装饰器结构 def func_3(argTrue): # 外层接收参数def inner_func(func): # 中间层接收被装饰函数wraps(func) # 保留元信息def wrap_func(*args, **kwargs): …...
es疑惑解读
好的,没问题。下面是我们对话中关于 Elasticsearch 数据库的知识点汇总,以问答对的形式呈现,希望能成为一个清晰的教程。 Elasticsearch 基础与 CRUD 操作 Q1: 我有 pymysql 的使用经验,想学习 Elasticsearch (ES) 的增删改查&am…...
Elasticsearch面试题带答案
Elasticsearch面试题带答案 Elasticsearch面试题及答案【最新版】Elasticsearch高级面试题大全(2025版),发现网上很多Elasticsearch面试题及答案整理都没有答案,所以花了很长时间搜集,本套Elasticsearch面试题大全,Elasticsearch面试题大汇总,有大量经典的Elasticsearch面…...
Linux 的 TCP 网络编程 -- 回显服务器,翻译服务器
目录 1. 相关函数介绍 1.1 listen() 1.2 accept() 1.3 connect() 2. TCP 回显服务器 2.1 Common.hpp 2.2 InetAddr.hpp 2.3 TcpClient.cc 2.4 TcpServer.hpp 2.5 TcpServer.cc 2.6 demo 测试 3. TCP 翻译服务器 3.1 demo 测试 1. 相关函数介绍 其中一些函数在之前…...
差动讯号(2):奇模与偶模
我们经常在探讨差动对时经常听到差模(Differential mode)与共模(Common mode),究竟什么是差模? 什么是共模? 这一切就要从奇模(Odd mode)与偶模(Even mode&am…...
口腔牙科小程序源码介绍
基于ThinkPHP、FastAdmin以及UniApp开发的口腔牙科小程序源码,专为口腔牙科行业设计,旨在提供一个便捷、高效的线上服务平台。 从技术层面看,这套源码结合了ThinkPHP的强大后端功能、FastAdmin的快速开发特性以及UniApp的跨平台优势…...
云计算与大数据进阶 | 27、存储系统如何突破容量天花板?可扩展架构的核心技术与实践—— 分布式、弹性扩展、高可用的底层逻辑(上)
数据中心里,存储系统是至关重要的组成部分。由于相关硬件组件与存储操作系统的多样性和复杂性,如何在保证存储稳定、安全、可靠的同时,实现灵活扩展和自服务,一直是困扰数据中心全面云化的难题。 简单来说,现在的难题…...
企业级物理服务器选型指南 - 网络架构优化篇
在分布式系统架构中,物理服务器的网络质量直接影响业务连续性。本文将通过真实场景演示如何选择符合业务特性的物理服务器。 一、网络拓扑设计原则 当企业需要覆盖多地域用户时,建议采用混合组网方案: # 网络质量检测脚本(Pytho…...
可视化图解算法42:寻找峰值
牛客网 面试笔试TOP101 | LeetCode 162. 寻找峰值 1. 题目 描述 给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。 1.峰值元素是指其值严格大…...
java每日精进 5.20【MyBatis 联表分页查询】
1. MyBatis XML 实现分页查询 1.1 实现方式 MyBatis XML 是一种传统的 MyBatis 使用方式,通过在 XML 文件中编写 SQL 语句,并结合 Mapper 接口和 Service 层实现分页查询。分页需要手动编写两条 SQL 语句:一条查询分页数据列表,…...
瀚高安全版4.5.8/4.5.9字符串默认按字节存储导致数据无法写入(APP)
文章目录 环境文档用途详细信息 环境 系统平台:Linux x86-64 Red Hat Enterprise Linux 7 版本:4.5 文档用途 解决安全版4.5.8/4.5.9字符串默认使用字节存储导致插入时提示数据超长。 详细信息 使用sysdba用户执行,重载配置或重启数据库…...
python新手学习笔记①
本笔记是根据Bilibili里的【3小时超快速入门Python | 动画教学【2025新版】【自学Python教程】【零基础Python】【计算机二级Python】【Python期末速成】】 https://www.bilibili.com/video/BV1Jgf6YvE8e/这个视频合集制作的代码笔记! 1.字符串连接 运行结果 2.…...
用于管理共享内存的 C# 类 ShareMemory
可以在 Windows 和 Linux 上运行,利用了 .NET Core 的 System.IO.MemoryMappedFiles 库。这个类实现了共享内存的创建、打开、读取和写入功能。以下是对代码的一些分析和建议改进。 代码分析 初始化与打开共享内存: Init 方法用于创建新的共享内存段。OpenMem 方法…...
arcgispro双击打开没反应怎么办
不知道什么原因,突然就打不开了,网上关于arcgispro的教程和求助帖还比较少,参考了几个博主的分享,还是没解决 Arcpro——arcpro启动无反应_arcgispro正在初始化后没反应-CSDN博客 Arcgis Pro安装完成后启动失败的解决办法_arcgi…...
常见高速电路设计与信号完整性核心概念
一、传输线理论(Transmission Line Theory) 基本定义 当信号频率或边沿速率足够高时,互连线的长度与信号波长可比拟(通常为信号上升时间的1/6以上),此时需将互连视为传输线,而非理想导线。 临界…...
青少年编程与数学 02-019 Rust 编程基础 20课题、面向对象
青少年编程与数学 02-019 Rust 编程基础 20课题、面向对象 一、面向对象的编程特性(一)封装(Encapsulation)(二)多态(Polymorphism)(三)继承(Inhe…...
<uniapp><vuex><状态管理>在uniapp中,如何使用vuex实现数据共享与传递?
前言 本专栏是基于uniapp实现手机端各种小功能的程序,并且基于各种通讯协议如http、websocekt等,实现手机端作为客户端(或者是手持机、PDA等),与服务端进行数据通讯的实例开发。 发文平台 CSDN 环境配置 系统&…...
如何使用通义灵码辅助开发鸿蒙OS - AI编程助手提升效率
一、引言 鸿蒙 OS 是华为推出的一款面向全场景的分布式操作系统,其开发应用主要使用华为基于 IntelliJ IDEA 定制的 DevEco Studio。然而,DevEco Studio 的插件生态相对有限,为了提升开发效率和代码质量,我们可以借助通义灵码这一…...
解决git中断显示中文为八进制编码问题
git config --global core.quotepath false 命令用于配置 Git 如何处理非 ASCII 字符(如中文、日文、韩文等)的文件名显示 core.quotepath Git 的一个核心配置项,控制是否对非 ASCII 文件名进行转义(quote)处理。 f…...
宿州金博学校开展防震演练:夯实安全根基,守护校园平安
5月13日上午9点30分,金博学校原本宁静的校园被一阵急促的警报声打破,一场精心筹备、紧张有序的防震演练正式开启。本次演练意义重大,旨在强化全体师生的防震减灾意识,提高大家在地震突发时的应急反应与自我保护能力。 紧急避险&am…...
【鸿蒙开发】安全
应用隐私保护最佳实践 使用隐私声明获取用户同意 初次访问使用隐私声明弹窗,只有用户同意后才能开始正常使用。 减少应用的位置访问权限 使用模糊定位获取位置信息 位置权限申请方式 target API level申请位置权限申请结果位置的精确度小于9ohos.permission.L…...
企业级网络安全护盾:剖析高防IP原理与防护策略
在当今数字化时代,网络安全已成为企业不可忽视的关键课题。高防IP作为网络安全防护的重要手段之一,正因其出色的防御能力和应用灵活性受到广泛关注。本文将深入解析高防IP的原理,包括流量清洗、防御策略、节点分布等技术要点,并通…...
智能事件分析边缘服务器:交通管理与安全监测的利器
在当今交通管理和安全监测的领域中,智能化、高效化的设备需求日益增长。智能事件分析边缘服务器凭借其卓越的性能和丰富的功能,成为了该领域的佼佼者。 一、产品概述 智能事件分析边缘服务器是一款采用嵌入式 Linux 操作系统的边缘事件分析终端。它具有…...
Gin--Blog项目-flags文件解析
flags/enter.go文件解析 package flagsimport ("flag""os" )type Options struct {File stringDB boolVersion bool }var FlagOptions new(Options)func Parse() {flag.StringVar(&FlagOptions.File, "f", "settings.yaml&qu…...
JVM的面试相关问题
面试中的相关问题主要是三块 1.JVM 内存区域划分 2.JVM 的类加载机制 3.JVM 的垃圾回收机制 JVM Java虚拟机 VM Virtual Machine 虚拟机,用 软件 来 模拟 硬件 传统意义上的"虚拟机" 更多指的是 VMWare, Virtual Box, Hyper-V, KVM(构造出虚拟的电脑,甚至可以…...
Linux(3)——基础开发工具
一、软件包管理器——yum 1.Linux下安装程序的方式 在Linux环境下安装软件的方式有以下几个方式: 1)源码安装,直接下载源代码,让它自行编译运行形成可执行程序。 2)软件包安装,下载rpm安装包࿰…...
HarmonyOS5云服务技术分享--ArkTS调用函数
✨【HarmonyOS实战指南】手把手教你用ArkTS玩转云函数文件获取✨ 大家好呀今天我们来聊聊如何通过HarmonyOS的ArkTS语言实现云函数文件获取功能。整个过程就像搭积木一样有趣,保证小白也能轻松上手!(文末有完整代码模板哦) &…...
2025年AI搜索引擎发展洞察:技术革新与市场变革
引言:AI搜索的崛起与市场格局重塑 2024-2025年,AI搜索市场迎来了前所未有的变革期。随着DeepSeek-R1等先进大语言模型的推出,传统搜索引擎、AI原生搜索平台以及各类内容平台纷纷加速智能化转型,推动搜索技术从基础信息检索向深度…...
基于开源链动2+1模式AI智能名片S2B2C商城小程序的社群构建与新型消费迎合策略研究
摘要:随着个性化与小众化消费的崛起,消费者消费心理和模式发生巨大变化,社群构建对商家迎合新型消费特点、融入市场经济发展至关重要。开源链动21模式AI智能名片S2B2C商城小程序的出现,为社群构建提供了创新工具。本文探讨该小程序…...
leetcode 旋转数组 java
本来想用栈或者队列来解决,发现一直报k>nums.length的错。 将原数组下标为 i 的元素放至新数组下标为 (ik)modn 的位置,最后将新数组拷贝至原数组即可。 class Solution {public void rotate(int[] nums, int k) {// Stack<Integer> stack n…...
Ansible模块——通过 URL 下载文件
通过 URL 下载文件 ansible.builtin.get_url 可以通过 URL 下载文件。 选项名 类型 默认值 描述 attributesstrnull 设置文件系统对象的属性,格式参考 lsattr;支持 , -, 操作符。别名:attr。 backupboolfalse 创建目标文件的备份副本&am…...