MyBaits常见问题总结

1、mybaits中使用小于号

【错误分析】
如过在mybatis中使用<>&等字符,配置文件中会提示如下错误
The content of elements must consist of well-formed character data or markup.
【解决方法】
方法一   如果是在动态语句中,则需要转换

符号:

方法二 (推荐), 此时特殊符号不进行解析

【参考资料】

2、mybatis 可以返回map类型对象

注意:resultMap  和 resultType 区别

3、mybaits 查询sql中in的写法

4、mybatis 查询like 正规写法

正确方法一:

正确方法二:
like “%”#{name}”%”
错误方法
like ‘%”#{name}”%’
【参考资料】

MySQL数据join不走索引问题排查

【问题场景】

有个30多行的大SQL执行效率特别慢,问题集中在一个子查询上,开始没有建索引,可是发现索引都创建了,不走索引,大SQL简化一下,提出不走索引的部分,如下图所示

简单点,有三张表需要关联查询,关联关系如下

A表

B表 关联 A.col = B.id

C表 关联 B.col = C.id

问题出在 B表 关联 A.col = B.id,为啥?执行计划就是不走id主键,C表 关联 B.col = C.id都可以正常走

【解决思路】

1、尝试单表查询,验证索引是否正常 试了一下单表查询B是可以走主键索引,正常,排出索引问题

2、尝试优化SQL 修改了一下SQL,将left join 分别改为inner join,join和子查询,几种方式都不能走索引,排出优化可能

3、尝试在其他环境执行

发现在其他环境下可以正常,走索引,说明不是SQL的问题,排出SQL问题。

TMD !!! 到底哪出问题

既然有环境可以,肯定是哪里配置有问题,慢慢对比一下,于是从表结构,索引创建方式,逐一排查,还是没有发现问题。

没有思路了,困意来袭,下班回家,明日再战


新的一天开始,没办法,在baidu继续搜搜,“SQL 不走索引”

忽然间发现了一篇文章 https://www.cnblogs.com/jarjune/articles/7912722.html

启发了我,是不是两张表的编码方式不一样呢,有思路来,开搞,哈哈 ……

先看表的编码,哇塞,uft8mb4

再看字段的编码,神马,uft8mb4

我们默认都是uft8,谁干的,我的刀呢 …… 修改了表的编码和字段的编码方式,终于可以正常走索引了

【总结】

  • 对于大SQL,不要抱着大西瓜跑步,轻装上路。精确定位问题,简化问题,逐步缩小范围
  • 在一两个人开发的时候,大家都熟悉规范,使用默认的编码方式,一般会忽略编码方式不同的问题,所以团队开发要注意遵守规范
  • 在使用join连接查询的时候,如果编码不一致,就不走索引了

Java程序员面试题(高级篇)(一)

1、ThreadLocal 特性

  • ThreadLocal存放的值是线程封闭,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递
  • 在Thread类中有一个Map,用于存储每一个线程的变量的副本。
  • 线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收
  • 对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式(ThreadLocal的缺点时占用了较多的空间。)

2、jvm内存区域划分

  • 运行时数据区包括:虚拟机栈区,堆区,方法区,本地方法栈,程序计数器
  • 虚拟机栈区 :也就是我们常说的栈区,线程私有,存放基本类型,对象的引用和 returnAddress ,在编译期间完成分配。
  • 堆区 , JAVA 堆,也称 GC 堆,所有线程共享,存放对象的实例和数组, JAVA 堆是垃圾收集器管理的主要区域。
  • 方法区 :所有线程共享,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。这个区域的内存回收目标主要是针对常量池的对象的回收和对类型的卸载。
  • 程序计数器 :线程私有,每个线程都有自己独立的程序计数器,用来指示下一条指令的地址

3、类加载过程,classload机制

  • 五个阶段:加载、验证、准备、解析、初始化

4、类加载器

  • 启动类加载器,c++实现,虚拟机自身的一部分,负载加载JAVA_HOME\lib目录中jar
  • 其他类加载器,java实现,虚拟机外部,全部继承抽线类java.lang.ClassLoader
  • 扩展类加载器,负载加载JAVA_HOME\lib\ext目录中jar
  • 应用程序类加载器,负载加载用户类路径classpath上所有指导的类库 * 自定义类加载器

5、垃圾回收回收算法

  • 两个最基本的java回收算法:复制算法和标记清理算法
  • 复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
  • 标记清理:一块区域,标记可达对象(可达性分析),然后回收不可达对象,会出现碎片,那么引出
  • 标记-整理算法:多了碎片整理,整理出更大的内存放更大的

