Java面试突击篇

Mybatis
  1. #{} 和 $ {}的区别?
    #{}是预编译处理 而${}是字符串替换
    #{}可以防止SQL注入,先将#{}里面替换成?,然后调用PreparedStatement.set()来赋值
  2. 模糊查询like怎么写?
<if test="keyword != null and keyword != ''">
  and
  name like concat('%',#{keyword},'%')
</if>
  1. Mapper里面的方法能够重载吗?
    是不能的,Mybatis通过namespace接口的全路径加上方法名作为key放在一个map当中定位到唯一的mapperStatement,每一个标签就会被解析为一个MapperStatement对象,mapper接口工作原理是JDKProxy
  2. 如何获取自动生成的主键ID?
    首先insert成功会返回一个int类型的值表示插入的行数
    在Mybatisinsert标签里面有个userGenerator默认也是true,这个值已被赋值给对象id
  3. 如何执行批量插入?
    使用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();
}
  1. mapper当中如何传递多个参数?
    推荐使用@param注解,或者封装成map也行
  2. resultMap的联合查询和嵌套查询怎么做,一对一 和 一对多?
    一对一association
    一对多collection
  3. Mybatis是否支持延迟加载?
    在配置文件mybatisConfig可以配置lazyLoadingEnable=true or false
    Mybatis仅支持association和collection的延时加载,通过CGLib创建目标对象的代理对象,当调用目标方法时进入拦截器方法,拦截器方法invoke发现调用的是null就会
    单独发送事先
网络通信

参考文章

  1. 什么是OIS七层协议 和 TCP/IP四层协议?
    在这里插入图片描述
  2. TCP/IP三次握手了解吗?为什么是三次呢?
  3. TCP和UDP的区别 分别说一下?
  4. HTTP和HTTPS的区别
  5. get和POST的优缺点
  6. 网络IO和磁盘IO
  7. 在网络IO当中Socket和ServerSocket
  8. BIO和NIO
  9. Connection:keep-alive的作用?
  10. 一个完整的HTTP请求的过程
  11. socket.accept()为啥阻塞?什么是BIO
    会阻塞当前线程,这里可以说javaIO流是阻塞流
    ,因为前面提到过,Socket连接里面的输入输出流也是阻塞的,如果这个Socket连好过后,客户端和服务器迟迟不发数据,那么这个新创建的线程也会阻塞在那里,(除非这个新创建的线程里面不操作Socket里面的IO),为了阻止这种情况,就要像上面说的,在新创建的线程里面在新创建一个线程处理Socket里面的流的问题
    详细描述
JAVA核心基础
  1. 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);
  1. 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.747也就是说正常情况下大概扩容47次就到最大值了,实际这个不准确,因为1.5倍小数部分就被省略了;但是大概就47次。
所以这个事儿我的理解就是 一个缓冲作用 避免每次都跟最大值比较,避免无效的扩容(实际用不到那么多空间)。

  1. 怎么理解Java的多态?
  2. 说一说抽象类?
  3. String类型为啥不可变?new一个String产生了几个对象?
  4. this可以作为锁对象吗?
建议阅读本文档的方式 本文档提供详细的目录,建议大家使用电脑阅读。如果大家用手机阅读的话,可以下载一个不错的PDF阅读器,比如 很多人常用的福昕PDF阅读器。 本文档提供详细的目录,大家可以根据自己的实际需要选择自己薄弱的知识章节阅读。 前言 不论是校招还是社招都避免不了各种面试、笔试,如何去准备这些东西就显得格外重要。不论是笔试还是面试都是有 章可循的,我这个“有章可循”说的意思只是说应对技术面试是可以提前准备。 运筹帷幄之后,决胜千里之外!不打毫无准备的仗,我觉得大家可以先从下面几个方面来准备面试: 1. 自我介绍。(你可千万这样介绍:“我叫某某,性别,来自哪里,学校是那个,自己爱干什么”,记住:多说点简 历上没有的,多说点自己哪里比别人强!) 2. 自己面试中可能涉及哪些知识点、那些知识点是重点。 3. 面试中哪些问题会被经常问到、面试中自己改如何回答。(强烈不推荐背题,第一:通过背这种方式你能记住多 少?能记住多久?第二:背题的方式的学习很难坚持下去!) 4. 自己的简历该如何写。 “80%的offer掌握在20%的人手中” 这句话也不是不无道理的。决定你面试能否成功的因素中实力固然占有很大一部 分比例,但是如果你的心态或者说运气不好的话,依然无法拿到满意的 offer。运气暂且不谈,就拿心态来说,千万 不要因为面试失败而气馁或者说怀疑自己的能力,面试失败之后多总结一下失败的原因,后面你就会发现自己会越来 越强大。 另外,大家要明确的很重要的几点是: 1. 写在简历上的东西一定要慎重,这可能是面试官大量提问的地方; 2. 大部分应届生找工作的硬伤是没有工作经验或实习经历; 3. 将自己的项目经历完美的展示出来非常重要。 笔主能力有限,如果有不对的地方或者和你想法不同的地方,敬请雅正、不舍赐教。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值