源码分析常见问题

Android 代码中的常见的问题总结 新参与一个项目之中,分配了一个任务很快完成后就开始读团队中其余队友的代码,算是熟悉一下项目的整体流程及实现方式。并且在读代码的过程中发现了不少的问题或者毛病,在此进行总结以勉励自己不要犯这种低级的错误。(我保持着经常阅读自己代码并修改重构自己代码的习惯,因为在你某一时刻完成工作任务的时候,感觉当时自己代码写的很完美,这是正常的现象---完成功能后的自我满足感!不过如果你过段时间再次看自己当初以为写 阅读详情

一、ArrayList

1、用数组存储数据
2、默认容量是10
3、容量不够时,创建新的一个数组,并且容量为原来的1.5倍(* old+(old<<1)* ,并将原来的data复制到新的数组里,原来的那个被垃圾回收。
4、非线程安全
5、clone()方法是浅克隆,只是创建一个新的数组,但是数据=引用


二、LinkedList

1、用链表存储数据
2、是List和Deque接口的双向链表的实现,它可以被当作堆栈、队列或双端队列进行操作
3、不是线程安全的
4、clone()方法——浅复制


三、HashMap

1、传统HashMap的缺点:

在JDK1.6中,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个数组中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用数组+链表+红黑树实现,当链表长度超过阈值8时,将链表转换为红黑树,这样大大减少了查找时间。

2、基本元素默认值

(1)默认初始容量 = 16(容量为HashMap中槽的数目),且实际容量必须是2的整数次幂。
(2)最大容量 = 1 << 30(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换)
(3)装填因子 = 0.75,如果当前键值对个数 >= HashMap最大容量*装填因子,进行rehash操作
(4)Entry链表最大长度 = 8,当桶中节点数目大于该长度时,将链表转成红黑树存储(JDK1.8 新加)
(5)红黑树最小节点数 = 6,当桶中节点数小于该长度,将红黑树转为链表存储;
(6)桶可能被转化为树形结构的最小容量 = 64,当哈希表的大小超过这个阈值,才会把链式结构转化成树型结构,否则仅采取扩容来尝试减少冲突。应该至少 4*Entry链表最大长度(8) 来避免扩容和树形结构化之间的冲突。
(7)HashMap的扩容阈值 ,默认=16,在HashMap中存储的Node键值对超过这个数量时,自动扩容容量为原来的二倍
(8)JDK1.6用Entry描述键值对,JDK1.8中用Node代替Entry

// hash存储key的hashCode
final int hash;
// final:一个键值对的key不可改变
final K key;
V value;
//指向下个节点的引用
Node<K, V> next;

3、将链表转化为红黑树

HashMap中键值对的存储形式为链表节点,hashCode相同的节点(位于同一个桶)用链表组织,链表长度超过8(默认)则转换成红黑树。

4、hash()方法:

static final int hash(Object key) {
    int h;
    //计算key的hashCode, h = Objects.hashCode(key)
    //h >>> 16表示对h无符号右移16位,高位补0,然后h与h >>> 16按位异或
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
//相当于key的hash值高16位不变,低16位与高16位异或作为key的最终hash值。

为什么不能直接用key的哈希值?
这个与HashMap中table下标的计算有关。

n = table.length;
index = (n-1) & hash;
//(n - 1) & hash 本质上是hash % n,位运算更快

因为,table的长度都是2的幂,因此index仅与hash值的低n位有关,hash值的高位都被与操作置为0了。 直接用key的哈希值,很容易产生碰撞。将高16位与低16位异或来减少这种碰撞概率。

5、构造函数初始化容量不一定是传入的参数,初始化容量是大于等于该给定整数的最小2^次幂值。拓容的时候也会调用下面的函数。

//结果为>=cap的最小2的自然数幂
static final int tableSizeFor(int cap) {
         //先移位再或运算,最终保证返回值是2的整数幂
         int n = cap - 1;
         n |= n >>> 1;
         n |= n >>> 2;
         n |= n >>> 4;
         n |= n >>> 8;
         n |= n >>> 16;
         return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
 178     }

6、根据key的哈希值和key获取对应的节点

getNode可分为以下几个步骤:
1.如果哈希表为空,或key对应的桶为空,返回null
2.如果桶中的第一个节点就和指定参数hash和key匹配上了,返回这个节点。
3.如果桶中的第一个节点没有匹配上,而且有后续节点
3.1如果当前的桶采用红黑树,则调用红黑树的get方法去获取节点:查找时基本就是折半查找,效率很高。
3.2如果当前的桶不采用红黑树,即桶中节点结构为链式结构,遍历链表,直到key匹配
4.找到节点返回null,否则返回null。

注:匹配hash值用==,匹配key用equals方法。

7、将指定参数key和指定参数value插入map中,如果key已经存在,那就替换key对应的value

put(K key, V value)可以分为三个步骤:
1.通过hash(Object key)方法计算key的哈希值。
2.通过putVal(hash(key), key, value, false, true)方法实现功能。
3.返回putVal方法返回的结果。

putVal方法可以分为下面的几个步骤:
1.如果哈希表为空,调用resize()创建一个哈希表。
2.如果指定参数hash在表中没有对应的桶,即为没有碰撞,直接将键值对插入到哈希表中即可。
3.如果有碰撞,遍历桶,找到key映射的节点
3.1桶中的第一个节点就匹配了,将桶中的第一个节点记录起来。
3.2如果桶中的第一个节点没有匹配,且桶中结构为红黑树,则调用红黑树对应的方法插入键值对。
3.3如果不是红黑树,那么就肯定是链表。遍历链表,如果找到了key映射的节点,就记录这个节点,退出循环。如果没有找到,在链表尾部插入节点。插入后,如果链的长度大于TREEIFY_THRESHOLD这个临界值,则使用treeifyBin方法把链表转为红黑树。
4.如果找到了key映射的节点,且节点不为null
4.1记录节点的vlaue。
4.2如果参数onlyIfAbsent为false,或者oldValue为null,替换value,否则不替换。
4.3返回记录下来的节点的value。
5.如果没有找到key映射的节点(2、3步中讲了,这种情况会插入到hashMap中),插入节点后size会加1,这时要检查size是否大于阈值threshold,如果大于会使用resize方法进行扩容。
这里写图片描述

8、resize()方法

对table进行初始化或者扩容。
如果对table扩容,因为每次扩容都是翻倍,与原来计算(n-1)&hash的结果相比,节点要么就在原来的位置,要么就被分配到“原位置+旧容量”这个位置

resize的步骤总结为:
1.计算扩容后的容量,临界值threshold。

  • 如果原来的数组长度大于最大值2^30:oldCap >= MAXIMUM_CAPACITY,则threshold = Integer.MAX_VALUE;并且无法拓容,返回原来的数组
  • 如果现在数组长度的两倍小于MAXIMUM_CAPACITY且现在的容量大于DEFAULT_INITIAL_CAPACITY(16), 临界值变为原来的2倍:lnewThr = oldThr << 1;
  • 如果旧数组长度<= 0,而且旧临界值threshold > 0,数组的新容量设置为老数组扩容的临界值
  • 如果旧数组长度 <= 0,且旧临界值 <= 0,新容量扩充为默认初始化容量,新临界值为DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY

2.将hashMap的临界值修改为扩容后的临界值 threshold = newThr;
3.根据扩容后的容量新建数组,然后将hashMap的table的引用指向新数组。
4.如果旧table不为空,将旧table中的元素复制到新的table中。

  • oldTab[j]放入newTab中e.hash & (newCap - 1)的位置
  • 如果旧桶中的结构为链表,resize时,对原有的元素根据hash值重新就算索引位置,重新安放所有对象(1.6)而且,先放在一个索引上的元素终会被放到Entry链的尾部
  • 在1.8中,对链表重拍做了一系列优化,链表元素相对位置没有变化。它并没有重新计算元素在数组中的位置,而是采用了 原始位置加原数组长度的方法计算得到位置
e = oldTab[j];
if(e.hash & oldCap)==0 //原位置
    newTab[j] = e;
else{ 
    newTab[j + oldCap] = e;//原始位置加原数组长度
}
  • 如果旧桶中的结构为红黑树,将树中的node分离:循环遍历整棵树,对于每个节点判断是在index还是index+bit; 指定位置index或者 index + bit 之后的元素,指向 hXXX 还原成链表或者修剪过的树;如果 lXXX 树的数量小于 6,则还原成链表

9、将链表转化为红黑树

  • 根据哈希表中元素个数确定是扩容还是树形化
  • 如果是树形化
    遍历桶中的元素,创建相同个数的树形节点,复制内容,建立起联系
    然后让桶第一个元素指向新建的树头结点,替换桶的链表内容为树形内容 JDK 1.8 以后哈希表的 添加、删除、查找、扩容方法都增加了一种 节点为 TreeNode 的情况:

10、clone()

浅拷贝。
clone方法虽然生成了新的HashMap对象,新的HashMap中的table数组虽然也是新生成的,但是数组中的元素还是引用以前的HashMap中的元素。
这就导致在对HashMap中的元素进行修改的时候,即对数组中元素进行修改,会导致原对象和clone对象都发生改变,但进行新增或删除就不会影响对方,因为这相当于是对数组做出的改变,clone对象新生成了一个数组。

11、序列化

writeObject(java.io.ObjectOutputStream s)
序列化hashMap到ObjectOutputStream中
将hashMap的总容量capacity、实际容量size、键值对映射写入到ObjectOutputStream中。键值对映射序列化时是无序的。

readObject(java.io.ObjectInputStream s)
将hashMap的总容量capacity、实际容量size、键值对映射读取出来

11、总结

添加时,当桶中链表个数超过 8 时会转换成红黑树;
删除、扩容时,如果桶中结构为红黑树,并且树中元素个数太少的话,会进行修剪或者直接还原成链表结构;
查找时即使哈希函数不优,大量元素集中在一个桶中,由于有红黑树结构,性能也不会差。

四、HashTable

1、Hashtable存储的内容是键值对(key-value)映射,其底层实现是一个Entry数组+链表;
2、Hashtable和HashMap一样也是散列表,存储元素也是键值对;
3、HashMap允许key和value都为null,而Hashtable都不能为null,Hashtable中的映射不是有序的;
4、Hashtable和HashMap扩容的方法不一样,Hashtable中数组默认大小11,扩容方式是 old*2+1。
5、Hashtable继承于Dictionary类(Dictionary类声明了操作键值对的接口方法),实现Map接口(定义键值对接口);
6、Hashtable大部分类用synchronized修饰,证明Hashtable是线程安全的。


五、ConcurrentHashMap

JDK.6与1.7

1、采用了分段锁的设计,由于不是对整个Map加锁。分段锁称为Segment。2、ConcurrentHashMap中的HashEntry的value以及next都被volatile修饰,保持它们的可见性。
3、默认的并发度为16,即同时可以加16个segment。当用户设置并发度时,ConcurrentHashMap会使用大于等于该值的最小2幂指数作为实际并发度。
其他默认参数同hashmap,初始容量=16,拓展因子=0.75,树转链表的阀值=8,链表转树的阀值=6
4、如果并发度设置的过小,会带来严重的锁竞争问题;如果并发度设置的过大,原本位于同一个Segment内的访问会扩散到不同的Segment中,CPU cache命中率会下降,从而引起程序性能下降。(文档的说法是根据你并发的线程数量决定,太多会导性能降低)

5、put()
(1)在真正申请锁之前,put方法会通过tryLock()方法尝试获得锁,在尝试获得锁的过程中会对对应hashcode的链表进行遍历,如果遍历完毕仍然找不到与key相同的HashEntry节点,则为后续的put操作提前创建一个HashEntry。当tryLock一定次数后仍无法获得锁,则通过lock申请锁。
之所以在获取锁的过程中对整个链表进行遍历,主要目的是希望遍历的链表被CPU cache所缓存,为后续实际put过程中的链表遍历操作提升性能。
(2)在获得锁之后,Segment对链表进行遍历,如果某个HashEntry节点具有相同的key,则更新该HashEntry的value值,否则新建一个HashEntry节点,将它设置为链表的新head节点并将原头节点设为新head的下一个节点。新建过程中如果节点总数(含新建的HashEntry)超过threshold,则调用rehash()方法对Segment进行扩容,最后将新建HashEntry写入到数组中。

6、remove()
和put类似,remove在真正获得锁之前,也会对链表进行遍历以提高缓存命中率。

7、get()、containsKey()
两个方法几乎完全一致:他们都没有使用锁,而是通过Unsafe对象的getObjectVolatile()方法提供的原子读语义,来获得Segment以及对应的链表,然后对链表遍历判断是否存在key相同的节点以及获得该节点的value。但由于遍历过程中其他线程可能对链表结构做了调整,因此get和containsKey返回的可能是过时的数据,这一点是ConcurrentHashMap在弱一致性上的体现。如果要求强一致性,那么必须使用Collections.synchronizedMap()方法。

8、size()、containsValue()
首先不加锁循环执行以下操作:循环所有的Segment(通过Unsafe的getObjectVolatile()以保证原子读语义),获得对应的值以及所有Segment的modcount之和。如果连续两次所有Segment的modcount和相等,则过程中没有发生其他线程修改ConcurrentHashMap的情况,返回获得的值。

当循环次数超过预定义的值时,这时需要对所有的Segment依次进行加锁,获取返回值后再依次解锁。值得注意的是,加锁过程中要强制创建所有的Segment,否则容易出现其他线程创建Segment并进行put,remove等操作。

对于containsValue方法来说,如果在循环过程中发现匹配value的HashEntry,则直接返回true。

ConcurrentHashMap并不允许key或者value为null

JDK1.8

1、1.8中摒弃了Segment(锁段)的概念,而采用CAS和synchronized来保证并发安全。底层依然由“数组”+链表+红黑树的方式思想(JDK7与JDK8中HashMap的实现),但是为了做到并发,又增加了很多辅助的类,例如TreeBin,Traverser等对象内部类。

2、sizeCtl属性

负数代表正在进行初始化或扩容操作
-1代表正在初始化
-N 表示有N-1个线程正在进行扩容操作
正数或0代表hash表还没有被初始化,这个数值表示初始化或下一次进行扩容的大小,这一点类似于扩容阈值的概念。还后面可以看到,它的值始终是当前ConcurrentHashMap容量的0.75倍,这与loadfactor是对应的。

3、重要的类
(1)Node。最核心的内部类,它对value和next属性设置了volatile同步锁
(2)TreeNode。与HashMap不相同的是,它并不是直接转换为红黑树,而是把这些结点包装成TreeNode放在TreeBin对象中,由TreeBin完成对红黑树的包装。
(3)TreeBin。包装的很多TreeNode节点。它代替了TreeNode的根节点,也就是说在实际的ConcurrentHashMap“数组”中,存放的是TreeBin对象,而不是TreeNode对象,这是与HashMap的区别。另外这个类还带有了读写锁。

4、更新元素putVal()
更新元素是使用CAS机制更新,需要不断的失败重试,直到成功为止。
1 判断Node[]数组是否初始化,没有则进行初始化操作
2 通过hash定位Node[]数组的索引坐标,是否有Node节点,如果没有则使用CAS进行添加(链表的头结点),添加失败则进入下次循环。
3 检查到内部正在扩容,如果正在扩容,就帮助它一块扩容。
4 如果f!=null,则使用synchronized锁住f元素(链表/红黑二叉树的头元素)
4.1 如果是Node(链表结构)则执行链表的添加操作。
4.2 如果是TreeNode(树型结果)则执行树添加操作。
5 判断链表长度已经达到临界值8 就需要把链表转换为树结构。

5、size()

final long sumCount() { 
    CounterCell[] as = counterCells; 
    CounterCell a; 
    long sum = baseCount; 
    if (as != null) { 
        for (int i = 0; i < as.length; ++i) { 
        if ((a = as[i]) != null) 
            sum += a.value; 
        } 
    } 
return sum; 
}

JDK1.8中使用一个volatile类型的变量baseCount记录元素的个数,当插入新数据put()或则删除数据remove()时,会通过addCount()方法更新baseCount。counterCells存储的都是value为1的CounterCell对象,而这些对象是因为在CAS更新baseCounter值时,由于高并发而导致失败,最终将值保存到CounterCell中,放到counterCells里。这也就是为什么sumCount()中需要遍历counterCells数组,sum累加CounterCell.value值了。

AnyQ:基于常见问题的问答系统 任意Q AnyQ(回答您的问题)开源项目主要包含面向FAQ集合的问答系统框架,文本语义匹配工具SimNet。问答系统框架采用了配置化,插件化的设计,各功能均通过插件形式加入,当前共开放了20+种插件。开发者可以使用AnyQ系统快速构建和定制适用于特定业务场景的常见问题解答系统,并加速解码和升级。 SimNet是百度自然语言处理部于2013年自主研发的语义匹配框架,该框架在百度各产品上广泛应用,主要包括BOW,CNN,RNN,MM-DNN等核心网络结构形式,同时基于该框架也集成了学术界主流的语义匹配模型,如Match金字塔,MV-LSTM,K-NRM等模型。SimNet使用PaddleFluid和Tensorflow实现,可方便实现模型扩展。 AnyQ系统的语义匹配能力() 详细介绍 常见问题解答系统框架 AnyQ系统框架主要由问题分析,检索,匹配,重新排名等部分组成,框架中包含的功能均通 立即下载

相关推荐

FAQ:常见问题的小问答

常见问题解答:快来试试吧hackintosh ??? 本韦努托! Questa guidaèun正在进行中。 Se vuoi aggiungere qualcosa fai un pool请求oppure segnala con un issue Mi sono perso ... Cosa mi是否根据Hackintosh的票价提供服务? 根据价格,从以下方面进行分析: 硬件兼容的macOS 卸载程序Cl || er oppure OpenCore)。 埃索里奇德(Esso richiede): 简短说明中的Dei KErnel Extensions(可扩展性,可兼容)。 使用OpenCore的Degli SSDT(根据每个mappatura delle USB的英语电源管理) 在Mac OS X上可用的USB磁盘容量为16 GB,在Windows上不能使用USB磁盘。 M

代码设计过程中的常见缺陷

最近review同事的代码发现很多常见的缺陷,总结自己代码遇到过的问题,写了以下十点:   1、代码缺少注释;硬编码、常量没有说明含义。这是代码中常见的小问题。   源文件前面没有概要介绍,包括作者,时间,功能说明等。   2、在java代码中建议使用模板类List&lt;string&gt;代替非模板类Array。   因为使用List&lt;string&gt;可以知道list里面的类型,...

东拉西扯到天明 1781

HTML聚美优品常见问题源代码

HTML聚美优品常见问题源代码

Zepto源码分析项目常见问题解决方案

Zepto源码分析项目常见问题解决方案 1. 项目基础介绍和主要编程语言 项目介绍: Zepto源码分析项目是一个开源的GitHub项目,该项目主要对Zepto这个流行的JavaScript库的源码进行详细的解析和学习。Zepto是一个轻量级的、针对现代浏览器的JavaScript库,它提供了简洁的API来简化DOM操作、事件处理、AJAX请求等常见的前端开发任务。通过该项目,开发者可以深入理解Z...

gitblog_00401的博客 476

YOLOv8使用设备摄像头实时监测

YOLOv8使用设备摄像头实时监测

Joining667的博客 4188

CocosCreator | 自定义启动页之H5

01 效果对比 默认启动页: 自定义启动页: 02 启动页存在的意义 我们在 creator 中的开发的游戏都是基于 cocos engine,所以在展示我们的游戏之前,是必须要先加载 cocos engine,然后才是我们自己的业务代码 流程图如下: 而构建完成后未精简的 cocos engine 代码为 1.9M 如果再加上物理相关代码的话,一共是2M 别忘了,我们自己的首场景也要加载过程哦 所以,从游戏启动,到真...

Valiancer 5899

SpringBoot源码分析项目常见问题解决方案

SpringBoot源码分析项目常见问题解决方案 1. 项目基础介绍和主要编程语言 本项目是基于SpringBoot框架的源码分析项目,主要目的是深入理解SpringBoot的底层实现机制。项目包含了SpringBoot的启动过程、容器的refresh过程、条件注解的底层实现、内置Servlet容器、可执行文件解析、工厂加载机制、配置环境的构造过程、日志系统的构造等内容。主要编程语言为Java。 ...

gitblog_00419的博客 406

LayaBox CommandBuffer描边使用详细

项目需要使用LayaBox做一个给3D物体动态描边的一个功能,前前后后踩了一些坑算是把这个东西给做出来了把我改好的代码贴上,分享给大家。 (1)想要使用描边你的引擎版本必须 >=2.9.0 (2)你必须下载 Laya官方的BlurShader库才能使用这个功能,下载地址:https://github.com/layabox/layaair-demo/tree/master/h5/3d/ts/LayaAir3D_PostProcess/BlurShader 下载完之后把BlurShader放到自己项目的

小智队长 1735

opengl 源码分析常见问题

想必大家都困惑 显存是在什么时候分配的,我们c,c++分配一般会调用new,malloc,但是opengl从头到尾接口也没有看到,gl什么alloc,gl什么new之类的函数,这个我从学习opengl以来,十分困惑,接下来我就重点讲述下纹理是如何分配显存的。通过上边代码分析,我们可以明确的得出结论,就是无论画屏幕,还是画纹理,本质都是对其绑定surface 做处理,也就是说FBO id是0号,就是画屏幕,非0号,就是绑定了其他的纹理或者renderbuffer。...

c553110519的专栏 1995

告别VLC!用Python+OpenCV实时拉取RTSP监控流,并实现抽帧降低延迟(附完整代码)

本文介绍了一种基于Python和OpenCV的低延迟RTSP监控流处理方案,通过抽帧技术显著降低延迟并保持视频分析准确性。文章详细讲解了RTSP流处理的基础挑战、抽帧技术原理与实现,以及完整的低延迟处理方案,包括硬件加速配置和动态抽帧算法,帮助开发者优化监控视频流处理性能。

weixin_30333885的博客 275

AD9361 FIR 滤波器设计

matlab 得到滤波器系数

weixin_44630490的博客 1万+

《一本小小的MyBatis源码分析书》附属项目常见问题解决方案

《一本小小的MyBatis源码分析书》附属项目常见问题解决方案 1. 项目基础介绍和主要编程语言 本项目是《一本小小的MyBatis源码分析书》的附属代码,旨在帮助读者更好地理解和学习MyBatis的源码。项目包含了MyBatis的相关测试代码以及一个简单的数据库脚本,用于搭建测试环境。主要使用的编程语言是Java。 2. 新手使用项目时需注意的问题及解决步骤 问题一:数据库脚本执行失败 问题描述...

gitblog_00705的博客 362

地图自定义编码CSV转换成ini文件

创 建 schema.ini 文件:有时,当您尝试使用 .csv 文件将自定义地理信息导入 Tableau 时,您可能会看到“无法使用.csv,因为它不包含唯一列”错误消息。这是因为您的 .csv 文件可能包含数值数据,例如数值邮政编码。对于新的地理角色,Tableau 将只接受文本字段。但是,您可以创建一个 schema.ini 文件,以指示 Tableau 应将您要导入的数值字段视为文本字段。...

wenyusuran的专栏 1975

《JDK 源码分析》项目常见问题解决方案

《JDK 源码分析》项目常见问题解决方案 《JDK 源码分析》项目是一个对 Java 开发工具包(Java Development Kit, JDK)源码进行深入分析和解读的开源项目。该项目旨在帮助开发者更好地理解 JDK 内部的工作原理。该项目主要使用 Java 语言进行开发。 以下是新手在使用这个项目时可能遇到的三个常见问题及其详细的解决步骤: 1. 克隆项目后无法编译 问题分析 可能是因为项...

gitblog_00935的博客 423

基于STM32、HAL库的 CH9102X USB转UART收发器 驱动程序设计

/ 或 UART_HWCONTROL_RTS_CTS。// 其他函数实现类似,使用HAL_UART_Transmit_IT, HAL_UART_Receive_IT等。UART_TXD <---> USARTx_RX (STM32接收)UART_RXD <---> USARTx_TX (STM32发送)* @param huart: UART句柄指针。* @param huart: UART句柄指针。* @param huart: UART句柄指针。* @param huart: UART句柄指针。

corlin6688的博客 506

如何在 Mac 上下载安装 Xcode——并为 iOS 开发更新它原文

下载 Xcode安装命令行工具打开新版本删除文件注意,我在下面的步骤中列出了一些终端命令。这些命令可以被输入到你现在的工作目录中。这意味着你不需要导航到任何特定的文件夹。如果你真的想这样做,你可以在输入下面的步骤中的命令之前先输入== cd==。这将使你返回到主文件夹。

专注于AI领域前沿知识,业余爱好开发软件 4670

【亲测免费】 RocketMQ-3.4.6源码分析与注释项目常见问题解决方案

RocketMQ-3.4.6源码分析与注释项目常见问题解决方案 一、项目基础介绍 本项目是对阿里巴巴分布式消息队列中间件RocketMQ-3.4.6的源码分析和中文详细注释。项目旨在帮助开发者更好地理解RocketMQ的工作原理和设计思想。主要编程语言为Java。 二、新手常见问题与解决步骤 问题一:如何下载和导入项目 问题描述: 新手在使用前不知道如何将项目下载到本地并导入到IDE中。 解决步骤...

gitblog_00020的博客 296

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

HashMap源码分析以及常见问题

HashMap基本用法 通过HashMap与Hashtable比较: HashMap能接受为null的键和值,Hashtable键和值都不能为null(通过put方法跟踪源码就一目了然); HashMap是非synchronized的,所以快,Hashtable是synchronized,相对慢(源码); HashMap 数组+链表 的存储结构,存储键值对;而一般的集合List、Set则是存

kingyxfly的博客 400

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

JavaEasyUI分页模块源码分析与常见问题解决方案

/ 自定义布局// 自定义按钮文本buttons: [{ iconCls: 'icon-search', handler: function() { // 自定义搜索功能 }}]});```EasyUI分页模块作为数据展示的重要组件,其稳定性和性能直接影响用户体验。通过深入理解源码实现机制,开发者能够更好地解决实际开发中遇到的各种问题。本文介绍的问题解决方案基于实际项目经验,涵盖了常见的异常情况和性能优化场景。在实际项目中,建议结合具体业务需求进行适当的定制和优化。

D111222DJC的博客 1399

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Redis 专栏(使用介绍、源码分析、常见问题...)

来源http://blog.youkuaiyun.com/yangbodong22011/article/details/78529448 https://github.com/hurley25 https://github.com/hurley25/ANet ANet 基于Redis网络模型的简易网络库,网络模块代码取自Redis源码。 Redis网络模型介绍 Redis网络模型是一个使用I

$firecat利白的代码足迹$ 1021

ThreadLocal源码分析及其常见问题

参考博文: https://blog.youkuaiyun.com/weixin_42126028/article/details/108345422 https://blog.youkuaiyun.com/zzg1229059735/article/details/82715741 ThreadLocal ThreadLocal让线程拥有独立的可操作变量,各个不同线程之间不共享. 1. 证明ThreadLocal拥有独有变量 public class ThreadLocalTest01 { //创建threadLocal

As097的博客 291

Java进阶(List)——面试时List常见问题解读 & 结合源码分析

本篇博客介绍常见的关于Java中List集合的面试问题,结合源码分析题目背后的知识点。

Arya的博客,专注后端领域 972

Java进阶(Set)——面试时Set常见问题解读 & 结合源码分析

本篇博客介绍常见的关于Java中Set集合的面试问题,结合源码分析题目背后的知识点。

Arya的博客,专注后端领域 865
上一篇: binlog以及Canel
下一篇: ThreadLocal原理
HY_Chan
博客等级 码龄10年 54粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值