腾讯高级面试题:请谈谈Redis 9种数据结构以及它们的内部编码实现

STM32+CubeMX实战:5步搞定LWIP HTTP服务器搭建(附常见编译错误解决) 本文详细介绍了基于STM32和CubeMX平台,快速搭建LWIP HTTP服务器的5步实战指南。内容涵盖从项目初始化、LWIP深度配置到解决经典的`HTTPD_FSDATA_FILE`编译错误,并分享了使用VSCode进行高效开发的工作流,旨在帮助嵌入式开发者快速实现网络功能并规避常见陷阱。 阅读详情

90%的人知道Redis 5种最基本的数据结构,只有不到10%的人知道8种基本数据结构(5种基本+bitmap+GeoHash+HyperLogLog),只有不到5%的人知道9种基本数据结构(5.0最新版本数据结构Streams),只有不到1%的人掌握了所有9种基本数据结构以及8种内部编码,掌握这篇文章的知识点,让你成为面试官眼中Redis方面最靓的仔!

说明:本文基于Redis-3.2.11版本源码进行分析。

5种普通数据结构

这个没什么好说的,对Redis稍微有点了解的都知道5种最基本的数据结构:String,List,Hash,Set,Sorted Set。不过,需要注意的是,这里依然有几个高频面试题。

  • Set和Hash的关系

答案就是Set是一个特殊的value为空的Hash。Set类型操作的源码在t_set.c中。以新增一个元素为例(int setTypeAdd(robj *subject, sds value)),如果编码类型是OBJ_ENCODING_HT,那么新增源码的源码如下,事实上就是对dict即Hash数据结构进行操作,并且dictSetVal时value是NULL:

dictEntry*de=dictAddRaw(ht,value,NULL);
if(de){
dictSetKey(ht,de,sdsdup(value));
dictSetVal(ht,de,NULL);
return1;
}

同样的,我们在t_hash.c中看到Hash类型新增元素时,当判断编码类型是OBJ_ENCODING_HT时,也是调用dict的方法:dictAdd(o->ptr,f,v),dictAdd最终也是调用dictSetVal()方法,只不过v即value不为NULL:

/*Addanelementtothetargethashtable*/
intdictAdd(dict*d,void*key,void*val)
{
dictEntry*entry=dictAddRaw(d,key,NULL);

if(!entry)returnDICT_ERR;
dictSetVal(d,entry,val);
returnDICT_OK;
}

所以,Redis中Set和Hash的关系就很清楚了,当编码是OBJ_ENCODING_HT时,两者都是dict数据类型,只不过Set是value为NULL的特殊的dict。

  • 谈谈你对Sorted Set的理解

Sorted Set的数据结构是一种跳表,即SkipList,如下图所示,红线是查找10的过程:

 

头条高级面试题:请谈谈Redis 9种数据结构以及它们的内部编码实现

SkipList

  • 如何借助Sorted set实现多维排序

Sorted Set默认情况下只能根据一个因子score进行排序。如此一来,局限性就很大,举个栗子:热门排行榜需要按照下载量&最近更新时间排序,即类似数据库中的ORDER BY download_count, update_time DESC。那这样的需求如果用Redis的Sorted Set实现呢?

事实上很简单,思路就是将涉及排序的多个维度的列通过一定的方式转换成一个特殊的列,即result = function(x, y, z),即x,y,z是三个排序因子,例如下载量、时间等,通过自定义函数function()计算得到result,将result作为Sorted Set中的score的值,就能实现任意维度的排序需求了。可以参考笔者之前的文章:《Redis高级玩法:如何利用SortedSet实现多维度排序》。

Redis内部编码

我们常说的String,List,Hash,Set,Sorted Set只是对外的编码,实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis可以在合适的场景选择更合适的内部编码。

如下图所示(图片纠正:intset编码,而不是inset编码),可以看到每种数据结构都有2种以上的内部编码实现,例如String数据结构就包含了raw、int和embstr三种内部编码。同时,有些内部编码可以作为多种外部数据结构的内部实现,例如ziplist就是hash、list和zset共有的内部编码,而set的内部编码可能是hashtable或者intset:

头条高级面试题:请谈谈Redis 9种数据结构以及它们的内部编码实现

Redis内部编码

 

