使用哈希查找有两个步骤: 使用哈希函数将被查找的键转换为数组的索引:在理想的情况下,不同的键会被转换为不同的索引值,但是在有些情况下我们需要处理多个键被哈希到同一个索引值的情况。...在使用了上述线性探查法的情况下,则 7 和 8 在存储的时候,因为两者哈希后得到的索引一致,并且 7 已经存到了哈希表中,哪么 8 在找到索引 4 的时候会发现已经有值了,则它继续开始往后查找,此时找到索引为...但我们这里的代码是 map.get(k2),当我们调用Object类的 hashCode方法(因为 HashMapKey 里没定义)计算 k2 的 hash值时,其实得到的是 k2 的内存地址(假设是...但 k1 有可能仅仅是和 k2 具有相同的 hash值,但未必和 k2 相等,这个时候,就需要调用 HashMapKey 对象的 equals 方法来判断两者是否相等了。...由于我们在 HashMapKey 对象里没有定义 equals 方法,系统就不得不调用 Object 类的 equals 方法,同理由于 Object 的固有方法是根据两个对象的内存地址来判断,所以 k1
一、指针 首先先说一下指针: 弄懂指针对以后编程效率有大大滴帮助,大学第一个编程语言C语言,两节C语言指针我一直记忆犹新。...云里雾里,那时候我就知道指针是个好东西,但我控制不住它,它会给我惹好多麻烦。 指针是其实也是一个对象,它指向一个内存地址单元,内存单元里存着各种变量。...指针就像风筝的线,如果这个指针不指向了这个内存地址,风筝就会飞走了,内存地址就会被存储器干掉。 弱引用:指针指向内存地址,但并没有共存亡的关系。...3.strong与weak strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示在列表中,则此对象会被从内存中释放。...对copy属性要特别注意:被定义有copy属性的对象必须要 符合NSCopying协议,必须实现- (id)copyWithZone:(NSZone *)zone方法。
示例程序 这里构建一个简单的示例来进行实际演示。...这也是我用了很久的一个方法,不过后来我知道了有更官方的解决方式: set follow-fork-mode child catch exec 囧,…… Catch Point真是个好东西,支持很多有用的事件...通常设置为step模式可解决单步调试的问题。 程序运行 我经常用到的一个功能是需要使用 gdb 执行某个程序,并且能精确控制程序的参数,包括命令行、标准输入和环境变量等。...比如下面的截图就是我曾经用 gdb + OpenOCD 来调试 ESP32固件的示例: Xtensa指令集调试 ESP32是比较少见的Xtensa指令集架构,上面的拓展都不支持,不过 gdb 本身支持...附录: gdb命令表 gdb 还有其他一些小技巧,可以参考awesome-cheatsheets/tools/gdb.txt中的列表。该列表最初由韦神创建,我时不时也会添加一些上去。
我们再来观察Hash表(这里的Hash表纯粹是数据结构上的概念,和Java无关)。它的平均查找次数接近于1,代价相当小,关键是在Hash表里,存放在其中的数据和它的存储位置是用Hash函数关联的。...但我们这里的代码是hm.get(k2),当我们调用Object类的hashCode方法(因为Key里没定义)计算k2的hash值时,其实得到的是k2的内存地址(假设是2000)。...存k1时,是根据它id的hash值,假设这里是100,把k1对象放入到对应的位置。而取k2时,是先计算它的hash值(由于k2的id也是1,这个值也是100),随后到这个位置去找。...但k1有可能仅仅是和k2具有相同的hash值,但未必和k2相等(k1和k2两把钥匙未必能开同一扇门),这个时候,就需要调用Key对象的equals方法来判断两者是否相等了。...由于Object的固有方法是根据两个对象的内存地址来判断,所以k1和k2一定不会相等,这就是为什么依然在26行通过hm.get(k2)依然得到null的原因。
但我们这里的代码是hm.get(k2),当我们调用Object类的hashCode方法(因为Key里没定义)计算k2的hash值时,其实得到的是k2的内存地址(假设是2000)。...而取k2时,是先计算它的hash值(由于k2的id也是1,这个值也是100),随后到这个位置去找。 但结果会出乎我们意料:明明100号位置已经有k1,但第26行的输出结果依然是null。...但k1有可能仅仅是和k2具有相同的hash值,但未必和k2相等(k1和k2两把钥匙未必能开同一扇门),这个时候,就需要调用Key对象的equals方法来判断两者是否相等了。...由于Object的固有方法是根据两个对象的内存地址来判断,所以k1和k2一定不会相等,这就是为什么依然在26行通过hm.get(k2)依然得到null的原因。...为了解决这个问题,我们需要打开第9到14行equals方法的注释。在这个方法里,只要两个对象都是Key类型,而且它们的id相等,它们就相等。
这可能是由于: 试图解引用空指针(你不被允许访问内存地址 0);◈ 试图解引用其他一些不在你内存(LCTT 译注:指不在合法的内存地址区间内)中的指针;◈ 一个已被破坏并且指向错误的地方的 C++ 虚表指针...这个“C++ 虚表指针”是我的程序发生段错误的情况。我可能会在未来的博客中解释这个,因为我最初并不知道任何关于 C++ 的知识,并且这种虚表查找导致程序段错误的情况也是我所不了解的。...但我想也希望做一个更深入调查,并找出些 valgrind 没告诉我的信息! 所以我想获得一个核心转储并探索它。...这个博客听起来很多,当我做这些的时候很困惑,但说真的,从一个段错误的程序中获得一个堆栈调用序列不需要那么多步骤: ☉ 试试用 valgrind 如果那没用,或者你想要拿到一个核心转储来调查: ☉ 确保二进制文件编译时带有调试符号信息...我可以使用 gdb 弄清楚有个 C++ 的虚表条目指向一些被破坏的内存,这有点帮助,并且使我感觉好像更懂了 C++ 一点。也许有一天我们会更多地讨论如何使用 gdb 来查找问题!
为了庆祝 SQL 的 50 岁生日,让我们来讨论一下表,并在需要时引入技术术语。但是,我不想仅仅 针对现有表测试查询。关系数据库 的世界始于 Schema。...这只是将表缝合在一起的一种方式,以便我们可以挑选出需要显示的信息,同时保持 Schema 不变。...我将使用 Llama 3,但我还查看了 OpenAI 的 LLM,并得到了大致相同的结果。 我们的第一个查询:“创建一个关系数据库模式来描述书籍、出版商和作者。” 结果: 到目前为止还不错。...它尚未创建 DDL,但我们可以单独询问。它在某种程度上做得更好,用英语描述了模式。我们来看看回复的其余部分: 它描述了外键约束并添加了 ISBN,这是我没想到的。...最后,我们来问一个视图: 这比我的版本复杂多了;不过,当我调整到我的模式命名时,在 DB Fiddle 中运行得很好。此处看到的表别名命名对于理解没有什么帮助。
当然,解决所有这些谜题需要额外的知识,而不仅仅是类和实例,我将在接下来的讨论中澄清这一点。如果你对这两个概念都很了解,你可以跳过下一段,这段只是对这两个概念的简要概述。...在上面的代码中,我们修改了greet()函数,要求它使用内省id()函数向我们显示self参数的内存地址。...如您所见,self参数和实例student是同一个对象,因为它们具有相同的内存地址。 ? 2. 为什么不需要在函数调用中设置它呢? ?...对于感兴趣的读者,这里有几件事要知道,可以帮助你更深入地了解这个谜。当创建一个Python类时,它声明的函数就是这个类的属性(称为函数对象)。换句话说,类“拥有”这些函数。...对类和静态方法的清晰解释将是以后文章的主题。但我在这里可以展示的是,当我们声明一个类方法时,函数确实有一些类似于在实例方法中使用self的东西,它通常被称为cls,引用类对象本身。它与具体实例无关。
您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列。...前文普及了OllyDbg的基础用法和CrakeMe案例;这篇文章将详细讲解OllyDbg和Cheat Engine工具逆向分析用法,完成植物大战僵尸的游戏辅助器,包括修改阳光值和自动拾取阳光两个功能,希望对入门的同学有帮助...基础性文章,希望对您有所帮助,作者的目的是与安全人共同进步,加油~ 文章目录 一.VS内存地址查看 二.Cheat Engine逆向修改阳光值 三.OllyDbg逆向自动拾取阳光 四.总结及学习推荐 作者的...---- 一.VS内存地址查看 在讲解OllyDbg和Cheat Engine工具逆向分析游戏之前,我想先给大家普及下内存地址的基础概念,以及通过创建项目来讲解下内存、地址、值它们的关系。...显示结果如下图所示,这里获取了植物大战僵尸的进程ID。 PID:3256 原理搞懂之后,接下来就需要编写代码完成阳光值的修改。
但是 12 字节不是Bucket的有效大小,因为它需要是 8 字节的倍数(结构的最大成员的大小)。...在未来英特尔的第 5 级分页提案(白皮书)中,它计划在 x86 上放宽对 57 位的限制,这意味着我们可以使用最重要的 7 位——即 58 到 64 位——来存储额外的数据。...分离哈希的另一个优点是现在不需要打包Bucket 。 实验评价: 我们对该技术进行了广泛的评估,以了解它如何影响性能和内存利用率。...sales有s_item_id (int)、s_quantity(int) 、s_date(date)列,而items有i_item_id (int)和i_price (double)列。...sales有 10 亿行,items有 3000 万行。 建立基准 我们对销售额进行了 Group By 查询,以测量构建哈希表的性能和内存。
假设我们将城市的表,起名为City,它通常包含类似这样的字段: Id Int Identity(1,1) 城市Id Name Varchar(50) 城市名称 ZIP...假设我们有代表酒店订单的HotelOrder表,它包含代表状态的StatusId字段,我们的查询可能会像这样:Select *, (Select Status From BookingStatus Where...我们先看它解决了什么:上面提到的问题1、问题2都解决了,既不需要在数据库中创建表,又无需连接到数据库进行查询。...实际上,.Net 中提供了 Type类 和 System.Reflection命名空间来帮助解决我们现在的问题。...我在后面将较详细地介绍 Type类,现在只希望你能对反射有个第一印象,所以只简略地作以说明:Type抽象类提供了访问类型元数据的能力,当你实例化了一个Type对象后,你可以通过它的属性和方法,获取类型的元数据信息
int main() { printf("我是一个进程:pid:%d,ppid:%d\n",getpid(),getppid()); pid_t id = fork(); if(id==0)...虽然我们知道我们取到的地址不是物理内存地址,而是虚拟内存地址,中间是通过一层映射关系来将虚拟内存地址转化为物理内存地址的,那中间到底是怎么做到的,其实在这中间起着关键作用的,有一个内核数据结构叫做页表。...页表 什么是页表: 页表是操作系统内核用来管理虚拟地址和物理地址之间映射的一个数据结构。它的核心作用是支持虚拟内存,使得每个进程可以在自己的独立虚拟地址空间中运行,增强了内存隔离和安全性。...我们new或者malloc出来的空间也是虚拟内存,有一个问题就来了,结构体就那么大,但是堆区是动态的,那他是如何实现动态开辟的呢,刚刚我们提到了mm_struct有一段区域是存储begin和end的,我们只需要改变...掌握程序地址空间的布局不仅能帮助我们理解进程的内存使用,还能为调试、性能优化和内存管理打下坚实基础。
这篇文章比较特殊,是一篇穿插答疑文章,由于刚好在前一篇教程《驱动开发:内核枚举PspCidTable句柄表》整理了枚举句柄表的知识点,正好这个知识点能解决一个问题,事情是这样的有一个粉丝求助了一个问题,...图片首先因为我的人生经历比较特殊,我经历过无法求知的困境,深知一个人在没有任何人指点的情况下去研究技术是多么的折磨人,所以在某些情况下只要你关注了我,我也会尽自己最大可能去帮助大家,即便是当时没有解决这个问题我也会记下来...图片然后干脆就直接枚举出整个系统所有的进程与线程信息,例如上一篇文章中提到的枚举句柄表,打开ARK工具找到所需查询的线程,会发现他有一个ETHREAD结构。...你或许灵机一动,我直接得到ETHREAD信息,从里面找EPROCESS,再从里面找进程名,但跟到最后你会发现它显示的是SYSTEM进程,如果继续往下就是内核了,小丑竟是你自己。...if (PsLookupThreadByThreadId(i_id, &p_ethread) == STATUS_SUCCESS){//DbgPrint("线程TID: %d | ID: %d | 内存地址
你并不需要有C语言的基础(我们会总结一些基础),但如果有的话会更有帮助。 这是这个系列的第一篇文章。在这篇文章,我们会谈论PHP程序的基础:在哪里找到它,基本的代码结构和一些最基础的C语言概念。...我们可以下载它,然后导入到一个好的IDE中,在这些IDE中我们可以点击跳到函数的定义和声明,当我发现这比想象中略困难。我有一个更好的解决方案。...一旦定义之后,你不能改变它的类型(你可以在之后转换成其他类型,但你 需要使用不同的变量来实现)。因为,在C语言里面,变量并不真实地存在。它们只是为了我们使用的方便的内存地址的标签。...现在,另一个理解指针的事情是它们是如何在C的数组里应用的(不是PHP的数组,而是C语言中的数组)。因为指针是内存地址,我们可以通过分配一块的内存来 定义一个数组,然后通过递增指针来遍历它。...然后,我们可以递增指针(增 加它的内存地址)来遍历整个字符串。
我将这个问题转发给了我的首席助手 ChatGPT,它给出了以下回答: ChatGPT: 您的 SQL 脚本基本没有问题,但是最后的查询语句中联结表的方式有点问题。...对于 did 表中没有的组合(如您示例中的 Bob 和“clean”),会显示 0 次。...执行查询: 我将运行更正后的查询,以显示它如何处理人和工作的组合,包括一个人没有工作记录的情况。...这展示了人员和工作表的笛卡尔积,创建了每个人与每个工作的组合,而不考虑他们是否实际上做过这份工作。 规则7:通过实践学习 现在这里有一个尴尬的坦白。...学生需要检查生成的代码,然后(在LLM的帮助下!)解释为什么需要 cross join 以及它是如何起作用的。 一些老师现在可能愿意并能够采用这种全新的方法。
简单来说:通过explain命令我们可以学习到该条SQL是如何执行的,随后解析explain的结果可以帮助我们使用更好的索引,最终来优化它!...通过explain命令我们可以知道以下信息:表的读取顺序,数据读取操作的类型,哪些索引可以使用,哪些索引实际使用了,表之间的引用,每张表有多少行被优化器查询等信息。...在id列上也会有几种情况: 如果id相同执行顺序由上至下。 如果id不相同,id的序号会递增,id值越大优先级越高,越先被执行。 (一般有子查询的SQL语句id就会不同) ?...NULL:在执行阶段不需要访问表。 1.3.5possible_keys 这一列显示查询可能使用哪些索引来查找 1.3.6key 这一列显示MySQL实际决定使用的索引。...当然了,在《高性能MySQL》中也有复杂的SQL语句来分析(但我认为我们一般不会写到那么复杂)..
希望对入门的同学有帮助,作者的目的是与安全人共同进步,加油~ 文章目录: 一.VS内存地址查看 二.Cheat Engine逆向修改阳光值 三.OllyDbg逆向自动拾取阳光 四.总结及学习推荐 作者逆向...(参考文献见后) 一.VS内存地址查看 在讲解OllyDbg和Cheat Engine工具逆向分析游戏之前,我想先给大家普及下内存地址的基础概念,以及通过创建项目来讲解下内存、地址、值它们的关系。...E8 03 00 00 注意这里仅显示了一个字节,我们如果右键选中转换为4字节,则可以显示完整的数值,如下图所示。...显示结果如下图所示,这里获取了植物大战僵尸的进程ID。 PID:3256 原理搞懂之后,接下来就需要编写代码完成阳光值的修改。...我们终于可以愉快的玩耍了,妈妈再也不用担心我的阳光!
领取专属 10元无门槛券
手把手带您无忧上云