知乎上任何关于PHP的话题,最后都会变成引战贴,树大招风就是这样。今天长话短说,聊点干货,助你在知乎的PHP话题上不落下风。...如果你传入的字符串不是标准JSON格式,或者JSON串的层数超过定义的值,又会返回NULL。...通俗点说,正常情况下json_decode()函数会返回数组,其他情况下会返回true,false,NULL。在使用这个函数时不出问题还好,只要一出问题,没认真看文档的人肯定一脸懵。...比如数组中有个值是8.6,json_encode之后会变成8.60000000000001。...至于在知乎上大家说的那些问题,我觉得都不是什么大问题。例如语法不美,速度不快,函数命名不规范……为什么大家都喜欢喷这几点?
今天聊点干货,助你在知乎的PHP话题上不落下风。 函数返回参数之坑 通常情况下函数返回的数据类型都是固定的,比如返回Int,String,Array。...如果你传入的字符串不是标准JSON格式,或者JSON串的层数超过定义的值,又会返回`NULL`。...json函数之坑 在PHP7.1之后,json_encode($arr) 函数会默认给float类型的数据添加精度。...比如数组中有个值是8.6,json_encode 之后会变成8.60000000000001。...之前的分析文章请看这里-我是如何拿到巨额漏洞奖金的 数组结构类型太少之坑 PHP虽然有数组的概念,但全是基于HashTable实现。你想创建一个int型的数组,但是PHP不支持。
day013: JS数据类型之问——概念篇 1.JS原始数据类型有哪些?引用数据类型有哪些?...在 JS 中,存在着 7 种原始值,分别是: boolean null undefined number string symbol bigint 引用数据类型: 对象Object(包含普通对象-Object...p1对象的内存地址,通过调用person.age = 26确实改变了p1的值,但随后person变成了另一块内存空间的地址,并且在最后将这另外一份内存空间的地址返回,赋给了p2。...3.null是对象吗?为什么? 结论: null不是对象。 解释: 虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。...0.1和0.2在转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉,此时就已经出现了精度的损失,相加后因浮点数小数位的限制而截断的二进制数字在转换为十进制就会变成0.30000000000000004
, n);//堆顶的最小值被弹出了,堆顶变成了空节点,空节点开始下浮到合适位置后用数组最后子节点填充。...array[child = right]; //比较出左右子节点更小的那个子节点 if (key.compareTo((T) c) <= 0) //如果左右子节点的最小值大于数组末尾的值...,那么数组末尾的值直接放到父节点,空节点下沉结束 break; array[k] = c; // 如果子节点最小值小于数据末尾的值...子节点上浮到父空节点 k = child; //空节点下滑到最小子节点的位置 } array[k] = key; // 最后空节点填充数组最后的值...} } 参考资料:数据结构之优先队列--二叉堆(Java实现)
返回特殊值: 向空队列取数据,会返回 null; 向容量满的队列加数据,会返回 false。...入栈的均摊时间复杂度分析 3.3 使用数组实现队列结构 使用数组实现队列相对复杂,我们需要一个队头指针和一个队尾指针: 队空: head == tail; 队满: tail == n(并不是真的满,只是无法填充新数据...因为 ArrayDeque 禁止存储 null 元素,所以需要逐个判断元素是否为 null 值后才添加。 ♀️疑问 6:为什么 ArrayDeque 要求数组容量是 2 的整数幂?...其实在 Deque 接口上并不严格禁止存储 null 元素,但是会强烈建议 Deque 的实现不提供存储 null 值的能力。因为 null 通常会作为一个特殊值来判断队列是否为空。...容器源码分析之 Deque 与 ArrayDeque[3] —— jrthe42 著 Why null values are not allowed in ArrayDeque?
在 Java 中,java.util.Arrays类提供的多种数组操作功能,可以有效地执行各种数组相关的操作,使得数组处理变得简单和高效。..., null, null, null, null, null] System.out.println(Arrays.toString(copyOf10)); 这 copyOf,copyOfRange,无异于为数组之尺...注意:若范围大于原数组,多出位置以 null 填充。...每一个元素,都被赋予相同的值。 也可以使用 Arrays.setAll 填充,它允许传入一个函数,生成填充值。...hashCode 方法会根据数组元素值计算出一个数字,如果元素值发生改变,则数字改变。但是同样对于多维数字,在计算数字时不会计算子数组中的元素,这种情况应该使用 deepHashCode判断。
:(n - 1) & hash n是数组长度 hashMap默认长度为16,这个算法为 15 & hash 几个问题: 为什么用右移16位 真正计算数组位置的用的是低16位,所以右移可以将高16位起到作用...index的地方,要么是变成了原来的index(5) + oldCap(16) = 21 因此,我们在扩充HashMap的时候,不需要像JDK1.7的实现那样重新计算hash,只需要看看原来的hash值新增的那个...扩容之桶计算规则图解 ?...+链表 改为:数组+链表+红黑树 hash算法改变 1.8中hash算法改为: (h = key.hashCode) ^ (h>>>16) 高低16位混合运算 扩容方式改变 头插法变成尾插法,并发情况下不会形成死锁...在一些场景下,该特性很有用,比如缓存。
假设一共N个AtomicLong,代码变成: 接口被调用时:AtomicLong[随机数(或者递增数)%N].incrementAndGet() 获取统计总数: for(int i=0;i 这样在获取统计总数时...我们规定N必须为2的n次方 这时我们的计数代码就变成了: AtomicLong[随机数(或者递增数)&(2^n-1)].incrementAndGet() 然后我们想到,我们用的是数组,内存上是连续的...首先对象头在64位虚拟机中,如果启用压缩对象头的话,占用12位。之后,我们使用的是128bytes的填充,所以偏移128bytes。12bytes+128bytes=140bytes。...,因为对于2^n取余相当于对2^n-1取与运算,提高代码性能 transient volatile Cell[] cells; // 累积器的基本值,在两种情况下会使用: /.../ 1、没有遇到并发的情况,直接使用base,速度更快; // 2、多线程并发初始化table数组时,必须要保证table数组只被初始化一次,因此只有一个线程能够竞争成功,这种情况下竞争失败的线程会尝试在
但与Char不同的是,FixedString使用null字节填充末尾字符,而Char通常使用空格填充。比如在下面的例子中,字符串‘abc’虽然只有3位,但长度却是5,因为末尾有2位空字符填充。...在定义枚举集合的时候,有几点需要注意。首先,Key和Value是不允许重复的,要保证唯一性。其次,Key和Value的值都不能为Null,但Key允许是空字符串。...在写入枚举数据的时候,只会用到Key字符串部分。 数据在写入的过程中,会对照枚举集合项的内容逐一检查。如果Key字符串不在集合范围内则会抛出异常。 为什么还需要专门的枚举类型呢?这是出于性能的考虑。...Nullable类型与Java8的Optional对象有些相似,它表示某个基础数据类型可以是Null值。...Null值: INSERT INTO Null_TEST VALUES ('nauu',null) INSERT INTO Null_TEST VALUES ('bruce',20) SELECT c1
如果当前线程已经拥有 objectref 的 monitor 的持有权,那它可以重入这个 monitor,重入时计数器的值也会加 1。...下面我们一起来学习 一个对象在JVM中的的内存布局,来寻找答案。 2.2 对象头 在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。...实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分是按照4字节对齐 填充数据:用于字节对齐。虚拟机要求对象起始地址必须是8字节的整数倍。...在Java虚拟机(HotSpot)中,monitor是由ObjectMonitor实现的,其主要数据结构如下: ObjectMonitor() { _header = NULL;...最后没办法也就只能升级为重量级锁了 引用自:强烈推荐-深入理解Java并发之synchronized实现原理 锁消除 Java虚拟机在JIT编译时,通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁
参考链接: 何时在StringBuilder上使用StringJoiner StringBuilder and StringJoiner 相信大家在平时工作中经常会使用到StringBuilder类...那么首位被挤掉了,由0变成1,那么就变成了负数了 } private int hugeCapacity(int minCapacity) { //推断是否溢出,若溢出,则将容量设置为整型的最大值...(suffix, "The suffix must not be null"); // 给成员变量设定值 this.prefix = prefix.toString();...elements) { joiner.add(cs); } return joiner.toString(); } 补充一个问题 1.为什么扩容是原数组的长度...为什么要+2? 指数扩容是一种折中的算法,因为一方面要减少内存分配次数,另一方面要避免浪费内存。为什么要+2?
开始迭代链表 Object k; // 直到Entry->next为null,就把当前的Entry对象变成链表的下一个节点。...在插入时,1.7先判断是否需要扩容,再插入,1.8先进行插入,插入完成再判断是否需要扩容; 问题 为什么capcity是2的幂?...这种算法在保持分布均匀之外,效率也非常高。 为什么需要使用加载因子,为什么需要扩容呢?...因为如果填充比很大,说明利用的空间很多,如果一直不进行扩容的话,链表就会越来越长,这样查找的效率很低,因为链表的长度很大(当然最新版本使用了红黑树后会改进很多),扩容之后,将原来链表数组的每一个链表分成奇偶两个子链表分别挂在新链表数组的散列位置...与之相比HashTable是线程安全的,且不允许key、value是null。 HashTable默认容量是11。
在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。...hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,但是形成了链表,同一各链表上的Hash值是相同的,所以说数组存放的是链表。...) return r; r = p; } } 二,源码中的数据域 加载因子(默认0.75):为什么需要使用加载因子,为什么需要扩容呢...因为如果填充比很大,说明利用的空间很多,如果一直不进行扩容的话,链表就会越来越长,这样查找的效率很低,因为链表的长度很大(当然最新版本使用了红黑树后会改进很多),扩容之后,将原来链表数组的每一个链表分成奇偶两个子链表分别挂在新链表数组的散列位置...= null); } } return null; } get(key)方法时获取key的hash值,计算hash&(n-1)得到在链表数组中的位置
还是刚才那个例子: var a [10]int var s []int = a[0:4] fmt.Println(s) 这样我们输出得到的结果是[0 0 0 0],因为数组初始化默认值为0。...这一次发生变化了,切片的容量变成了4,也就是说变小了,这是为什么呢? 原因很简单,因为数组的头指针的位置移动了。数组原本的长度是6,往右移动了两位,剩下的长度自然就是4了。...但是剩下的问题是,为什么数组的头指针会移动呢? 因为数组的头指针和切片的位置是挂钩的,我们前面的切片操作虽然会改变切片中的元素和它的长度,但是都没有改变切片指针的位置。...这也是为什么切片的容量定义是它对应的数组从开始到末尾元素的个数,而不是对应的数组元素的个数。因为指针向右移动会改变容量的大小,但是数组本身的长度是没有变化的。...像是这样: s := make([]int, 5) 我们如果打印这个s的话,会得到[0 0 0 0 0],也就是说golang会为我们给切片填充零值。
不同于之前的jdk的实现,1.8采用的是数组+链表+红黑树,在链表过长的时候可以通过转换成红黑树提升访问性能。...int TREEIFY_THRESHOLD = 8; //将红黑树转成链表(桶)的临界值 static final int UNTREEIFY_THRESHOLD = 6; //转变成树的table的最小容量...; } 这里提到里的remove的话,肯定与之联想到的就是其抛出ConcurrentModificationException。...Node[] t = table; current = next = null; index = 0; //在table数组中找到第一个下标不为空的节点。...较高的填充因为减少了空间的消耗,但是增加了查找的时间 最好能够在创建HashMap的时候指定其容量,这样能存储效率比使其存储空间不够后自动增长更高。
0 : (h = key.hashCode()) ^ (h >>> 16); } 取模,计算出下标 在计算下标的时候,让列表长度对哈希值做取模操作,让计算出来的哈希值在列表范围内,n 为list长度 i...= (n - 1) & hash 为什么HashMap的数组长度要取2的整次幂 因为这样(数组长度 - 1)正好相当于一个“低位掩码”。...负载因子的作用是在空间和时间效率上取得一个平衡。 float DEFAULT_LOAD_FACTOR = 0.75f 扩容做了哪些操作 创建一个新的Entry空数组,长度是原数组的2倍。...重新Hash 遍历原Entry数组,把所有的Entry重新Hash到新数组中。 为什么要重新hash?...= null) { ... } } 为什么要树化? 本质上是个安全问题。
若不存在,则在字符串常量池中创建一个内容为"abc"的字符串对象,并将堆中的对象与之联系起来 聊聊Java中的SPI 系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程...Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。 Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。...HashMap 的长度为什么是 2 的幂次方 首先考虑奇数行不行,在计算hash的时候,确定落在数组的位置的时候,计算方法是(n - 1) & hash ,奇数n-1为偶数,偶数2进制的结尾都是0,经过...HashMap 的扩容伐值为什么是0.75 当负载因子是1.0的时候,也就意味着,只有当数组的8个值(这个图表示了8个)全部填充了,才会发生扩容。这就带来了很大的问题,因为Hash冲突时避免不了的。...负载因子是0.5的时候,这也就意味着,当数组中的元素达到了一半就开始扩容,既然填充的元素少了,Hash冲突也会减少,那么底层的链表长度或者是红黑树的高度就会降低。查询效率就会增加。
为什么? 另外,我们知道在JDK7中HashMap底层实现只是数组+链表,而到了JDK8就变成了数组+链表+红黑树。...具体的分析可以参考:HashMap源码注解 之 静态工具方法hash()、tableSizeFor()(四)。...= null); } } return null; } 2.为什么重写equals还要重写hashcode?...false null 可以看到,因为hashCode()得到的值不同,在map中他们被当成了不同的key。...举个例子: 假设线程A线程B同时对下图集合扩容: 1.A先执行,在newTable[i] = e前时间片耗尽被挂起,此时e = 1,e.next = null,next = 2 2.线程B执行数组扩容
领取专属 10元无门槛券
手把手带您无忧上云