Redis这样设计有两个好处:

  1. 可以偷偷的改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动对外数据结构和命令。
  2. 多种内部编码实现可以在不同场景下发挥各自的优势。例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降。这时候Redis会根据配置选项将列表类型的内部实现转换为linkedlist。

String的3种内部编码

由上图可知,String的3种内部编码分别是:int、embstr、raw。int类型很好理解,当一个key的value是整型时,Redis就将其编码为int类型(另外还有一个条件:把这个value当作字符串来看,它的长度不能超过20)。如下所示。这种编码类型为了节省内存。Redis默认会缓存10000个整型值(#define OBJ_SHARED_INTEGERS 10000),这就意味着,如果有10个不同的KEY,其value都是10000以内的值,事实上全部都是共享同一个对象:

127.0.0.1:6379>setnumber"7890"
OK
127.0.0.1:6379>objectencodingnumber
"int"

接下来就是ebmstr和raw两种内部编码的长度界限,请看下面的源码:

#defineOBJ_ENCODING_EMBSTR_SIZE_LIMIT44
robj*createStringObject(constchar*ptr,size_tlen){
if(len<=OBJ_ENCODING_EMBSTR_SIZE_LIMIT)
returncreateEmbeddedStringObject(ptr,len);
else
returncreateRawStringObject(ptr,len);
}

也就是说,embstr和raw编码的长度界限是44,我们可以做如下验证。长度超过44以后,就是raw编码类型,不会有任何优化,是多长,就要消耗多少内存:

127.0.0.1:6379>setname"a1234567890123456789012345678901234567890123"
OK
127.0.0.1:6379>objectencodingname
"embstr"
127.0.0.1:6379>setname"a12345678901234567890123456789012345678901234"
OK
127.0.0.1:6379>objectencodingname
"raw"

那么为什么有embstr编码呢?它相比raw的优势在哪里?embstr编码将创建字符串对象所需的空间分配的次数从raw编码的两次降低为一次。因为embstr编码的字符串对象的所有数据都保存在一块连续的内存里面,所以这种编码的字符串对象比起raw编码的字符串对象能更好地利用缓存带来的优势。并且释放embstr编码的字符串对象只需要调用一次内存释放函数,而释放raw编码对象的字符串对象需要调用两次内存释放函数。如下图所示,左边是embstr编码,右边是raw编码:

 

头条高级面试题:请谈谈Redis 9种数据结构以及它们的内部编码实现

embstr V.S. raw

 

ziplist

由前面的图可知,List,Hash,Sorted Set三种对外结构,在特殊情况下的内部编码都是ziplist,那么这个ziplist有什么神奇之处呢?

以Hash为例,我们首先看一下什么条件下它的内部编码是ziplist:

  1. 当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个);
  2. 所有值都小于hash-max-ziplist-value配置(默认64个字节);

如果是sorted set的话,同样需要满足两个条件:

  1. 元素个数小于zset-max-ziplist-entries配置,默认128;
  2. 所有值都小于zset-max-ziplist-value配置,默认64。

实际上,ziplist充分体现了Redis对于存储效率的追求。一个普通的双向链表,链表中每一项都占用独立的一块内存,各项之间用地址指针(或引用)连接起来。这种方式会带来大量的内存碎片,而且地址指针也会占用额外的内存。而ziplist却是将表中每一项存放在前后连续的地址空间内,一个ziplist整体占用一大块内存。它是一个表(list),但其实不是一个链表(linked list)。

ziplist的源码在ziplist.c这个文件中,其中有一段这样的描述 -- The general layout of the ziplist is as follows::

<zlbytes><zltail><zllen><entry><entry>...<entry><zlend>
  • zlbytes:表示这个ziplist占用了多少空间,或者说占了多少字节,这其中包括了zlbytes本身占用的4个字节;
  • zltail:表示到ziplist中最后一个元素的偏移量,有了这个值,pop操作的时间复杂度就是O(1)了,即不需要遍历整个ziplist;
  • zllen:表示ziplist中有多少个entry,即保存了多少个元素。由于这个字段占用16个字节,所以最大值是2^16-1,也就意味着,如果entry的数量超过2^16-1时,需要遍历整个ziplist才知道entry的数量;
  • entry:真正保存的数据,有它自己的编码;
  • zlend:专门用来表示ziplist尾部的特殊字符,占用8个字节,值固定为255,即8个字节每一位都是1。

