在 Java 中,Map 是属于 java.util 包下的一个接口(interface),所以说“为什么 Map 不能插入 null?”这个问题本身问的不严谨。...Map 部分类关系图如下:所以,这里面试官其实想问的是:为什么 ConcurrentHashMap 不能插入 null?...在 ConcurrentHashMap 中,key 或者是 value 值都不能为 null。2.为什么不能插入null?...如果我们查看 ConcurrentHashMap 的源码,就能发现为什么 ConcurrentHashMap 不能插入 null 了,以下是 ConcurrentHashMap 添加元素时的部分核心源码...所以,如果 ConcurrentHashMap 允许插入 null 值,那么就会存在二义性问题。那就有同学会问了,为什么 HashMap 允许插入 null,它就不怕有二义性问题吗?
首先,语法上,抽象类不能被实例化,这是语法规定。强制实例化一个抽象类的代码,编译器会报错。...它建立一个基本的格式,用来确定什么是对于所有派生类是公共的——除此之外,别无用途。抽象基类仅仅表示接口,不表示特例实现,因此,实例化一个抽象类对象,总是没有意义的。...第三,从编译器设计的实现上来看,如果想要禁止用户实例化抽象类,可以在抽象类的所有虚函数里,打印出错的信息,以提示用户不能实例化抽象基类。...但是这种方法只有到运行时才能获得出错信息,并且要求程序员进行可靠且详尽的测试,并不能禁止程序员实例化抽象基类。最好是在编译时就能发现这个问题。...因此,只要有一个函数在类中被声明为纯虚函数,则VTABLE就是不完全的。 如果一个类的VTABLE是不完全的,当某人试图创建这个类的对象时,编译器做什么呢?它不能安全地创建一个纯抽象类的对象。
问题 类成员模板函数为什么不能被 virtual 修饰?
这个解释对于了解"继承"的小伙伴来说,显得理所当然。 但实际情况是:不是因为有了“继承”特性,里氏替换才有意义;而是因为有了里氏替换原则,才规范了“继承”特性的使用。 PS:小二哥可能表述得有点怪。...只看基类 Dog 类型来说,基于里氏替换原则,你既可以给 ShepherdDog,又可以给 Cat。但理性告诉你,你不能给 Cat。因为,你把 Cat 给邻居,邻居会觉得你在鄙视他:咋的?...小伙伴们,肯定就会说啦:Cat 和 Dog 是两种动物了,肯定不能使用继承关系啦~ 这个说法是对的。但对于我们面向对象编程过程中,尤其是在“继承”关系中,我们考虑的是“替换性”。...Cat 不能替换 Dog, 因此,我们不能让 Cat extends Dog。 同样,网络上经典的例子:正方形不是长方形的子类,也是如此。...而什么情况下能对这个基类进行具体实现呢?满足里氏代换原则,你就可以基于基类进行具体实现。 为什么里氏代换原则这么重要,小伙伴们理解了吗?
在java、C++等面向对象的语言中,实现多态的方式就是使用父类引用指向子类对象,所以父类引用指向子类对象是没有任何为题的,但是,大家有没有想过,子类引用可以指向父类对象吗?答案是不可以!...但是为什么呢? 下图是在java中,使用子类引用指向父类对象的情况 ? 编译可以通过,因为对生成的Person对象做了一个强制转换,骗过了编译器,其本质上还是属于子类引用指向父类对象。...为什么java里面不允许这种操作,而C++却允许这种操作呢?我们接下来在C++的环境下,反汇编窥探一下这写代码究竟干了些什么事。...首先,在执行这行代码的时候,先把一个4压入栈中,然后去调用operator new这个函数,很明显,这个4就是该函数的一个参数,它完成的任务就是,向堆空间申请4个字节的存储空间,为什么是4个字节?...因为Person这个类里面只有age这一个属性,因此new出来的对象也只需要4个字节存储就够了。然后使用stu这个Student类型的指针指向这4个存储空间的首地址。 ? ?
关于读写锁里面有一个锁升级和降级的问题,也就是写锁可以降级为读锁,但是读锁却不能升级为写锁。那么为什么是这样?...这就是读锁为什么不能直接升级写锁的主要原因,当然这里并不是绝对,升级写锁的最佳条件是一次只允许一个读线程升级,这样以来就不会产生大量不可控的竞争,在JDK8中新增的StampedLock类就可以比较优雅的完成这件事
不能,因为string类是被final修饰的类,final修饰过的类不能被继承、final修饰过的变量不能被修改。
__(self): raise Exception('不能实例化这个类') kingname = People() kingname.say() 一旦初始化就会报错,如下图所示:...一个不能被初始化的类,有什么用? 这就要引入我们今天讨论的一种设计模式——混入(Mixins)。 Python 由于多继承的原因,可能会出现钻石继承[1]又叫菱形继承。...{self.age}岁') kingname = People('kingname', 28) pm = People('pm', 25) kingname > pm 显然,这样写会报错,因为两个类的实例是不能比较大小的...: 本质上,混入的写法与普通的类继承类没有什么区别。...混入: 不能包含状态(实例变量)。 包含一个或多个非抽象方法。 参考资料 [1]钻石继承: https://en.wikipedia.org/wiki/Multiple_inheritance
,有没有必要封装,以及怎样封装,如果小伙伴有更好的建议,可以提出,进行互相学习。...LOGGER.isInfoEnabled()) { LOGGER.info("print: {}", "this is the log"); } 所以,一般封装是将 if 判断这块逻辑统一封装为一个工具类。...可能到这里还有小伙伴不是很理解为什么要加 if 判断,可以看下下面这段代码: 可以看出转换逻辑这块相对比较复杂、耗时,在这里只是模拟的场景,实际使用可能会有其他情况,比如打印方法的出参入参、计算耗时等...说到这里相信小伙伴已经看出问题了,因为这样写的话,当我关闭日志打印时,只是关闭了磁盘输出,但是耗时逻辑依然会继续执行。...-- slf4j 2.0 依赖 --> org.slf4j slf4j-api</artifactId
如其名字,它对开发者提供了统一的门面,允许开发者在部署时插入所需的日志框架。 如何使用 使用它很简单,引入对应的依赖。... org.slf4j slf4j-api 1.7.28 org.slf4j slf4j-simple 1.7.28...结论是,slf4j-jdk14 和 jul-to-slf4j、slf4j-log4j12和log4j-over-slf4j、slf4j-jcl和jcl-over-slf4j 这三对内部两个之间不能同时存在
为什么要用NumPy 经常有人拿List和NumPy比,为什么使用NumPy而不是List?...而在我们使用NumPy时候,这个5会被转换为包含4个字节的int32类型? ? 但是在Numpy中你可以说这32位太长,然后指定为16位甚至8位都行 ?...感受到了吗,所以为啥NumPy比List快,因为它使用的内存字节更少所以我们的计算机可以更快速的读取。...最后,List能做的事比如插入、增加、删除数据NumPy都可以搞定,List不能做的事,NumPy也能搞定,比如我有两个list a = [1,2,3] b = [4,5,6] 如果我直接计算a*b,...下一期开始就会从代码讲起,所以还等什么,抓紧分享给小伙伴上车学NumPy,没有留言功能的我,分享与在看是对我唯一的鼓励,催更就来点点,至于会更新几期我也不知道,毕竟这次不再仅仅是刷题。拜拜~
小伙伴们在面试的时候,有一个特别常见的问题,那就是数据库的回表。什么是回表?为什么需要回表? 今天松哥就来和大家聊一聊这个话题。 1....这个其实很多小伙伴可能也都听说过,B+Tree 嘛! B+Tree 是什么?...那么主键占 8 个字节,当然还有其他一些头信息也会占用字节我们这里就不考虑了,我们大概算一下,小伙伴们心里有数即可: 16*1024/(8+6)=1170 即一个非叶子结点可以指向 1170 个页,那么一个三层的...扩展 基于第一、二小节的分析,我们再来捋一捋为什么在数据库中建议使用自增主键。 自增主键往往占用空间比较小,int 占 4 个字节,bigint 占 8 个字节。...自增主键插入的时候比较快,直接插入即可,不会涉及到叶子节点分裂等问题(不需要挪动其他记录);而其他非自增主键插入的时候,可能要插入到两个已有的数据中间,就有可能导致叶子节点分裂等问题,插入效率低(要挪动其他记录
根据jar的pom文件可以看出,这个slf4j-log4j12依赖父级是org.slf4j,然后想着去我的pom文件中查找一下就可以了,然后就尴尬了,发现没有这个依赖。...可是为什么没有这个依赖,会有jar加载到项目中去呢,分析一下基本可以断定,应该是其它依赖的子依赖有引用到org.slf4j这个依赖。...3.问题排查 那怎么看到底是哪一个依赖引用到了org.slf4j依赖呢,这边我们可以用idea的一个查看依赖的功能。 ? 打开之后如下所示: ?.../artifactId> 3.4.5 org.slf4j...因为有时候你不知道哪里出问题,又不能用debug进行调试,所以我们只能借助仅存的错误提示来排查错误。这个时候我们更应该借助工具的作用,比如今天讲到的idea中查看依赖的工具。
Boolean :1字节 byte:1字节 short:2字节 int:4字节 long: 8字节 char:2字节 float:4字节 double:8字节 2...、string可以被继承么,为什么?...5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。...7、抽象类里可以没有抽象方法 8、如果一个类里有抽象方法,那么这个类只能是抽象类 9、抽象方法要被实现,所以不能是静态的,也不能是私有的。...详细讲解 15、final的用途 final 修饰的类叫最终类,该类不能被继承。 final 修饰的方法不能被重写。 final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
配置 Application 启动类 启动成功: 五、命令测试 # 创建topic ....'org.slf4j', name: 'slf4j-api', version: '1.7.25' // https://mvnrepository.com/artifact/org.slf4j.../slf4j-log4j12 compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.25' } 解决。...5、错误: 找不到或无法加载主类 kafka.admin.TopicCommand 执行 ....不知道为什么,执行了一下 core 模块的 gradle build,虽然命令失败了,但是又试了试 .\bin\windows\kafka-topics.bat 发现执行正常了。
但说实话,这样苍白的回答并不能令面试官感到满意,他还想知道的更多。...为什么会这样呢?为什么为什么?回答的不对吗? 暴躁的小伙伴请喝口奶茶冷静一下。...Java 的序列化是指,将对象转换成以字节序列的形式来表示,这些字节序中包含了对象的字段和方法。序列化后的对象可以被写到数据库、写到文件,也可用于网络传输。...一个类既然实现了 Serilizable 接口,肯定是想要被序列化的,对吧?那为什么保存关键数据的 elementData 又不想被序列化呢?...大家都知道,数组是定长的,就是说,数组一旦声明了,长度(容量)就是固定的,不能像某些东西一样伸缩自如。这就很麻烦,数组一旦装满了,就不能添加新的元素进来了。
为什么说是’必要的间接依赖‘呢?这是因为不是所有的间接依赖都会被引入的。这还得说说maven的 依赖范围。...这种冲突可能不是同一个依赖的不同版本(这个依赖调解能搞定),而是不能同时出现的两个依赖。...比如slf4j-log4j和logback这两个依赖是不能同时出现的,但是因为他们的坐标不一样,所以maven不会对齐进行处理。这个时候我们就需要手动进行 排除依赖 了。...:slf4j-api1.6.1 paths to dependency are: [ERROR] Dependency convergence error for org.slf4j:slf4j-api...-org.slf4j:slf4j-api:1.6.1 and +-org.myorg:my-project:1.0.0-SNAPSHOT +-org.slf4j:slf4j-nop:1.6.0 +-org.slf4j
1.2.17 org.slf4j...1.7.12 org.slf4j...--直接使用类名即可,对于整个包的路径配置(别名),简单快捷 --> select...-- 不能写成'%#{name}%' --> <!
序列化和反序列化 序列化 将一个类对象转换成为一段字节序列保存在文件中,和java的原生类writeObject对应 反序列化 将对象序列化生成的字节序列还原为一个对象,和java的原生类readObject...serialVersionUID(用于记录java序列化版本)在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 与本地相应实体类的 serialVersionUID...commons-fileupload 1.3.1 commons-io 2.4 commons-collections 3.1 commons-logging 1.2 commons-beanutils 1.9.2 org.slf4j...所以有些防火墙工具在检测反序列化数据时仅仅检测这几个字节是不安全的设置。...识别出序列化数据后,就要定位插入点,不同的数据类型有以下的十六进制对照表: 0x70 - TC_NULL 0x71 - TC_REFERENCE 0x72 - TC_CLASSDESC 0x73 - TC_OBJECT
所有键列所在位置找到第一个索引,NOT NULL 并将其作为聚簇索引 未声明且找不到合适的 UNIQUE 索引,则内部生成一个隐藏的聚簇索引 GEN_CLUST_INDEX,这个隐藏的行 ID 是 6 字节且单调增加...图:《MySQL 技术内幕 InnoDB 存储引擎》 数据的插入 当数据插入时,InnoDB 会使页面 1/16 空闲,以备将来插入和更新索引记录。...顺序插入(升序或降序):会将索引页剩余的大约 15/16 装满 随机插入:只会使用容量的 1/2 到 15/16 在随机插入中,会频繁的移动、分页,从而造成大量的碎片,并且使索引树不够紧凑。...一般使用手机号、身份证号作为主键等并不能保证顺序性。 流水号一般相对较长,比如 28 位,32 位等,过长的话会二级索引占用空间较多。同时为了业务需求,流水号具有一定的随机性。...结束语 本文主要通过查阅资料,了解为什么要设置一个和业务无关的自增 id 用来当做主键,很多内容比较浅显,比如 InnoDB 的 B+ 树,页分裂及页合并,插入过程等都没有进行深入研究,有兴趣的小伙伴可以更深入的研究下
领取专属 10元无门槛券
手把手带您无忧上云