我们知道,整个Redis的数据结构是key-value形式组成的一个全局字典,还有带过期时间key集合也是一个字典。
struct RedisDb{
dict* dict; //所有key-value
dict* expires //所有key的过期时间
...
}
struct zset{
dict* dict //所有的value-score
zskiplist *zsl //跳表
}
一、字典内部结构
在字典的内部结构中包含两个hashtable,但是只有一个hashtable是存储数据的(我们假设为h[0],另一个hashtable(我们假设h[1])的作用是:当字典需要进行扩容或者缩容的时候,需要分配出新的hashtable,然后进行渐进式的搬迁 ,这个h[0]存储的是旧的数据,h[1]存储的是新的数据,当数据完全迁移到h[1]的时候,h[0]里面的hashtable将会被删除,而被被h[1]取代。
Redis里面hashtable的结构和Java中HashMap的结构以及原理几乎是一样的,都是通过粪桶的方式解决了hash冲突。在结构中一共有两个维度,第一个是数组,在每一个数组元素中又存了一个链表结构。
当插入一个元素的时候,先获取元素的散列值,根据散列值找到结构数组中对应的位置。如果该位置中没有元素,则把插入的新值填充到相应的数组位置。若有元素(元素为一个链表节点),则以哈希值和内容来比较两个元素是否相等,如果不相等取元素的下一个节点,直到取到最后一个节点加入到元素的尾部中。
二、渐进式rehash详解
大字典扩容redis一般采用渐进式rehash操作。
首先我们要先知道两个问题。第一个就是什么叫渐进式,第二个就是为什么需要渐进式。
在我的理解下,渐进式rehash就是把一次rehash操作分成很多步进行操作,这样可以把一次性的耗时分散到其他操作的耗时上,这属于一个分治的思想。如果不采用渐进式rehash,那么一次大字典的扩容操作是需要花费很多时间的,这对于单线程的redis是很难承受这样的过程。所以干脆把一次性的耗时分散到多次、渐进式的完成。虽然这样扩容会慢一些,但是总可以完成扩容操作。
渐进式rehash大致分为四个步骤:
为 ht[1]
分配空间, 让字典同时持有 ht[0]
和 ht[1]
两个哈希表。
在字典中维持一个索引计数器变量 rehashidx
, 并将它的值设置为 0
, 表示 rehash 工作正式开始。
在 rehash 进行期间, 每次对字典执行添加、删除、查找或者更新操作时, 程序除了执行指定的操作以外, 还会顺带将 ht[0]
哈希表在 rehashidx
索引上的所有键值对 rehash 到 ht[1]
, 当 rehash 工作完成之后, 程序将 rehashidx
属性的值增一。
随着字典操作的不断执行, 最终在某个时间点上, ht[0]
的所有键值对都会被 rehash 至 ht[1]
, 这时程序将 rehashidx
属性的值设为 -1
, 表示 rehash 操作已完成。
渐进式的过程如下图所示:
dict | type | privdata | ht | rehashidx \n -1 "]; // 哈希表 dictht0 [label = " dictht | table | size \n 4 | sizemask \n 3 | used \n 4"]; dictht1 [label = " dictht | table | size \n 8 | sizemask \n 7 | used \n 0"]; table0 [label = " dictEntry*[4] | <0> 0 | <1> 1 | <2> 2 | <3> 3 "]; table1 [label = " dictEntry*[8] | <0> 0 | <1> 1 | <2> 2 | ... | <7> 7 "]; // 哈希表节点 kv0 [label = " dictEntry | { k0 | v0 } "]; kv1 [label = " dictEntry | { k1 | v1 } "]; kv2 [label = " dictEntry | { k2 | v2 } "]; kv3 [label = " dictEntry | { k3 | v3 } "]; // node [shape = plaintext, label = "NULL"]; // dict:ht -> dictht0:head [label = "ht[0]"]; dict:ht -> dictht1:head [label = "ht[1]"]; dictht0:table -> table0:head; dictht1:table -> table1:head; table0:0 -> kv2:head -> null0; table0:1 -> kv0:head -> null1; table0:2 -> kv3:head -> null2; table0:3 -> kv1:head -> null3; table1:0 -> null10; table1:1 -> null11; table1:2 -> null12; table1:7 -> null17; }" class="has" src="http://img.e-com-net.com/image/info8/65c6a2e068d545749bdd6d5353d61f2b.jpg" width="0" height="0">
dict | type | privdata | ht | rehashidx \n 0 "]; // 哈希表 dictht0 [label = " dictht | table | size \n 4 | sizemask \n 3 | used \n 3"]; dictht1 [label = " dictht | table | size \n 8 | sizemask \n 7 | used \n 1"]; table0 [label = " dictEntry*[4] | <0> 0 | <1> 1 | <2> 2 | <3> 3 "]; table1 [label = " dictEntry*[8] | ... | <4> 4 | ... "]; // 哈希表节点 kv0 [label = " dictEntry | { k0 | v0 } "]; kv1 [label = " dictEntry | { k1 | v1 } "]; kv2 [label = " dictEntry | { k2 | v2 } "]; kv3 [label = " dictEntry | { k3 | v3 } "]; // node [shape = plaintext, label = "NULL"]; // dict:ht -> dictht0:head [label = "ht[0]"]; dict:ht -> dictht1:head [label = "ht[1]"]; dictht0:table -> table0:head; dictht1:table -> table1:head; table0:0 -> null0; table0:1 -> kv0:head -> null1; table0:2 -> kv3:head -> null2; table0:3 -> kv1:head -> null3; table1:4 -> kv2:head -> null14 }" class="has" src="http://img.e-com-net.com/image/info8/3f9d6e65caf44c95959b217b5587aaff.jpg" width="0" height="0">
dict | type | privdata | ht | rehashidx \n 1 "]; // 哈希表 dictht0 [label = " dictht | table | size \n 4 | sizemask \n 3 | used \n 2"]; dictht1 [label = " dictht | table | size \n 8 | sizemask \n 7 | used \n 2"]; table0 [label = " dictEntry*[4] | <0> 0 | <1> 1 | <2> 2 | <3> 3 "]; table1 [label = " dictEntry*[8] | ... | <4> 4 | <5> 5 | ... "]; // 哈希表节点 kv0 [label = " dictEntry | { k0 | v0 } "]; kv1 [label = " dictEntry | { k1 | v1 } "]; kv2 [label = " dictEntry | { k2 | v2 } "]; kv3 [label = " dictEntry | { k3 | v3 } "]; // node [shape = plaintext, label = "NULL"]; // dict:ht -> dictht0:head [label = "ht[0]"]; dict:ht -> dictht1:head [label = "ht[1]"]; dictht0:table -> table0:head; dictht1:table -> table1:head; table0:0 -> null0; table0:1 -> null1; table0:2 -> kv3:head -> null2; table0:3 -> kv1:head -> null3; table1:4 -> kv2:head -> null14 table1:5 -> kv0:head -> null15; }" class="has" src="http://img.e-com-net.com/image/info8/2bf31e323ad34fbd8111a4386e35f590.jpg" width="0" height="0">
dict | type | privdata | ht | rehashidx \n 2 "]; // 哈希表 dictht0 [label = " dictht | table | size \n 4 | sizemask \n 3 | used \n 1"]; dictht1 [label = " dictht | table | size \n 8 | sizemask \n 7 | used \n 3"]; table0 [label = " dictEntry*[4] | <0> 0 | <1> 1 | <2> 2 | <3> 3 "]; table1 [label = " dictEntry*[8] | ... | <1> 1 | ... | <4> 4 | <5> 5 | ... "]; // 哈希表节点 kv0 [label = " dictEntry | { k0 | v0 } "]; kv1 [label = " dictEntry | { k1 | v1 } "]; kv2 [label = " dictEntry | { k2 | v2 } "]; kv3 [label = " dictEntry | { k3 | v3 } "]; // node [shape = plaintext, label = "NULL"]; // dict:ht -> dictht0:head [label = "ht[0]"]; dict:ht -> dictht1:head [label = "ht[1]"]; dictht0:table -> table0:head; dictht1:table -> table1:head; table0:0 -> null0; table0:1 -> null1; table0:2 -> null2; table0:3 -> kv1:head -> null3; table1:1 -> kv3:head -> null11; table1:4 -> kv2:head -> null14 table1:5 -> kv0:head -> null15; }" class="has" src="http://img.e-com-net.com/image/info8/35097ec231cc466ab6a9b713652e9cc3.jpg" width="0" height="0">
dict | type | privdata | ht | rehashidx \n 3 "]; // 哈希表 dictht0 [label = " dictht | table | size \n 4 | sizemask \n 3 | used \n 0"]; dictht1 [label = " dictht | table | size \n 8 | sizemask \n 7 | used \n 4"]; table0 [label = " dictEntry*[4] | <0> 0 | <1> 1 | <2> 2 | <3> 3 "]; table1 [label = " dictEntry*[8] | ... | <1> 1 | ... | <4> 4 | <5> 5 | ... | <7> 7 "]; // 哈希表节点 kv0 [label = " dictEntry | { k0 | v0 } "]; kv1 [label = " dictEntry | { k1 | v1 } "]; kv2 [label = " dictEntry | { k2 | v2 } "]; kv3 [label = " dictEntry | { k3 | v3 } "]; // node [shape = plaintext, label = "NULL"]; // dict:ht -> dictht0:head [label = "ht[0]"]; dict:ht -> dictht1:head [label = "ht[1]"]; dictht0:table -> table0:head; dictht1:table -> table1:head; table0:0 -> null0; table0:1 -> null1; table0:2 -> null2; table0:3 -> null3; table1:1 -> kv3:head -> null11; table1:4 -> kv2:head -> null14 table1:5 -> kv0:head -> null15; table1:7 -> kv1:head -> null17; }" class="has" src="http://img.e-com-net.com/image/info8/329ba5b0f63347fd91252a0d1bef7cf0.jpg" width="0" height="0">
dict | type | privdata | ht | rehashidx \n -1 "]; // 哈希表 dictht0 [label = " dictht | table | size \n 8 | sizemask \n 7 | used \n 4"]; dictht1 [label = " dictht | table | size \n 0 | sizemask \n 0 | used \n 0"]; table0 [label = " dictEntry*[8] | ... | <1> 1 | ... | <4> 4 | <5> 5 | ... | <7> 7 "]; table1 [label = "NULL", shape = plaintext]; // 哈希表节点 kv0 [label = " dictEntry | { k0 | v0 } "]; kv1 [label = " dictEntry | { k1 | v1 } "]; kv2 [label = " dictEntry | { k2 | v2 } "]; kv3 [label = " dictEntry | { k3 | v3 } "]; // node [shape = plaintext, label = "NULL"]; // dict:ht -> dictht0:head [label = "ht[0]"]; dict:ht -> dictht1:head [label = "ht[1]"]; dictht0:table -> table0:head; dictht1:table -> table1; table0:1 -> kv3:head -> null11; table0:4 -> kv2:head -> null14; table0:5 -> kv0:head -> null15; table0:7 -> kv1:head -> null17; }" class="has" src="http://img.e-com-net.com/image/info8/de107f39f8904feb94b0a20c6f3aaefa.jpg" width="0" height="0">
渐进是把hash操作分散到对字典的增加、删除、修改等操作上的。那么如果对于一个正在发生rehash操作的字典,我需要查找到该字典的某一个元素该怎么办?首先我会在h[0]进行查找,如果在h[0]找不到的话则再去h[1]上进行查找。
在增加操作中的增加的元素都一律保存在新表h[1]当中,这将意味着一旦发生扩容操作h[0]的值是不会改变的。
如果在搬迁的过程中并没有对字典进行操作那怎么办?是否就意味着不会进行rehash操作了?当然不是。如果字典后面没有进行操作的话,redis还有一个定时器任务,redis将会在定时器任务中对字典进行搬迁操作
三、hash攻击
hashtable中key的分布的均匀程度影响到redis的性能,但是如果一个hash函数存在偏向性,那么黑客可以利用这个偏向性对服务器进行攻击,使得key的分布堆积在某一个数组当中,这样会使得链表非常的长,导致查找的效率下降,可能查询的时间复杂度退化到O(n)级别,这样服务器很容易崩溃,这就是hash攻击。
四、扩容条件
当hash表中元素的个数等于数组长度的时候将会进行扩容操作,扩容的大小为原来数组的2倍。不过如果redis正在做bgsave操作为了加少过多的内存页分离(COW操作),redis此时尽量不会去扩容。如果hash表中的元素长度为数组长度的5倍以上,将会进行强制扩容。
五、缩容条件
当hash表进行删除操作,元素个数低于数组长度的10%,将会进行缩容操作。缩容操作不会考虑redis是否在进行bgsava操作。
参考:http://redisbook.com/preview/dict/incremental_rehashing.html
你可能感兴趣的:(redis,java)
”天下第一神数“——紫微斗数的JAVA实现!紫微玄机速run~
钮钴禄·爱因斯晨
赛博算命JAVA实现 java python 开发语言
各位佬儿们好呀~~互三必回哦~更多精彩:个人主页赛博算命精彩文章:梅花易数的java实现赛博算命系列文章不作溢美之词,不作浮夸文章,此文与功名进取毫不相关也!与各位共勉!!文章目录#前言:一、紫微斗数简介二、紫微斗数的数学原理1.**命盘构建规则**2.**星曜分布算法**3.**运势推导逻辑**三、Java实现步骤1.代码分布实现1.1**数据结构设计**1.2**命盘构建算法实现**1.3**
华为OD-不限经验,急招,机考资料,面试攻略,不过改推,捞人
2301_79125642
java
超星(学习通)-Java后端一面网易互娱40min(感觉是G了)一篇不太像面经的面经2023总结,前端大二上进小红书秋招面经第一波海康红外图像算法实习(微影)面经测试工程师社招-测试面试题大厂在职傻屌。TPlink图像算法工程师一二三面经深圳海康红外图像算法实习(微影)面经TPLink提前批面经(已OC)传统车辆转规控算法岗秋招记录腾讯TEG测试与质量管理全记录瑞幸Java开发校招一面腾讯金融科技
希音(Shein)前端开发面试题集锦和参考答案
大模型大数据攻城狮
arcgis webpack 前端攻击 xss csrf react 前端面试
用Node写过什么工具或npm包在实际开发中,使用Node编写过多种实用工具和npm包。自动化构建工具开发了一个简单的自动化构建工具,用于处理前端项目的资源压缩和合并。在前端项目中,为了优化性能,需要对CSS和JavaScript文件进行压缩,减少文件体积,同时将多个小文件合并成一个大文件,减少HTTP请求。这个工具使用Node的fs模块进行文件的读写操作,通过terser库对JavaScript
Redis
任璐
redis 数据库 缓存
1.Redis简介简单来说redis就是一个数据库,不过与传统数据库不同的是redis的数据是存在内存中的,所以存写速度非常快,因此redis被广泛应用于缓存方向。另外,redis也经常用来做分布式锁。redis提供了多种数据类型来支持不同的业务场景。除此之外,redis支持事务、持久化、LUA脚本、LRU驱动事件、多种集群方案。2.我们为什么要用redis/为什么要用缓存呢?主要从“高性能”和“
【华为OD机试真题E卷】54、统一限载货物数最小值 | 机试真题+思路参考+代码解析(C++、Java、Py)
KFickle
Java Py) 华为od c++ java 华为OD机试真题 统一限载货物数最小值
文章目录一、题目题目描述输入输出样例1样例2二、代码与思路参考C++代码Java代码Python代码订阅本专栏后即可解锁在线OJ刷题权限个人博客首页:KFickle专栏介绍:最新的华为OD机试真题D、E卷,每题都使用C++,Java,Python语言进行解答,每个题目的思路分析都非常详细,持续更新,支持在线OJ刷题,订阅后评论获取权限,有代码问题随时解答,代码仅供学习参考一、题目题目描述火车站附近
迎接AI挑战:Java程序员的技能进化与发展趋势!!!
小南AI学院
人工智能 java 开发语言
1.AI时代,JAVA程序员编码方式的发展趋势在AI时代,JAVA程序员编码方式的发展趋势正在经历显著变化。以下是几个主要发展方向:AI辅助编码工具的普及:像GitHubCopilot、AmazonCodeWhisperer和JetBrainsAIAssistant等工具正在帮助Java开发者更快地编写代码,自动完成常见模式和解决方案。这些工具不仅提供代码补全,还能生成函数、类甚至完整的实现。声明
Java中获取日期区间中所有日期
知行02
Java相关 日期处理 LocalDate 时间区间 Java 日期遍历
1.获取传入日期区间中所有日期1.代码演示/***根据传入的日期,获取时间区间中所有的日期**@paramstartDate开始日期*@paramendDate结束日期*@returnjava.util.List*@since2022/3/2*/@TestpublicstaticListgetAllDatesInTheDateRange(LocalDatestartDate,LocalDateen
java.util中的Scanner类
鼬猿
java 开发语言 intellij-idea
Scanner类可以用于从各种来源(如标准输入、文件、字符串等)读取不同类型的数据。它提供了各种方法来解析和提取输入的数据,并将其转换为相应的数据类型。在使用Scanner之前,需要先通过import语句导入java.util.Scanner类。创建了一个Scanner对象并传入System.in作为输入源,表示从标准输入中读取数据。例:Scanner变量名=newScanner(System.i
【华为OD技术面试手撕真题】113、组合总和 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS)
KJ.JK
华为OD技术面试手撕真题 华为od 面试 c语言 华为od机试E卷 华为od机试真题 组合总和
文章目录一、题目题目描述样例1二、代码参考C语言思路C语言代码C++语言思路C++代码Java语言思路Java代码Python语言思路Python代码JS语言思路JS代码作者:KJ.JK个人博客首页:KJ.JK专栏介绍:本专栏更新每年华为OD机试的高频手撕代码题,每个题目都会使用五种语言进行解答(C&C++&Java&Python&JS),思路分析都非常详细,争取实现最低的时间复杂度和高通过率,每
Java接口(3)与图书管理系统
风吹落叶3257
java 开发语言
抽象类与接口的区别1.抽象类包含普通类和抽象方法,子类可以直接调用普通类方法不用重写。接口包含抽象方法和全局变量。2.抽象类有各种权限,接口只有pubilc。3.子类使用抽象类用extend,使用接口用implement。4.一个抽象类可以实现若干个接口,接口不能继承抽象类,但是接口可以继承多个接口5.一个类只能继承一个抽象类,一个子类可以实现多个接口。Object类Object类没有父类,可以引
数据库事务,回滚到指定点 oracle java
xiaoyustudiowww
jvm java oracle
======oracle表sqlCREATETABLE"SMALL19RAIN"."R_TABLE_STU"("NAME"VARCHAR2(200BYTE),"AGE"NUMBER,"STU_ID"NUMBERNOTNULLENABLE,"DATARAIN"VARCHAR2(200BYTE))SEGMENTCREATIONIMMEDIATEPCTFREE10PCTUSED40INITRANS1MA
琴韵博主 —— 工具集
琴 韵
知识库 在线文档
CSDN猿如意_开发者工具箱CSDN开发助手ChromeChrome最新版离线下载internetdownloadmanager付费在线转换在线JSON字符串转Java实体类(JavaBean、Entity)在线MD5加密解密YAML、YML在线编辑器(格式化校验)在线图片转换成文字图片base64互转颜色转换颜色转换人民币大小写转换蛙蛙:英文字母大小写转换、文本工具汉字拼音在线转换Google翻
【Qt】Qt Widgets和QML(Qt Quick)开发界面的区别
£އއ昔年
qt 开发语言
Qt提供了两种主要的UI技术:QtWidgets和QML(QtQuick)。它们的核心区别主要体现在使用方式、架构、性能、开发难度和适用场景等方面。1.QtWidgetsvs.QML总体对比对比项QtWidgetsQML(QtQuick)语言C++(带QtUI库)QML+JavaScript(底层C++)渲染方式传统窗口系统控件(原生或模拟)基于OpenGL,使用GPU加速UI风格经典桌面UI(W
JAVA排序
荔枝吃吃
java 排序算法 算法
1.冒泡排序/***使用冒泡排序算法对整数数组进行排序*冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,*一次比较两个元素,如果它们的顺序错误就把它们交换过来*遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成*这个算法的名字由来是因为越小(或越大)的元素会经过交换慢慢“浮”到数列的顶端**@paramarr待排序的整数数组*/publicstaticvoidbubb
React 基础教程
阿贾克斯的黎明
前端 react.js 前端 前端框架
目录React基础教程一、React简介二、安装和设置三、创建第一个React组件(一)函数式组件(二)类组件四、渲染组件五、组件的属性和状态(一)属性(Props)(二)状态(State)六、组件的生命周期方法七、事件处理八、总结React是一个用于构建用户界面的JavaScript库。它以高效、灵活和可维护性而受到广泛的欢迎。本教程将介绍React的基础知识,帮助你快速上手React开发。一、
贪心算法-字符串数组能拼接出的最小字典序(java)
SP_1024
算法 贪心算法 算法 java
最小字典序的贪心算法题目描述贪心算法的解题思路贪心算法自定义比较器贪心算法暴力递归解法题目描述给定一个由字符串组成的数组strs,必须把所有的字符串拼接起来,返回所有可能的拼接结果中字典序最小的结果贪心算法的解题思路首先我们很自然的能想到,遍历数组,比较数组中每一个元素,字典序越小的,就放前面.但这里右一个陷阱,比如ba和b两个字符串,b的字典序小于ba,如果拼成bba就错了,显然bab字典序更小
【无标题】Hollo world.Javascript
一一代码
python javascript
HelloWorld最简单JavaScript代码console.log("Hello,World!");变量和数据类型JavaScript中的变量声明和基本数据类型。```javascriptletname="Alice";//字符串constage=25;//数字letisStudent=true;//布尔值console.log(name,age,isStudent);```函数定义一个简单
HTML+CSS+javascript 轮播图
Paula-柒月拾
javascript html css 前端 html5
HTML,CSS和JavaScript可以用来创建轮播图。HTML用于构建网页的结构,所以您可以使用HTML来定义轮播图的各个部分,如图像和文本。CSS用于设计网页的外观,所以您可以使用CSS来设置轮播图的布局和样式。JavaScript用于控制网页的行为,所以您可以使用JavaScript来控制轮播图的功能,如自动播放和用户交互。下面是一个简单的HTMLCSSJavaScript轮播图的例子:H
Java 常见的面试题(MySql)
web18285997089
面试 学习路线 阿里巴巴 java mysql oracle
一、数据库的三范式是什么?**范式:**简言之就是,数据库设计对数据的存储性能,还有开发人员对数据的操作都有莫大的关系。所以建立科学的,规范的的数据库是需要满足一些规范的来优化数据数据存储方式。在关系型数据库中这些规范就可以称为范式。第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在
【2024年华为OD机试】 (C卷,100分)- 分配土地(JavaScript&Java & Python&C/C++)
妄北y
算法汇集笔记总结(保姆级) 华为od c语言 javascript python java
一、问题描述题目描述从前有个村庄,村民们喜欢在各种田地上插上小旗子,旗子上标识了各种不同的数字。某天,集体村民决定将覆盖相同数字的最小矩阵形的土地分配给村里做出巨大贡献的村民。请问此次分配土地,做出贡献的村民最大会分配多大面积?输入描述第一行输入m和n:m代表村子的土地的长。n代表土地的宽。第二行开始输入地图上的具体标识:旗子上的数字为1~500,未插旗子的土地用0标识。输出描述输出此次分配土地,
【第10天】给定一个字符 c ,要求转换成大写进行输出 | 初识ASCII码
执 梗
《Java入门100练》 c语言 java 算法 蓝桥杯 数据结构
本文已收录于专栏《Java入门一百例》学习指引序、专栏前言一、什么是ASCII?二、【例题2】2、解题思路3、模板代码4、代码解析三、【例题2】2、解题思路3、模板代码4、代码解析四、奇淫巧技五、推荐专栏六、课后习题序、专栏前言 本专栏开启,目的在于帮助大家更好的掌握学习Java,特别是一些Java学习者难以在网上找到系统地算法学习资料帮助自身入门算法,同时对于专栏内的内容有任何疑问都可在文章末
redis进阶——哈希(Hash)
文修
Redis redis hash
redis作为最流行的高性能的key-value数据库,笔者几乎每个项目都会用到,不过老实说,笔者在初期只会用string类型,就是说每次都是整存整取,说实话,效率不高,不知道大家有没有像我这样。不过,我知道redis有其他类型,只是因为习惯以及懒的原因,所以长期执着于string类型,后来在空余时间,了解了其他存储方式,一看之后,瞬间就觉得自己以前太low了,今天要说的就是我redis里面的哈希
前端本地储存的方式汇总
懒羊羊我小弟
前端框架 javascript js 浏览器 web app 小程序
JavaScript本地存储是Web开发中用于在客户端存储数据的重要技术,以下是常见方式及其区别和应用场景:一、WEB浏览器本地存储方式及特点1.1储存方式1.Cookie存储容量:约4KB(每个域名)。生命周期:可设置过期时间;默认随会话结束失效。作用域:同源页面共享。访问方式:通过document.cookie读写,每次HTTP请求自动携带。特点:支持服务器端操作(通过HTTP头),但存储效率
【全开源】Java陪诊小程序医院陪护陪诊小程序APP源码
指间代码师
java 小程序 开发语言 微信开放平台 微信小程序 大数据
陪诊小程序医院陪护陪诊小程序是一种结合了医疗服务和便捷技术的创新工具,旨在为需要陪诊服务的患者提供全方位的支持和帮助。一、功能预约挂号:患者可以通过陪诊小程序直接预约挂号,选择适合的医生和就诊时间,避免了传统挂号方式的繁琐和耗时。陪诊服务:小程序提供陪诊员服务,陪诊员可以协助患者完成挂号、取药、缴费等流程,确保患者能够顺利就医。在线咨询:患者可以通过小程序与医生进行在线沟通,获取专业的医疗建议和健
java.lang.NoClassDefFoundError异常的正确解决方法
梅菊林
各种问题解决方案 java 开发语言
java.lang.NoClassDefFoundError是Java运行时环境中的一个错误,表明JVM在运行时尝试加载一个类的定义,但未能找到。这通常发生在编译时该类是可用的,但在运行时JVM的类路径(classpath)上却找不到这个类。此错误不同于ClassNotFoundException,后者通常在加载类时抛出,而NoClassDefFoundError则是在尝试定义类或其静态成员时抛出
【Py/Java/C++/C/JS/Go六种语言OD独家2024E卷真题】20天拿下华为OD笔试之【模拟】2024E-最大相连男生数【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 模拟 # 状态压缩 算法 java c++ c语言 华为od javascript python
可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳oj1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例输入输出解题思路代码代码一:分类写法pythonjavacppCNodejavaScriptGo代码二:合并写法pythonjavacppCNodejavaScriptGo*代码三:状态压缩写法pythonjavacppCNod
【Py/Java/C++/JS/Go五种语言【OD独家2024E卷真题】20天拿下华为OD笔试之【哈希表】2024E-猜字谜【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 哈希表 java c++ 华为od python 算法 leetcode
可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳oj1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述备注示例一输入输出示例二输入输出解题思路谜面和谜底如何匹配暴力匹配所有谜底谜底库哈希表的构建代码解法一:哈希表预处理谜底pythonjavacppNodejavaScriptgo时空复杂度解法二:暴力匹配解(会超时)pythonja
【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【排序】2024E-VLAN资源池【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
# 模拟 最新华为OD真题 java c++ 华为od leetcode 算法 python
可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明示例三输入输出说明解题思路用二元组表示区间删除某一元素后区间的变化将二元组形式转换回原形式代码pythonjavacpp时空复杂度华为OD算法/大厂面试高频题算法练习冲刺训练相关推荐阅读【华为OD
【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【模拟】2024E-靠谱的车【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 模拟 # 数学 java c++ 华为od 算法 python leetcode
可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出示例二输入输出示例三输入输出解题思路从A进制到九进制从九进制到十进制代码pythonjavacpp时空复杂度华为OD算法/大厂面试高频题算法练习冲刺训练相关推荐阅读【华为OD机考】2024D+E卷最全真题【完全原创题解
【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【模拟】2024D-学生重新排队【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 模拟 # 蒙特卡洛 java c++ 华为od leetcode 算法 python
有LeetCode算法/华为OD考试扣扣交流群可加948025485可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述备注示例一输入输出说明示例二输入输出说明解题思路数组预处理检查某个组是否已经排好队检查所有组是否已经排好队蒙特卡洛模拟框架单次蒙特卡洛模拟整体思路编号挑选优化组号区间优化单次蒙
Spring的注解积累
yijiesuifeng
spring 注解
用注解来向Spring容器注册Bean。
需要在applicationContext.xml中注册:
<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>。
如:在base-package指明一个包
<context:component-sc
传感器
百合不是茶
android 传感器
android传感器的作用主要就是来获取数据,根据得到的数据来触发某种事件
下面就以重力传感器为例;
1,在onCreate中获得传感器服务
private SensorManager sm;// 获得系统的服务
private Sensor sensor;// 创建传感器实例
@Override
protected void
[光磁与探测]金吕玉衣的意义
comsci
这是一个古代人的秘密:现在告诉大家
信不信由你们:
穿上金律玉衣的人,如果处于灵魂出窍的状态,可以飞到宇宙中去看星星
这就是为什么古代
精简的反序打印某个数
沐刃青蛟
打印
以前看到一些让求反序打印某个数的程序。
比如:输入123,输出321。
记得以前是告诉你是几位数的,当时就抓耳挠腮,完全没有思路。
似乎最后是用到%和/方法解决的。
而今突然想到一个简短的方法,就可以实现任意位数的反序打印(但是如果是首位数或者尾位数为0时就没有打印出来了)
代码如下:
long num, num1=0;
PHP:6种方法获取文件的扩展名
IT独行者
PHP 扩展名
PHP:6种方法获取文件的扩展名
1、字符串查找和截取的方法
1
$extension
=
substr
(
strrchr
(
$file
,
'.'
), 1);
2、字符串查找和截取的方法二
1
$extension
=
substr
面试111
文强chu
面试
1事务隔离级别有那些 ,事务特性是什么(问到一次)
2 spring aop 如何管理事务的,如何实现的。动态代理如何实现,jdk怎么实现动态代理的,ioc是怎么实现的,spring是单例还是多例,有那些初始化bean的方式,各有什么区别(经常问)
3 struts默认提供了那些拦截器 (一次)
4 过滤器和拦截器的区别 (频率也挺高)
5 final,finally final
XML的四种解析方式
小桔子
dom jdom dom4j sax
在平时工作中,难免会遇到把 XML 作为数据存储格式。面对目前种类繁多的解决方案,哪个最适合我们呢?在这篇文章中,我对这四种主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。 预 备 测试环境: AMD 毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server
wordpress中常见的操作
aichenglong
中文注册 wordpress 移除菜单
1 wordpress中使用中文名注册解决办法
1)使用插件
2)修改wp源代码
进入到wp-include/formatting.php文件中找到
function sanitize_user( $username, $strict = false
小飞飞学管理-1
alafqq
管理
项目管理的下午题,其实就在提出问题(挑刺),分析问题,解决问题。
今天我随意看下10年上半年的第一题。主要就是项目经理的提拨和培养。
结合我自己经历写下心得
对于公司选拔和培养项目经理的制度有什么毛病呢?
1,公司考察,选拔项目经理,只关注技术能力,而很少或没有关注管理方面的经验,能力。
2,公司对项目经理缺乏必要的项目管理知识和技能方面的培训。
3,公司对项目经理的工作缺乏进行指
IO输入输出部分探讨
百合不是茶
IO
//文件处理 在处理文件输入输出时要引入java.IO这个包;
/*
1,运用File类对文件目录和属性进行操作
2,理解流,理解输入输出流的概念
3,使用字节/符流对文件进行读/写操作
4,了解标准的I/O
5,了解对象序列化
*/
//1,运用File类对文件目录和属性进行操作
//在工程中线创建一个text.txt
getElementById的用法
bijian1013
element
getElementById是通过Id来设置/返回HTML标签的属性及调用其事件与方法。用这个方法基本上可以控制页面所有标签,条件很简单,就是给每个标签分配一个ID号。
返回具有指定ID属性值的第一个对象的一个引用。
语法:
&n
励志经典语录
bijian1013
励志 人生
经典语录1:
哈佛有一个著名的理论:人的差别在于业余时间,而一个人的命运决定于晚上8点到10点之间。每晚抽出2个小时的时间用来阅读、进修、思考或参加有意的演讲、讨论,你会发现,你的人生正在发生改变,坚持数年之后,成功会向你招手。不要每天抱着QQ/MSN/游戏/电影/肥皂剧……奋斗到12点都舍不得休息,看就看一些励志的影视或者文章,不要当作消遣;学会思考人生,学会感悟人生
[MongoDB学习笔记三]MongoDB分片
bit1129
mongodb
MongoDB的副本集(Replica Set)一方面解决了数据的备份和数据的可靠性问题,另一方面也提升了数据的读写性能。MongoDB分片(Sharding)则解决了数据的扩容问题,MongoDB作为云计算时代的分布式数据库,大容量数据存储,高效并发的数据存取,自动容错等是MongoDB的关键指标。
本篇介绍MongoDB的切片(Sharding)
1.何时需要分片
&nbs
【Spark八十三】BlockManager在Spark中的使用场景
bit1129
manager
1. Broadcast变量的存储,在HttpBroadcast类中可以知道
2. RDD通过CacheManager存储RDD中的数据,CacheManager也是通过BlockManager进行存储的
3. ShuffleMapTask得到的结果数据,是通过FileShuffleBlockManager进行管理的,而FileShuffleBlockManager最终也是使用BlockMan
yum方式部署zabbix
ronin47
yum方式部署zabbix
安装网络yum库#rpm -ivh http://repo.zabbix.com/zabbix/2.4/rhel/6/x86_64/zabbix-release-2.4-1.el6.noarch.rpm 通过yum装mysql和zabbix调用的插件还有agent代理#yum install zabbix-server-mysql zabbix-web-mysql mysql-
Hibernate4和MySQL5.5自动创建表失败问题解决方法
byalias
J2EE Hibernate4
今天初学Hibernate4,了解了使用Hibernate的过程。大体分为4个步骤:
①创建hibernate.cfg.xml文件
②创建持久化对象
③创建*.hbm.xml映射文件
④编写hibernate相应代码
在第四步中,进行了单元测试,测试预期结果是hibernate自动帮助在数据库中创建数据表,结果JUnit单元测试没有问题,在控制台打印了创建数据表的SQL语句,但在数据库中
Netty源码学习-FrameDecoder
bylijinnan
java netty
Netty 3.x的user guide里FrameDecoder的例子,有几个疑问:
1.文档说:FrameDecoder calls decode method with an internally maintained cumulative buffer whenever new data is received.
为什么每次有新数据到达时,都会调用decode方法?
2.Dec
SQL行列转换方法
chicony
行列转换
create table tb(终端名称 varchar(10) , CEI分值 varchar(10) , 终端数量 int)
insert into tb values('三星' , '0-5' , 74)
insert into tb values('三星' , '10-15' , 83)
insert into tb values('苹果' , '0-5' , 93)
中文编码测试
ctrain
编码
循环打印转换编码
String[] codes = {
"iso-8859-1",
"utf-8",
"gbk",
"unicode"
};
for (int i = 0; i < codes.length; i++) {
for (int j
hive 客户端查询报堆内存溢出解决方法
daizj
hive 堆内存溢出
hive> select * from t_test where ds=20150323 limit 2;
OK
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
问题原因: hive堆内存默认为256M
这个问题的解决方法为:
修改/us
人有多大懒,才有多大闲 (评论『卓有成效的程序员』)
dcj3sjt126com
程序员
卓有成效的程序员给我的震撼很大,程序员作为特殊的群体,有的人可以这么懒, 懒到事情都交给机器去做 ,而有的人又可以那么勤奋,每天都孜孜不倦得做着重复单调的工作。
在看这本书之前,我属于勤奋的人,而看完这本书以后,我要努力变成懒惰的人。
不要在去庞大的开始菜单里面一项一项搜索自己的应用程序,也不要在自己的桌面上放置眼花缭乱的快捷图标
Eclipse简单有用的配置
dcj3sjt126com
eclipse
1、显示行号 Window -- Prefences -- General -- Editors -- Text Editors -- show line numbers
2、代码提示字符 Window ->Perferences,并依次展开 Java -> Editor -> Content Assist,最下面一栏 auto-Activation
在tomcat上面安装solr4.8.0全过程
eksliang
Solr solr4.0后的版本安装 solr4.8.0安装
转载请出自出处:
http://eksliang.iteye.com/blog/2096478
首先solr是一个基于java的web的应用,所以安装solr之前必须先安装JDK和tomcat,我这里就先省略安装tomcat和jdk了
第一步:当然是下载去官网上下载最新的solr版本,下载地址
Android APP通用型拒绝服务、漏洞分析报告
gg163
漏洞 android APP 分析
点评:记得曾经有段时间很多SRC平台被刷了大量APP本地拒绝服务漏洞,移动安全团队爱内测(ineice.com)发现了一个安卓客户端的通用型拒绝服务漏洞,来看看他们的详细分析吧。
0xr0ot和Xbalien交流所有可能导致应用拒绝服务的异常类型时,发现了一处通用的本地拒绝服务漏洞。该通用型本地拒绝服务可以造成大面积的app拒绝服务。
针对序列化对象而出现的拒绝服务主要
HoverTree项目已经实现分层
hvt
编程 .net Web C# ASP.ENT
HoverTree项目已经初步实现分层,源代码已经上传到 http://hovertree.codeplex.com请到SOURCE CODE查看。在本地用SQL Server 2008 数据库测试成功。数据库和表请参考:http://keleyi.com/a/bjae/ue6stb42.htmHoverTree是一个ASP.NET 开源项目,希望对你学习ASP.NET或者C#语言有帮助,如果你对
Google Maps API v3: Remove Markers 移除标记
天梯梦
google maps api
Simply do the following:
I. Declare a global variable:
var markersArray = [];
II. Define a function:
function clearOverlays() {
for (var i = 0; i < markersArray.length; i++ )
jQuery选择器总结
lq38366
jquery 选择器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
基础数据结构和算法六:Quick sort
sunwinner
Algorithm Quicksort
Quick sort is probably used more widely than any other. It is popular because it is not difficult to implement, works well for a variety of different kinds of input data, and is substantially faster t
如何让Flash不遮挡HTML div元素的技巧_HTML/Xhtml_网页制作
刘星宇
html Web
今天在写一个flash广告代码的时候,因为flash自带的链接,容易被当成弹出广告,所以做了一个div层放到flash上面,这样链接都是a触发的不会被拦截,但发现flash一直处于div层上面,原来flash需要加个参数才可以。
让flash置于DIV层之下的方法,让flash不挡住飘浮层或下拉菜单,让Flash不档住浮动对象或层的关键参数:wmode=opaque。
方法如下:
Mybatis实用Mapper SQL汇总示例
wdmcygah
sql mysql mybatis 实用
Mybatis作为一个非常好用的持久层框架,相关资料真的是少得可怜,所幸的是官方文档还算详细。本博文主要列举一些个人感觉比较常用的场景及相应的Mapper SQL写法,希望能够对大家有所帮助。
不少持久层框架对动态SQL的支持不足,在SQL需要动态拼接时非常苦恼,而Mybatis很好地解决了这个问题,算是框架的一大亮点。对于常见的场景,例如:批量插入/更新/删除,模糊查询,多条件查询,联表查询,