如下就是一个真实的ziplist编码,包含了2和5两个元素:

[0f000000][0c000000][0200][00f3][02f6][ff]
||||||
zlbyteszltailentries"2""5"end

linkedlist

这是List的一种编码数据结构非常简单,就是我们非常熟悉的双向链表,对应Java中的LinkedList。

skiplist

这个前面也已经提及,就是经典的跳表数据结构。

hashtable

这个也很容易,对应Java中的HashMap。

intset

Set特殊内部编码,当满足下面的条件时Set的内部编码就是intset而不是hashtable:

  1. Set集合中必须是64位有符号的十进制整型;
  2. 元素个数不能超过set-max-intset-entries配置,默认512;

验证如下:

127.0.0.1:6379>saddscores135
(integer)0
127.0.0.1:6379>saddscores128
(integer)1
127.0.0.1:6379>objectencodingscores
"intset"

那么intset编码到底是个什么东西呢?看它的源码定义如下,很明显,就是整型数组,并且是一个有序的整型数组。它在内存分配上与ziplist有些类似,是连续的一整块内存空间,而且对于大整数和小整数采取了不同的编码,尽量对内存的使用进行了优化。这样的数据结构,如果执行SISMEMBER命令,即查看某个元素是否在集合中时,事实上使用的是二分查找法:

typedefstructintset{
uint32_tencoding;
uint32_tlength;
int8_tcontents[];
}intset;

// intset编码查找方法源码(人为简化),标准的二分查找法:
staticuint8_tintsetSearch(intset*is,int64_tvalue,uint32_t*pos){
intmin=0,max=intrev32ifbe(is->length)-1,mid=-1;
int64_tcur=-1;

while(max>=min){
mid=((unsignedint)min+(unsignedint)max)>>1;
cur=_intsetGet(is,mid);
if(value>cur){
min=mid+1;
}elseif(value<cur){
max=mid-1;
}else{
break;
}
}

if(value==cur){
if(pos)*pos=mid;
return1;
}else{
if(pos)*pos=min;
return0;
}
}

#defineINTSET_ENC_INT16(sizeof(int16_t))
#defineINTSET_ENC_INT32(sizeof(int32_t))
#defineINTSET_ENC_INT64(sizeof(int64_t))

 

3种高级数据结构

Redis中3种高级数据结构分别是bitmap、GEO、HyperLogLog,针对这3种数据结构,笔者之前也有文章介绍过。其中,最重要的就是bitmap。

bitmap

这个就是Redis实现的BloomFilter,BloomFilter非常简单,如下图所示,假设已经有3个元素a、b和c,分别通过3个hash算法h1()、h2()和h2()计算然后对一个bit进行赋值,接下来假设需要判断d是否已经存在,那么也需要使用3个hash算法h1()、h2()和h2()对d进行计算,然后得到3个bit的值,恰好这3个bit的值为1,这就能够说明:d可能存在集合中。再判断e,由于h1(e)算出来的bit之前的值是0,那么说明:e一定不存在集合中:

头条高级面试题:请谈谈Redis 9种数据结构以及它们的内部编码实现

BloomFilter

需要说明的是,bitmap并不是一种真实的数据结构,它本质上是String数据结构,只不过操作的粒度变成了位,即bit。因为String类型最大长度为512MB,所以bitmap最多可以存储2^32个bit。

GEO

GEO数据结构可以在Redis中存储地理坐标,并且坐标有限制,由EPSG:900913 / EPSG:3785 / OSGEO:41001 规定如下:

  1. 有效的经度从-180度到180度。
  2. 有效的纬度从-85.05112878度到85.05112878度。

当坐标位置超出上述指定范围时,该命令将会返回一个错误。添加地理位置命令如下:

redis>GEOADDcity114.03104022.324386"shenzhen"112.57215422.267832"guangzhou"
(integer)2
redis>GEODISTcityshenzhenguangzhou
"150265.8106"

但是,需要说明的是,Geo本身不是一种数据结构,它本质上还是借助于Sorted Set(ZSET),并且使用GeoHash技术进行填充。Redis中将经纬度使用52位的整数进行编码,放进zset中,score就是GeoHash的52位整数值。在使用Redis进行Geo查询时,其内部对应的操作其实就是zset(skiplist)的操作。通过zset的score进行排序就可以得到坐标附近的其它元素,通过将score还原成坐标值就可以得到元素的原始坐标。

