目录
String s="a"+"b"+"c"+"d";创建了几个对象?
String s = new String("xyz");创建几个String对象?
String、StringBuilder、StringBuffer的区别?
如何保证ArrayList线程安全
一、继承Arraylist,然后重写或按需求编写自己的方法,这些方法要写成synchronized,在这些synchronized的方法中调用ArrayList的方法。
二:使用Collections.synchronizedList();使用方法如下:
假如你创建的代码如下:List<Map<String,Object>> data=new ArrayList<Map<String,Object>>();
那么为了解决这个线程安全问题你可以这么使用Collections.synchronizedList(),如:
List<Map<String,Object>> data=Collections.synchronizedList(new ArrayList<Map<String,Object>>());
MySQL索引数据结构
1. 关于索引
索引是帮助Mysql更加高效获取数据的一种数据结构,索引的使用很简单,但是如果不能理解索引底层的数据结构的话,就谈不上去优化索引了。
2. B+树
Mysql的索引用的是B+树,他具有这样的几个特点:
1、数据都存储在叶子节点中、非叶子节点只存储索引
2、叶子节点中包含所有的索引
3、每个小节点的范围都在大节点之间
4、叶子节点用指针相连,提高访问性能,比如条件是>或者<的查询就可以直接按指针找(Mysql中的B+树叶子节点中的指针是双向指针)
B+树的数据结构如图所示,首先非叶子节点只存储索引,且每个指针所指向的节点最左边的索引都是该指针对应的索引值,比如头节点的第一个索引值8,指向的非叶子节点的第一个索引值也是8。
3. 为什么索引这么快?
索引可以支撑千万级表的快速查找,为什么呢?下面就来解释一下:
show GLOBAL STATUS like 'Innodb_page_size'
在Innodb中,默认的innodb_page_size大小为16kb,这就相当于上面每一个节点的大小默认情况下是16kb。一个索引值的大小为8B,索引后的指针所占大小为4B,因此可以解算出一个节点中大约可以存储1170个索引。
对于叶子节点,由于存储了数据,我们可以大方地估计每个数据的大小为1kb,相当于在叶子节点中每个节点可以存储16个数据。
这样就可以计算出一个三层的B+树结构的索引一共可以存储1170117016=2190万条数据,这就意味着只需要三次磁盘IO,就可以检索两千万条数据,由此可见索引可以支撑千万级表的快速查找。
类的实例化方法调用顺序
参考答案
类加载器实例化时进行的操作步骤:
加载 -> 连接 -> 初始化
- 代码书写顺序加载父类静态变量和父类静态代码块
- 代码书写顺序加载子类静态变量和子类静态代码块
- 父类非静态变量(父类实例成员变量)
- 父类非静态代码块
- 父类构造函数
- 子类非静态变量(子类实例成员变量)
- 子类非静态代码块
- 子类构造函数
String s="a"+"b"+"c"+"d";创建了几个对象?
参考答案
1个
Java 编译器对字符串常量直接相加的表达式进行优化,不等到运行期去进行加法运算,在编译时就去掉了加号,直接将其编译成一个这些常量相连的结果。
所以 "a"+"b"+"c"+"d" 相当于直接定义一个 "abcd" 的字符串。
String s = new String("xyz");创建几个String对象?
参考答案
两个或一个
- 第一次调用 new String("xyz"); 时,会在堆内存中创建一个字符串对象,同时在字符串常量池中创建一个对象 "xyz"
- 第二次调用 new String("xyz"); 时,只会在堆内存中创建一个字符串对象,指向之前在字符串常量池中创建的 "xyz"
String、StringBuilder、StringBuffer的区别?
参考答案
相同点:
- 都可以储存和操作字符串
- 都使用 final 修饰,不能被继承
- 提供的 API 相似
区别:
- String 是只读字符串,String 对象内容是不能被改变的
- StringBuffer 和 StringBuilder 的字符串对象可以对字符串内容进行修改,在修改后的内存地址不会发生改变
- StringBuilder 线程不安全;StringBuffer 线程安全
方法体内没有对字符串的并发操作,且存在大量字符串拼接操作,建议使用 StringBuilder,效率较高。
静态内部类和非静态内部类有什么区别?
参考答案
- 静态内部类不需要有指向外部类的引用;非静态内部类需要持有对外部类的引用
- 静态内部类可以有静态方法、属性;非静态内部类则不能有静态方法、属性
- 静态内部类只能访问外部类的静态成员,不能访问外部类的非静态成员;非静态内部类能够访问外部类的静态和非静态成员
- 静态内部类不依赖于外部类的实例,直接实例化内部类对象;非静态内部类通过外部类的对象实例生成内部类对象
同步代码块和同步方法有什么区别?
参考答案
- 同步方法就是在方法前加关键字 synchronized;同步代码块则是在方法内部使用 synchronized
- 加锁对象相同的话,同步方法锁的范围大于等于同步方法块。一般加锁范围越大,性能越差
- 同步方法如果是 static 方法,等同于同步方法块加锁在该 Class 对象上
什么是多态?如何实现?有什么好处?
参考答案
多态:
同一个接口,使用不同的实例而执行不同操作。同一个行为具有多个不同表现形式或形态的能力。
实现多态有三个条件:
- 继承
- 子类重写父类的方法
- 父类引用变量指向子类对象
实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
Java 中使用父类的引用变量调用子类重写的方法,即可实现多态。
好处:
- 消除类型之间的耦合关系
- 可替换性(substitutability)
- 可扩充性(extensibility)
- 接口性(interface-ability)
- 灵活性(flexibility)
- 简化性(simplicity)