6、垃圾回收集器

  • Serial New收集器是针对新生代的收集器,采用的是复制算法
  • Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理
  • Parallel Scavenge(并行)收集器,针对新生代,采用复制收集算法
  • Serial Old(串行)收集器,新生代采用复制,老年代采用标记整理
  • Parallel Old(并行)收集器,针对老年代,标记整理
  • CMS收集器,基于标记清理
  • G1收集器:整体上是基于标记整理 ,局部采用复制

7、 Java中垃圾回收有什么目的?什么时候进行垃圾回收?

  • 垃圾回收的目的是识别并且丢弃应用不再使用的对象来释放和重用资源。
  • 触发主GC(Garbage Collector,垃圾回收)的条件:
    • 当应用程序空闲时,即没有应用线程在运行时,GC会被调用。
    • Java堆内存不足时,GC会被调用。

8、进行垃圾回收几种类型?

  • 在新生代的Eden区满了,会触发新生代GC(Mimor GC);
  • 经过多次触发新生代GC存活下来的对象就会升级到老年代;
  • 升级到老年代的对象所需的内存大于老年代剩余的内存,则会触发老年代GC(Full GC);
  • 当程序调用System.gc()时也会触发Full GC;

9、线程的几种状态。

  • 在线程的生命周期中,它要经过 新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态。
  • 尤其是当线程启动以后,它不可能一直”霸占”着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。

参考资料:https://juejin.im/post/5b10e53b6fb9a01e5b10e9be

10、JVM优化策略

  • 给JVM设置-XX:+HeapDumpOnOutOfMemoryError参数,让JVM碰到OOM场景时输出dump信息。 说明:OOM的发生是有概率的,甚至有规律地相隔数月才出现一例,出现时的现场信息对查错非常有价值。
  • 在线上生产环境,JVM的Xms和Xmx设置一样大小的内存容量,避免在GC 后调整堆大小带来的压力。

Java程序员面试题(网络篇)(一)

1、http请求方式

  • HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
  • HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

2、GET 和 POST 区别

3、OSI的7层体系结构

OSI分层 (7层):物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

4、TCP/IP的体系结构

TCP/IP分层(4层):网络接口层、 网际层、运输层、 应用层。

5、五层协议的体系结构

五层协议 (5层):物理层、数据链路层、网络层、运输层、 应用层。

6、各层协议和作用

  • 物理层:RJ45、CLOCK、IEEE802.3 (中继器,集线器,网关)
  • 数据链路:PPP、FR、HDLC、VLAN、MAC (网桥,交换机)
  • 网络层:IP、ICMP、ARP、RARP、OSPF、IPX、RIP、IGRP、 (路由器)
  • 传输层:TCP、UDP、SPX
  • 会话层:NFS、SQL、NETBIOS、RPC
  • 表示层:JPEG、MPEG、ASII
  • 应用层:FTP、DNS、Telnet、SMTP、HTTP、WWW、NFS

每一层的作用如下:

  • 物理层:通过媒介传输比特,确定机械及电气规范(比特Bit) 数据
  • 链路层:将比特组装成帧和点到点的传递(帧Frame)
  • 网络层:负责数据包从源到宿的传递和网际互连(包PackeT)
  • 传输层:提供端到端的可靠报文传递和错误恢复(段Segment)
  • 会话层:建立、管理和终止会话(会话协议数据单元SPDU)
  • 表示层:对数据进行翻译、加密和压缩(表示协议数据单元PPDU)
  • 应用层:允许访问OSI环境的手段(应用协议数据单元APDU)

7、TCP三次握手全过程

  • 客户端发送SYN请求,进入SYN_SEND状态
  • 服务端收到SYN请求,并返回一个ACK应答,并发送一个SYN其请求,服务器进入SYN_RECV状态
  • 客户端收到服务端的SYN请求和ACK应答,发送ACK应答,客户端进入ESTABLISH状态,服务端收到应答后进入ESTABLISH。如果没有收到应答,数据包都会根据TCP的重传机制进行重传。

8、TCP 四次挥手的全过程

  • 客户端发送FIN包,请求断开连接,客户端进入FIN_WAIT1状态
  • 服务端收到FIN包后返回应答,进入CLOSE_WAIT状态
  • 客户端收到FIN的应答后进入FIN_WAIT2状态
  • 服务端发送FIN请求包,进入LAST_ACK状态
  • 客户端收到FIN请求包后,发送应答进入TIME_WAIT状态
  • 服务器收到ACK应答后,进入close状态。