总之,Redis中处理这些地理位置坐标点的思想是:二维平面坐标点 --> 一维整数编码值 --> zset(score为编码值) --> zrangebyrank(获取score相近的元素)、zrangebyscore --> 通过score(整数编码值)反解坐标点 --> 附近点的地理位置坐标。

  • GEOHASH原理

使用wiki上的例子,纬度为42.6,经度为-5.6的点,转化为base32的话要如何转呢?
首先拿纬度来进行说明,纬度的范围为-90到90,将这个范围划为两段,则为[-90,0]、[0,90],然后看给定的纬度在哪个范围,在前面的范围的话,就设当前位为0,后面的话值便为1.然后继续将确定的范围1分为2,继续以确定值在前段还是后段来确定bit的值。就这样慢慢的缩小范围,一般最多缩小13次就可以了(经纬度的二进制位相加最多25位,经度13位,纬度12位)。这时的中间值,将跟给定的值最相近。如下图所示:

头条高级面试题:请谈谈Redis 9种数据结构以及它们的内部编码实现

Geohash

第1行,纬度42.6位于[0, 90]之间,所以bit=1;第2行,纬度42.6位于[0, 45]之间,所以bit=0;第3行,纬度42.6位于[22.5, 45]之间,所以bit=1,以此类推。这样,取出图中的bit位:1011 1100 1001,同样的方法,将经度(范围-180到180)算出来为 :0111 1100 0000 0。结果对其如下:

#经度
0111110000000
#纬度
101111001001

得到了经纬度的二进制位后,下面需要将两者进行结合:从经度、纬度的循环,每次取其二进制的一位(不足位取0),合并为新的二进制数:01101111 11110000 01000001 0。每5位为一个十进制数,结合base32对应表映射为base32值为:ezs42。这样就完成了encode的过程。

Streams

这是Redis5.0引入的全新数据结构,这种数据结构笔者之前也有文章对其进行详细解读,链接地址:《Streams:深入剖析Redis5.0全新数据结构》,用一句话概括Streams就是Redis实现的内存版kafka。而且,Streams也有Consumer Groups的概念。通过Redis源码中对stream的定义我们可知,streams底层的数据结构是radix tree:

typedefstructstream{
rax*rax;/*Theradixtreeholdingthestream.*/
uint64_tlength;/*Numberofelementsinsidethisstream.*/
streamIDlast_id;/*Zeroifthereareyetnoitems.*/
rax*cgroups;/*Consumergroupsdictionary:name->streamCG*/
}stream;

那么这个radix tree长啥样呢?在Redis源码的rax.h文件中有一段这样的描述,这样看起来是不是就比较直观了:

*(f)""
*/
*(io)"f"
*/\
*"firs"("rst")(o)"fo"
*/\
*"first"[][tb]"foo"
*/\
*"foot"("er")("ar")"foob"
*/\
*"footer"[][]"foobar"

Radix Tree(基数树) 事实上就几乎相同是传统的二叉树。仅仅是在寻找方式上,以一个unsigned int类型数为例,利用这个数的每个比特位作为树节点的推断。能够这样说,比方一个数10001010101010110101010,那么依照Radix 树的插入就是在根节点,假设遇到0,就指向左节点,假设遇到1就指向右节点,在插入过程中构造树节点,在删除过程中删除树节点。如下是一个保存了7个单词的Radix Tree:

头条高级面试题:请谈谈Redis 9种数据结构以及它们的内部编码实现

素质三连后可私信"学习”免费获取更多资料

[Dify] 实现“多知识库切换”功能的最佳实践 知识库切换是提升AI问答系统精准度的关键技术。本文介绍了Dify平台实现多知识库切换的三种方式:静态配置、元数据过滤和动态切换,分析了各自的优缺点。最佳实践建议包括:合理分库设计、意图分类、主库优先检索等。文章还提供了示例工作流程和注意事项,帮助构建更智能、精准的知识驱动型问答系统。通过合理切换知识库,可显著提升回答相关性和系统性能。 阅读详情

相关推荐

DCDC BUCK开关电源PCB设计

