前言 应用场景:签名函数,把函数名隐藏在结构体里,以函数指针成员的形式存储来进行敏感逻辑的保护。 为了提高代码的安全性,可以采用把把函数名隐藏在结构体里,以函数指针成员的形式存储。...static __attribute__((always_inline)) void anti_debug() //一般的函数调用都会通过call的方式来调用,hacker很容易对一个函数做手脚,如果是以...mainWindow.safeAreaInsets.bottom > 0.0) { return YES; } } return NO; } 1.2 把函数名隐藏在结构体里,以函数指针成员的形式存储...,以函数指针成员的形式存储。...,防止产生参数遍历获取信息风险 iOS敏感逻辑的保护方案:【把函数名隐藏在结构体里,以函数指针成员的形式存储】 敏感信息需要展示在web页面上时,应在后台进行敏感字段脱敏处理 身份证、银行卡号 姓名 预留手机号
redis本身是开源的C语言编写的k-v存储系统,他支持String、List、Set、ZSet、hash五种数据结构,每种数据结构底层是如何实现的?其数据结构为什么? 1....String 1.1 结论 底层结构:指针+字符数组 时间复杂度:O(1) 1.2 表格 1.3 底层原理 Redis是C语言开发的,但在C语言中并没有字符串类型,只能使用指针和字符数组的形式来保存一个字符串...char buf[]; } 获取字符串长度的时间复杂的为O(1),因为len保存的是当前字符串长度。...一个普通的双向链表,链表中每一项都占用独立的一块内存,各项之间用地址指针(或引用)连接起来,但是这种方式会造成大量的内存碎片,而且地址指针也会占用额外的内存。...ziplist却是将表中每一项存放在前后连续的地址空间内,一个ziplist整体占用一大块内存。
,因此「每次获取字符串的长度都会遍历得到,时间的复杂度是O(n)」,而Redis中获取字符串只要读取len的值就可,时间复杂度变为O(1)。...(2)「c语言」中两个字符串拼接,若是没有分配足够长度的内存空间就「会出现缓冲区溢出的情况」;而「SDS」会先根据len属性判断空间是否满足要求,若是空间不够,就会进行相应的空间扩展,所以「不会出现缓冲区溢出的情况...Hash类型 Hash对象的实现方式有两种分别是ziplist、hashtable,其中hashtable的存储方式key是String类型的,value也是以key value的形式进行存储。...渐进式rehash 假如在rehash的过程中数据量非常大,Redis不是一次性把全部数据rehash成功,这样会导致Redis对外服务停止,Redis内部为了处理这种情况采用「渐进式的rehash」。...压缩列表是列表键和哈希键底层实现的原理之一,「压缩列表并不是以某种压缩算法进行压缩存储数据,而是它表示一组连续的内存空间的使用,节省空间」,压缩列表的内存结构图如下: ?
PS:事实上以上的方法都有各自的优点,可是详细操作还是得依据实际情况而定。...大家都知道移动互联网如今非常红火,那么在这个移动当头的年代。移动安全也是一个非常大的问题。 当中就包括移动端接口的数据安全问题。...适合传输数据採用json/xml形式的接口。...原理和web 端一样 方法二: 假如是移动端的话: 1、你随便定义一个特定的密匙(比方:成佩涛黑客),移动端这边採用加密算法加密该字符串并作为參数传递到后台接口去...2、后台採取相同的算法进行解密或加密之后进行匹配字符串,如果匹配成功则进行查询 PS:事实上以上的方法仅仅是參考方案:原理主要是通过密匙传递,是否能被破解
但是在内核下忽略返回值是一个非常危险的情况,应该避免这样的情况出现,所以内核编程中有一点千万记住,就是 始终检查内核API返回值 1.4 IRQL 中断请求级别 IRQL在内核开发中是一个非常重要的概念...在内核中C++用得比较少,但是有一些使用资源的用法较弱( Resource Acquisition Is Initialization 资源获取即初始化)RALL用法很常用,可以防止资源泄露。...大部分情况下内核采用unicode指针的形式来使用字符串(wchar_t* 或者WCHAR)但是很多函数期待用UNICODE_STRING。...PCUNICODE_STRING; UNICODE_STRING是以字节而不是字符为单位,并且不包括UNICODE-NULL终结符,如果终结符存在,则MaximumLength是字符串可以增长到的最大字节数...而符号对象在内核模式下是以 \??\或者是\DosDevices\开头的比如前面例子里的:\Device\test。在User模式下就是以 \.\开头的比如说 ”\.\C: “。
Xposed是一个使用root权限的安卓框架,它是以模块的形式对系统或应用程序的核心组件进行替换,从而达到修改系统行为的目的。...54.inline hook和got hook原理,如何检测?inline hook跳板设计,多次跳转情况?...67.设备指纹生成会遇到的问题,异常情况如何解决?1.如果在获取设备指纹的过程中出现网络问题,可以采用重试机制,即在设定的时间内重复尝试获取设备指纹。...如何进行防护?如何进行对抗?还有哪些抓包方式?非root环境可以抓包嘛?说说方案?现有的一些最难的抓包情况是怎么样的?...2、采用混淆算法的抓包:采用混淆算法可以把客户端与服务端之间的数据流量进行混淆,使中间人抓包无从下手,这种抓包情况也是比较难的。86.flutter有了解么?遇到这种情况怎么进行抓包?
String String 一般用于存储 key-value的情况,也是比较常用的数据结构。 比如文章阅读数,点赞数,粉丝数量统计等。...hashtable key是string类型,value是key-value形式存储。...hashtable和hashmap原理类似,新增key时先计算key的数组下标,hashmap是以hash函数方式计算,hashtable是通过sizemask属性和哈希值再次计算得到下标。...redis链表的特点: 每个节点都有指向前一个节点和后一个节点的指针。 头节点和尾节点的prev和next指针指向为null,所以链表是无环的。...生产者使用lpush从队列左侧插入数据,消费者使用brpop从队列右侧获取数据进行消费。 所以类似于队列这种场景可以考虑采用list。
堆溢出攻击:攻击者利用程序中堆的分配方式中存在的漏洞,向堆中写入恶意代码,从而控制程序的执行流程。格式化字符串攻击:利用程序对格式化字符串的处理不当,向内存中写入恶意代码。...为了防止这种攻击,可以在堆上实施堆随机化(heap randomization)和地址空间随机化(ASLR)等技术。堆随机化可以使恶意代码难以找到并利用堆中的内存地址,从而增加攻击者的难度。...如何绕过该保护为了绕过SEHOP保护机制,突破方法就是进一步伪造SEH链,该方法的核心是能够找到合适的跳板指令,且伪造最终异常处理函数指针应该与真实的相同,伪造最终异常处理函数指针前4字节(SEH链指针...该技术通常通过在操作系统内核中实现,对每个进程都使用不同的随机偏移量来布局内存空间,防止攻击者利用事先获取到的内存地址来进行攻击。...这种保护机制可以有效地防止攻击者利用缓冲区溢出等漏洞来执行恶意代码,从而提高系统的安全性。
const修饰字符串常量:字符串常量位于文字常量区(也有文章归类于代码区),本身就不允许被修改,如果没有const的修饰,我们可能会在后面有意无意的修改字符串常量,这样会导致对只读内存区域的赋值,然后程序会立刻异常终止...//第三种 const int* const p4; //p本身是const的,而p指向的变量也是const 是以上两种的结合,指针指向的位置不能改变并且也不能通过这个指针改变变量的值,...因此,有三种情况可讨论: 1、函数参数为值传递: 值传递(pass-by-value)是传递一份参数的拷贝给函数,因此不论函数体代码如何运行,也只会修改拷贝而无法修改原始对象,这种情况不需要将参数声明为...根据上面对指针常量、常量指针等讨论,同样分为三种情况: 2.1 防止修改指针指向的内容 典型C库函数:char *strcpy(char *dest, const char *src); 2.2 防止修改指针指向的地址...2.3 防止修改指针指向的内容和地址 4.修饰函数的返回值 1、如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。
堆溢出攻击:攻击者利用程序中堆的分配方式中存在的漏洞,向堆中写入恶意代码,从而控制程序的执行流程。 格式化字符串攻击:利用程序对格式化字符串的处理不当,向内存中写入恶意代码。...为了防止这种攻击,可以在堆上实施堆随机化(heap randomization)和地址空间随机化(ASLR)等技术。堆随机化可以使恶意代码难以找到并利用堆中的内存地址,从而增加攻击者的难度。...如何绕过该保护 为了绕过SEHOP保护机制,突破方法就是进一步伪造SEH链,该方法的核心是能够找到合适的跳板指令,且伪造最终异常处理函数指针应该与真实的相同,伪造最终异常处理函数指针前4字节(SEH链指针...该技术通常通过在操作系统内核中实现,对每个进程都使用不同的随机偏移量来布局内存空间,防止攻击者利用事先获取到的内存地址来进行攻击。...这种保护机制可以有效地防止攻击者利用缓冲区溢出等漏洞来执行恶意代码,从而提高系统的安全性。
1.6.2.1 MySQL 索引重点 1.索引的原理、类型和结构 2.创建索引的注意事项,使用原则 3.如何排查和消除慢查询 1.6.2.2什么是索引 索引就是数据表中一个或者多个列进行排序的数据结构。...第一是只在叶子节点带有指向记录的指针(为什么?因为可以增加树的度)。第二就是叶子节点通过指针相连,为什么?因为可以实现范围查询。...如果大家对搜索引擎的搜索原理比较了解的话,会明白全文索引一般是通过倒排索引的形式实现的。 1.6.2.6什么时候创建索引 我们在建表的时候需要根据查询需求来创建索引。...尤其是枚举,一共才几个值,创建什么索引,完全没有必要~ 3.索引的长度不要太长(比较耗费时间) 作为索引在 B + Tree 中是以 key 的形式存在,为什么主键的索引要使用自增的 int 值呢?...(这种情况无法用到联合索引) 注意:总结为一句话就是当 B + Tree 的 key 没有办法直接比较的情况下,索引会失效。
当我们开发Windows应用程序时,通常会涉及到使用资源(Resource)的情况。资源可以包括图标、位图、字符串等,它们以二进制形式嵌入到可执行文件中。...在某些情况下,我们可能需要从可执行文件中提取自定义资源并保存为独立的文件。在这篇博客文章中,我们将讨论如何使用C++和WinAPI实现这个目标。...如果为 NULL,则返回调用线程的可执行模块句柄。 在许多情况下,GetModuleHandle 主要用于获取当前进程的模块句柄,以便在后续的操作中使用该句柄。...LockResource 用于获取指定资源的数据指针。它接受一个全局内存块的句柄,该内存块通常由 LoadResource 函数返回,然后返回一个指向资源数据的指针。...这种技术在一些特殊情况下可能会很有用,例如需要动态加载或替换资源的情况。希望这篇博客对你理解如何使用 C++ 和 Windows API 进行资源操作有所帮助。
当我们开发Windows应用程序时,通常会涉及到使用资源(Resource)的情况。资源可以包括图标、位图、字符串等,它们以二进制形式嵌入到可执行文件中。...在某些情况下,我们可能需要从可执行文件中提取自定义资源并保存为独立的文件。在这篇博客文章中,我们将讨论如何使用C++和WinAPI实现这个目标。...如果为 NULL,则返回调用线程的可执行模块句柄。在许多情况下,GetModuleHandle 主要用于获取当前进程的模块句柄,以便在后续的操作中使用该句柄。...LockResource用于获取指定资源的数据指针。它接受一个全局内存块的句柄,该内存块通常由 LoadResource 函数返回,然后返回一个指向资源数据的指针。...这种技术在一些特殊情况下可能会很有用,例如需要动态加载或替换资源的情况。希望这篇博客对你理解如何使用 C++ 和 Windows API 进行资源操作有所帮助。
说说Redis为什么快 Redis有几种数据结构,底层分别是怎么存储的 Redis有几种持久化方式 多线程情况下,如何保证线程安全? 用过volatile吗?底层原理是?...先看下Redis的数据结构&内部编码图: 1.2.1 SDS简单动态字符串 字符串长度处理:Redis获取字符串长度,时间复杂度为O(1),而C语言中,需要从头开始遍历,复杂度为O(n); 空间预分配...字典就是哈希表,比如HashMap,通过key就可以直接获取到对应的value。而哈希表的特性,在O(1)时间复杂度就可以获得对应的值。...多线程情况下,如何保证线程安全? 加锁,比如悲观锁select for update,sychronized等,如,乐观锁,乐观锁如CAS等,还有redis分布式锁等等。 5....它是如何保证可见性的,原理是什么 volatile关键字是Java虚拟机提供的的最轻量级的同步机制,它作为一个修饰符, 用来修饰变量。它保证变量对所有线程可见性,禁止指令重排,但是不保证原子性。
我们对字符串的操作就能变得行云流水 注意: string 诞生于 STL 之前,因此存在部分接口冗余的情况 ---- 正文 本文介绍的是 string 部分常用接口 basic_string string...s2 //string s2 = s1; //这种写法也是可以的 return 0; } ---- 容量操作相关 我们可以把 string 类看作一个专门用来处理字符的顺序表,因为它有字符指针...、容量、长度等信息,我们也可以进行手动扩容等操作 ️获取数据 获取 string 对象中指向字符串的指针 _str C++兼容C,在某些场景下需要使用指向字符串的指针,因此 string 类中提供了这个接口...int main() { string s("hello"); cout << s.c_str() << endl; //获取对象s中的字符串指针 return 0; } 此时直接打印内容的原因是当指针指向对象为常量字符串时...改用指针,先 2倍 扩容至 30,后续字符都是存在指针中 之后的扩容操作,都是以 1.5倍 进行扩容 会多开辟一些空间 Linux中 string 的扩容策略 默认大小为 0 的空间 当第一次扩容时,会先扩至
①、常数复杂度获取字符串长度 由于 len 属性的存在,我们获取 SDS 字符串的长度只需要读取 len 属性,时间复杂度为 O(1)。...里面的元素,并且 SDS 不是以空字符串来判断是否结束,而是以 len 属性表示的长度来判断字符串是否结束。...②、无环:表头节点的 prev 指针和表尾节点的 next 指针都指向 NULL,对链表的访问都是以 NULL 结束。 ...注意这里还有一个指向下一个哈希表节点的指针,我们知道哈希表最大的问题是存在哈希冲突,如何解决哈希冲突,有开放地址法和链地址法。...8、总结 大多数情况下,Redis使用简单字符串SDS作为字符串的表示,相对于C语言字符串,SDS具有常数复杂度获取字符串长度,杜绝了缓存区的溢出,减少了修改字符串长度时所需的内存重分配次数,以及二进制安全能存储各种类型的文件
这个映射函数叫做散列函数,存放记录的数组叫做散列表。 JavaScript 中的对象也是以 Key-Value 的形式访问,那么 JavaScript 的对象是否以 Hash 的结构存储呢?...JavaScript 对象存储形式 JavaScript 对象 Key 存储形式 在我们创建或者访问对象属性的时候,如果使用 对象.属性名 的方式,属性名只能为字符串类型,而且不能以数字开头: let...这里也间接证明了 JavaScript 对象中,所有的 key 都是字符串,即使你访问的时候不是字符串的形式,解释器也会先将其转化为字符串。...这种方式称之为按引用访问。...总结 在 JavaScript 中对象是以 Hash 结构存储的,用 键值对表示对象的属性,Key 的数据类型为字符串,Value 的数据类型是结构体,即对象是以 <String
对于这道题,我们要如何回答呢? 一般来说,我们会从介绍存储数据类型,在到内部数据结构,最后是底层实现原理的步骤进行回答。 1....Redis 的数据类型 有五大数据类型:String,List,Hash,Set,Zset。...: 真正存储字符串数据的空间,是一个char[]数组 不超过44字节的情况下以embstr存储,超过44字节则以raw形式存储,需要分配两次内存空间(分别为 Redis Object 和 SDS 分配空间...只有当存储的数据量比较小的情况下,Redis 才使用 ZipList 压缩列表来实现,其他情况则是对应着 Dict。...当数据量越来越大时,这种结构的优势就更加明显了。
①、常数复杂度获取字符串长度 由于 len 属性的存在,我们获取 SDS 字符串的长度只需要读取 len 属性,时间复杂度为 O(1)。...里面的元素,并且 SDS 不是以空字符串来判断是否结束,而是以 len 属性表示的长度来判断字符串是否结束。...②、无环:表头节点的 prev 指针和表尾节点的 next 指针都指向 NULL,对链表的访问都是以 NULL 结束。 ③、带链表长度计数器:通过 len 属性获取链表长度的时间复杂度为 O(1)。...注意这里还有一个指向下一个哈希表节点的指针,我们知道哈希表最大的问题是存在哈希冲突,如何解决哈希冲突,有开放地址法和链地址法。...8、总结 大多数情况下,Redis使用简单字符串SDS作为字符串的表示,相对于C语言字符串,SDS具有常数复杂度获取字符串长度,杜绝了缓存区的溢出,减少了修改字符串长度时所需的内存重分配次数,以及二进制安全能存储各种类型的文件
领取专属 10元无门槛券
手把手带您无忧上云