Mybatis
- #{} 和 $ {}的区别?
#{}是预编译处理 而${}是字符串替换
#{}可以防止SQL注入,先将#{}里面替换成?,然后调用PreparedStatement.set()来赋值 - 模糊查询like怎么写?
<if test="keyword != null and keyword != ''">
and
name like concat('%',#{keyword},'%')
</if>
- Mapper里面的方法能够重载吗?
是不能的,Mybatis通过namespace接口的全路径加上方法名作为key放在一个map当中定位到唯一的mapperStatement,每一个标签就会被解析为一个MapperStatement对象,mapper接口工作原理是JDKProxy - 如何获取自动生成的主键ID?
首先insert成功会返回一个int类型的值表示插入的行数
在Mybatisinsert标签里面有个userGenerator默认也是true,这个值已被赋值给对象id - 如何执行批量插入?
使用sqlSession的里面的一个executorType.batch
还有一个就是NameMapper里面有个SqlSession.getMapper获取一个mapper
SqlSession s = SqlSessionFactory.openSession(exexutor.batch);
try{
NameMapper mapper = SqlSession.getMapper(NameMapper.class);
for(String name : names){
mapper.insert(name);
}
s.commit();
}catch(Exception e){
s.rollback();
}finally{
s.close();
}
- mapper当中如何传递多个参数?
推荐使用@param注解,或者封装成map也行 - resultMap的联合查询和嵌套查询怎么做,一对一 和 一对多?
一对一association
一对多collection - Mybatis是否支持延迟加载?
在配置文件mybatisConfig可以配置lazyLoadingEnable=true or false
Mybatis仅支持association和collection的延时加载,通过CGLib创建目标对象的代理对象,当调用目标方法时进入拦截器方法,拦截器方法invoke发现调用的是null就会
单独发送事先
网络通信
- 什么是OIS七层协议 和 TCP/IP四层协议?
- TCP/IP三次握手了解吗?为什么是三次呢?
- TCP和UDP的区别 分别说一下?
- HTTP和HTTPS的区别
- get和POST的优缺点
- 网络IO和磁盘IO
- 在网络IO当中Socket和ServerSocket
- BIO和NIO
- Connection:keep-alive的作用?
- 一个完整的HTTP请求的过程
- socket.accept()为啥阻塞?什么是BIO
会阻塞当前线程,这里可以说javaIO流是阻塞流
,因为前面提到过,Socket连接里面的输入输出流也是阻塞的,如果这个Socket连好过后,客户端和服务器迟迟不发数据,那么这个新创建的线程也会阻塞在那里,(除非这个新创建的线程里面不操作Socket里面的IO),为了阻止这种情况,就要像上面说的,在新创建的线程里面在新创建一个线程处理Socket里面的流的问题
详细描述
JAVA核心基础
- Arrays.asList()方法的理解,以及数组和List的转化
Arrays.asList(strArray)返回值是java.util.Arrays类中一个私有静态内部类java.util.Arrays.ArrayList,它并非java.util.ArrayList类。java.util.Arrays.ArrayList类具有 set(),get(),contains()等方法,但是不具有添加add()或删除remove()方法,所以调用add()方法会报错
数组转List:更详细博客
String[] arr = new String[]{"q","qw","qwe","qwer"};
List<String> list0 = Arrays.asList(arr);
//list0.add("qwert");// java.lang.UnsupportedOperationException
List<String> list = new ArrayList<>(Arrays.asList(arr));
list.add("qwert");
list.forEach(System.out::print);
System.out.println();
list0.forEach(System.out::print);
// list转Array
String[] strArr = list1.toArray(new String[list1.size()]);
String[] strArr1 = list1.stream().toArray(String[]::new);
Arrays.stream(strArr).forEach(System.out::print);
System.out.println();
Arrays.stream(strArr1).forEach(System.out::print);
- ArrayList的扩容机制?
如果没有手动初始化容量默认创建一个空数组,然后在add的时候初始化默认容量10,每次add之前都回去调用ensureCapacityInternal(size+1)
如果初始化指定容量会立即初始化一个指定容量大小的数组
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
list.add()方法源码
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
ensureCapacityInternal()源码
//直到添加第11个元素,minCapacity(为11)比elementData.length(为10)要大。
//进入grow方法进行扩容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);// 1.5倍扩容
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
// 如果到达Integer.MAX_VALUE再add就会OOM异常
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;// 为什么是Integer.MAX_VALUE-8?
}
灵魂问题:那个MAX_ARRAY_SIZE是干什么的?为什么是Integer.MAX_VALUE-8
当我们的 newSize=1.5倍oldSize=1.5倍element.length>MAX_ARRAY_SIZE的时候
避免每次直接扩容成对应newSize,取一个缓冲值统一扩容为MAX_ARRAY_SIZE
直到element.length大于缓冲值MAX_ARRAY_SIZE时候,再进行统一扩容为Integer.MAX_VALUE;如果element.length=Integer.MAX_VALUE时候再add就会抛出异常OOM;
好了 说了这么多 虽然把流程搞明白了 但是为啥设置MAX_ARRAY_SIZE=Integer.MAX_VALUE-8这个问题 好像还是没得到解决啊?
所以 我们来模拟一下扩容过程:
首先是10->15->22->33->49->73->109->163->…->计算了一下
l
o
g
1.5
214748364.7
≈
47
\ log_{1.5}214748364.7\approx47
log1.5214748364.7≈47也就是说正常情况下大概扩容47次就到最大值了,实际这个不准确,因为1.5倍小数部分就被省略了;但是大概就47次。
所以这个事儿我的理解就是 一个缓冲作用 避免每次都跟最大值比较,避免无效的扩容(实际用不到那么多空间)。
- 怎么理解Java的多态?
- 说一说抽象类?
- String类型为啥不可变?new一个String产生了几个对象?
- this可以作为锁对象吗?