在开关电源中,BUCK(降压)电路、BOOST(升压)电路以及BUCK - BOOST(升降压)三种电路是最基本的拓扑结构。转换器又分DCDC(直流转直流)和ACDC(交流转直流),DCDC装换器结构无疑是比ACDC转换器结构简单,所以从DCDC转换器结构入手学习开关电源是一种很好的选择。本文主要从应用角度,进行相关器件的选型计算以及PCB绘制讲解DCDC 12V转5Vbuck电路。

2301_78342510的博客 6888

【Redis源码】字符串详解(七)

前言: 学过C的人应该都知道C的字符串是以字节数组存在,然后以\0结尾。计算字符串的长度使用strlen函数,这个标准库函数的复杂程度是O(n)。它需要对字节数组进行扫描遍历计算长度。作为redis单线程的应用是这种形式是比较消耗性能的。 Redis实现了字节的字符串叫sds(Simple Dynamic String),它是一个带着长度的信息的结构体,属于柔性字符串。 版本:redis...

c-rain 580

三角洲行动交易行自动化脚本

DFMarketBot - 三角洲行动自动交易助手 DFMarketBot是一款专为三角洲行动游戏设计的交易行自动化工具,通过OCR识别和鼠标模拟实现自动补卡、补子弹功能。项目采用Python开发,支持Windows平台,主要功能包括: 自动检测并购买指定物品(房卡/子弹) 价格监控与智能购买(低于设定价格自动下单) 自定义购买数量与次数限制 支持窗口/无窗口两种游戏模式 使用前需安装Tesseract OCR引擎并配置游戏为1920*1080分辨率。通过JSON文件可灵活配置监控物品清单、理想价格和购买策

愤怒的阿木木的博客 3万+

c语言读取redis中的数据类型,《闲扯Redis二》String数据类型之底层解析

一、前言Redis 提供了5种数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要。二、疑问与解析结构图上显示,String类型有三种实现方式:使用整数值实现的字符串对象使用 embstr 编码的动态字符串实现的字符串对象动态字符串实现的字符串对象疑问:embstr 是什么意思,动态字符...

weixin_31282459的博客 359

DDS信号发生器设计避坑指南:从AD9834配置到巴特沃斯滤波实战

本文详细解析了基于AD9834芯片的DDS信号发生器设计中的关键技术要点与常见陷阱,涵盖时钟源选择、寄存器配置时序、巴特沃斯滤波器设计等核心内容。针对中高频段信号质量优化,提供了实用的解决方案和代码示例,帮助工程师规避设计误区,提升信号发生器的性能和稳定性。

2y3u4i5o6p的博客 786

车载仪表-功能点测试大全(超详细,细分可作测试用例)

汽车仪表系统发展经历了机械式、电气化到智能化的演变,目前全液晶仪表渗透率达73.4%。文章详细梳理了仪表功能测试要点,包括UI界面显示一致性、按键响应、FM收音、信号灯显示、USB功能、蓝牙连接、胎压监测、导航系统、WiFi投屏、倒车影像及多媒体播放等关键功能模块的测试标准。特别关注界面切换流畅度、功能稳定性及异常情况处理能力,如投屏状态下是否卡顿、导航中断后能否自动恢复等。测试覆盖了CarPlay、AndroidAuto等主流投屏方案的兼容性验证,确保各类交互场景下的系统可靠性。

weixin_51551002的博客 2069

腾讯面试算法题——编码

题目描述 假定一种编码的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy 其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。 编写一个函数,输...

Shayne_S的专栏 6620

EWM与SAP ERP的数据集成

1、EWM与 SAPERP的无缝集成-基础数据&业务交易数据 2、SAP ERP设置:连接SAP ERP和EWM必须设置应用程序连接支持-ALE(Application Link Enabling) 3、ERP - EWM仓库数据集成: SAP ERP需要设置配置信息,连接ERP和EWM之间的库存管理应用,基于工厂+库存地点对应一个仓库号来进行配置; 在ERP中需要创建一个中间虚拟仓库,代表ERP仓库;“中间虚拟”仓库创建之后,工厂+库存地点的信息...

weixin_43899798的博客 3797

Redis数据编码方式详解

引言 Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove以及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。...

weixin_34345753的博客 1051

BUCK降压斩波电路设计实战:从IGBT选型到续流二极管优化