9、IP地址的分类

  • A类地址(1~126):网络号占前8位,以0开头,主机号占后24位。
  • B类地址(128~191):网络号占前16位,以10开头,主机号占后16位。
  • C类地址(192~223):网络号占前24位,以110开头,主机号占后8位。
  • D类地址(224~239):以1110开头,保留位多播地址。
  • E类地址(240~255):以1111开头,保留位今后使用。

注意

(1) 网络号剩余字段全为0的IP地址是保留地址,表示本网络,如00000000+24位主机号

(2) 主机号全为0表示本网络本身,例如202.98.174.0;主机号全为1表示本网络的广播地址,例如202.98.174.255。

(3) 127.X.X.X网络保留做为环路自检地址,该地址表示任意主机本身,目的地址为环路自检地址的IP数据报永远不会出现在任何网络上。

(4) 32位全为1,即255.255.255.255表示整个TCP/IP网络的广播地址;32位全为0,即0.0.0.0表示本网络上的本主机。

(5) 各类地址中,私有IP地址网段:此时,IP地址与子网掩码相与得到网络号

A类:1个A类网段,即10.0.0.0~10.255.255.255

B类:16个B类网段,即172.16.0.0~172.31.255.255

C类:256个C类网段,即192.168.0.0~192.168.255.25

10、说说http和https协议

11、tcp,udp区别

Java程序员面试题(基础篇)(三)

1、 Overload 和 Override 的区别。Overloaded 的方法是否可以改变返回值的类型?

  • 方法的重写 Overriding 和重载 Overloading 是 Java 多态性的不同表现。重写 Overriding 是父类与子类之间多态性的一种表现,重载 Overloading 是一个类中多态性的一种表现。
  • 如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的 定义如同被”屏蔽”了。
  • 如果在一个类中定义了多个同名的方法,它们或有不同的参数个数,或有不同的参数类型,则称为方法的重载(Overloading)。
  • Overloaded 的方法是可以改变返 回值的类型。

2、Collection 和 Collections 的区别。

  • Collection 是集合类的上级接口,继承与他的接口主要有 Set 和 List.
  • Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

3、java 中有几种类型的流?JDK 为每种类型的流提供了 一些抽象类以供继承,请说出他们分别是哪些类?

  • 字节流,字符流 。
  • 字节流继承于 InputStream OutputStream ,
  • 字符流继承于 InputStreamReader OutputStreamWriter。
  • 在java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。

4、error 和 exception 有什么区别 ?

  • error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
  • exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

5、父类子类多态关系

A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:

  • 类的继承具有传递性,子类可以通过向上转型的方式无条件地赋值给父类对象;
  • 父类通过向下转型赋值给子类时,必须通过强制类型转换。

6、Math中floor、ceil、round方法区别

  • floor: 求小于参数的最大整数。返回double类型 n. 地板,地面 例如:Math.floor(-4.2) = -5.0
  • ceil:求大于参数的最小整数。返回double类型 vt. 装天花板 例如:Math.ceil(5.6) = 6.0
  • round: 对小数进行四舍五入后的结果。返回int类型 例如:Math.round(-4.6) = -5

7、list是一个ArrayList的对象,如何在Iterator遍历的过程中正确并安全的删除一个list中保存的对象?

  • Iterator 支持从源集合中安全地删除对象,只需在 Iterator 上调用 remove() 即可。
  • 这样做的好处是可以避免 ConcurrentModifiedException ,当打开 Iterator 迭代集合时,同时又在对集合进行修改。
  • 有些集合不允许在迭代时删除或添加元素,但是调用 Iterator 的remove() 方法是个安全的做法。

8、jsp中静态include和动态include的区别

  • 静态的include:是jsp的指令来实现的,< %@include file=”xx.html”%> 是共享request请求域,先包含再编译,不检查包含页面的变化。不允许有相同的变量。 是在翻译阶段执行。
  • 动态的include:是jsp动作来实现的, 是不共享request请求域,先编译在包含,是要检查包含页面的变化的。在请求处理阶段执行。

9、Servlet的生命周期可以分为初始化阶段,运行阶段和销毁阶段三个阶段

  • init():仅执行一次,负责在装载Servlet时初始化Servlet对象
  • service() :核心方法,一般HttpServlet中会有get,post两种处理方式。在调用doGet和doPost方法时会构造servletRequest和servletResponse请求和响应对象作为参数。
  • destory():在停止并且卸载Servlet时执行,负责释放资源

10、线程与进程的区别?

  • 地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
  • 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
  • 调度和切换:线程上下文切换比进程上下文切换要快得多。
  • 在多线程OS中,进程不是一个可执行的实体。