本文详细解析了BUCK降压斩波电路的设计实战,从IGBT选型到续流二极管优化,涵盖了关键参数设计、调试技巧及电磁兼容问题解决方案。通过实际案例和数据对比,帮助工程师高效完成DC-DC转换电路设计,提升系统性能和可靠性。

weixin_29253711的博客 96

Keil中搭建自动化单元测试框架Unity

前言:   虽然一些C++的自动化单元测试框架也能用来C语言单元测试,但那样我们编写C语言程序时需要符合C++的标准,这样有一些C的特性是无法使用的,限制C的特性使用不太好,于是找了一个全部用C实现的自动化测试框架。Unity是一个简单且直接的自动化单元测试框架,它由很少的几个文件构成。 搭建环境:   1.从github上下载最新版本的Unity源码,下载链接:https://github...

程序员的自我修炼 3900

zset获取指定score_Redis(八):zset/zadd/zrange/zrembyscore 命令源码解析

前面几篇文章,我们完全领略了redis的string,hash,list,set数据类型的实现方法,相信对redis已经不再神秘。本篇我们将介绍redis的最后一种数据类型: zset 的相关实现。本篇过后,我们对redis的各种基础功能,应该不会再有疑惑。有可能的话,我们后续将会对redis的高级功能的实现做解析。(如复制、哨兵模式、集群模式)回归本篇主题,zset。zset 又称有序集合(so...

weixin_39762441的博客 1959

一文吃透 ABAP RESTful Application Programming Model(RAP):从数据建模与行为,到业务服务暴露,再到服务消费

本文介绍了SAP ABAP统一编程模型RAP的核心架构与实践方法,通过构建完整的ZTRAVEL和ZBOOKING业务对象,演示了从数据建模、行为定义到服务暴露的全流程。文章详细说明了RAP三层架构(数据与行为层、服务提供层、服务消费层)的实现方式,包括CDS视图实体定义、行为定义(BDEF)中的事务能力声明、投影与服务绑定等关键步骤。特别强调了ABAP Cloud环境下的开发限制和最佳实践,如使用GUID和late numbering机制,以及如何通过EML语言操作业务对象。最后提供了完整的代码示例,展示了

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 523

常用的数据结构及内部实现远离_腾讯高级面试题:请谈谈Redis9种数据结构以及它们的内部编码实现...

90%的人知道Redis 5种最基本的数据结构,只有不到10%的人知道8种基本数据结构(5种基本+bitmap+GeoHash+HyperLogLog),只有不到5%的人知道9种基本数据结构(5.0最新版本数据结构Streams),只有不到1%的人掌握了所有9种基本数据结构以及8种内部编码,掌握这篇文章的知识点,让你成为面试官眼中Redis方面最靓的仔!说明:本文基于Redis-3.2.11版本源...

weixin_42172204的博客 205

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

面试阿里问的Redis问题难到怀疑人生?看完这些技术点直呼“就这“?

其中横轴是连接数,纵轴是 QPS,有兴趣的同学可以去尝试一下 Redis 的基准测试程序。但是除了高性能之外,Redis 还有一个重要的优点,它的版本更新速度很快,并且功能也越来越强大。比如之前只有 5 种数据类型,而到现在已经有 9 种数据类型。之前最常用的功能是把它作为缓存数据库,而现在你可以使用它来实现消息队列了。比如之前只能单机模式运行,现在已经发展新增了集群模式运行了;

the shy 107

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

go每日新闻(2021-04-29)——QUIC 协议在蚂蚁落地综述

每日一谚: Keep Your APIs Concurrency-Free. go中文网每日资讯--2021-04-29 一、Go语言中文网 Go 切片的一种有趣内存泄漏方式 Go 切片的一种有趣内存泄漏方式 二、亚军进化史 Go技术日报(2021-04-28)——在Go中,你犯过这些错误吗 三、码农桃花源 QUIC 协议在蚂蚁落地综述 KubeSphere 3.1.0 GA:混合多云走向边缘,让应用无处不在 四、腾讯技术 “鹅厂老司机”谈破局:做自己的破壁人 五、polarisxu G.

韩亚军的博客 838

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

面试数据结构试题

链表: 1、找出单链表的倒数第K个元素(仅允许遍历一遍链表) 答:使用指针追赶的方法,定义一个fast指针和一个slow指针,fast指针先走K步,然后fast和slow同时继续走。当fast指针走到链表尾部时,slow指向的位置就是倒数第K个元素。注意:要考虑链表长度应该大于K。参考:剑指Offer(十四):链表中倒数第k个结点 2、找出单链表的中间元素(仅允许遍历一遍链表)...

4222

腾讯笔试和面试

由于近来有些人都问我腾讯笔试和面试到底是考什么,问什么,所以就灌下这篇水文,也算是我自己复习一遍以及给有兴趣或者后来者嗤鼻一笑的机会:)其实应聘内容也真的很难说清楚,而且我也不知道我所经历的是不是有代表性,何况我还是找工作的新手(本科也没找过工作,之前也只是应聘过华为),所以如果下文有什么疏漏之处,尽管踩我好了:)1。笔试我想腾讯的笔试还是比较适中的,虽然广度与深度都不够,但是毕竟因为它只是笔试,

雨中怡然 3577

Redis原理(二) Redis的对象类型及其内部编码

Redis 支持 5 种对象类型,而每种结构都有至少两种编码。 这样做的好处在于:一方面接口与实现分离,当需要增加或改变内部编码时,用户使用不受影响,另一方面可以根据不同的应用场景切换内部编码,提高效率。 Redis 各种对象类型支持的内部编码官网描述: Strings can be encoded as raw (normal string encoding) or int (strings ...

不能说的秘密的博客 1487

redis源码解读(八):redis对象

近来在研读redis3.2.9的源码,虽然网上已有许多redis的源码解读文章,但大都不成系统,且纸上学来终觉浅,遂有该系列博文。部分知识点参照了黄建宏的《Redis设计与实现》。 定义 在自定义的基础数据结构的基础上,redis 通过 redisObject 封装整合成了对外暴露的5中数据结构。 首先看看 redisObject 的定义: #define LRU_BITS 24

czrzchao的博客 829

Redis源码学习简记(七)object原理与个人理解

        object是redis中的封装系统。其把string,list,set,zset与hash封装成一个统一的对象,命名为robj。该数据结构中,存储了类型,编码,引用次数,数据与LRU替换算法的一些数据。具体先看看这个数据结构的定义,在server.h中定义。 //redis属于key-value 数据库 //nosql数据库,这种映射关系使用dict用来维护 //而dict实...

菜鸟的学习之路 856

redis string robj(int,raw,embstr)之 embstr 类型大小限制44字节由来

1 首先robj所占内存认知16Byte // 总共占用16Byte= 4bit + 4bit + 24bit(lru) + refcount 4Byte + *ptr 8Byte typedef struct redisObject { unsigned type:4; // 4bit unsigned encoding:4; // 4bit unsigned lru:LRU_BITS; /* LRU time (relative to global ...

qfzhangwei的专栏 651

Redis学习之zremrangebyrank命令

目录zremrangebyrank命令语法返回值例子 zremrangebyrank命令 Redis zremrangebyrank, 命令用于移除有序集中,指定排名(rank)区间内的所有成员。 区间分别以下标参数 start 和 stop 指出,包含 start 和 stop 在内。 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 ...

爱喝水的qdy的博客 2077

[redis数据库问题] 聊聊你对redis的理解

从Redis的特性来说:①redis数据库是一种非关系型数据库,数据以key-value的形式存储,②它是内存型数据库,数据保存在内存中,所以读写速度很快。③当然它也支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用,以保证数据的安全。④Redis不仅仅支持简单的key-value类型的数据,同时还提供l...

simuLeo的博客 1510

linux基础知识

1.信号 信号是软件中断,提供了一种处理异步事件的方法 unix信号机制最简单的接口是signal函数 /* * sign 信号整型 * func 函数指针 * return :函数指针(一个函数地址,函数有一个整型参数,无返回值) */ void (* signal(int sign,void (*func)(int))) (int) // 其他的表达方式 typedef void signfunc(int); signfunc *signal(int ,signfunc); type

GeekDengshuo 1114

redis的5种数据结构,在java中的表现形式

package com.mytest.controller; import java.util.List; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import or...

qazwsx081的专栏 520
上一篇: Sprinig Boot实现接口幂等性,看完居然发现这么简单,纯干货!
下一篇: 就这?Dataway让SpringBoot不需要Controller、Service、DAO等了
Java斗帝之路
博客等级 码龄7年 2392粉丝 687原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值