java面试题

 java面试题(这个条例清晰)

https://blog.csdn.net/weixin_41835916/article/details/81413498

一、Java的设计模式;

   网址链接:https://www.cnblogs.com/zhaojinyan/p/9401010.html

java的设计模式大体上分为三大类:

  • 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。
  • 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。
  • 行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

单例模式的代码实现

https://www.cnblogs.com/peter-hao/p/Singleton.html

 

一、java基础

 

Java中基本类型和引用类型的区别

  1.基本数据类型:byte short  int long  float double  char boolean 

  2.引用数据类型:
  类、接口类型、数组类型、枚举类型、注解类型。

      两者的区别:

 

   基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上。
  引用数据类型在被创建时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址

 

static关键字 

  • static 关键字可以用来修饰:属性、方法、内部类、代码块;

  • static 修饰的资源属于类级别,是全体对象实例共享的资源;

  • 使用 static 修饰的属性,静态属性是在类的加载期间初始化的,使用类名.属性访问

final 有什么用?

用于修饰类、属性和方法;

  • 被final修饰的类不可以被继承
  • 被final修饰的方法不可以被重写
  • 被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的

String,StringBuffer与StringBuilder的区别

String是字符串常量

StringBuffer是字符串变量,是线程安全

StringBuilder是字符串变量,是线程不安全的

一般:Stringbuff适用于多线程时使用,Stringbuilder在单线程下执行效率更高,String适用于少量的字符串操作的情况下

 

HashMap面试相关

  HashMap的底层是由数组和链表组成的(JDK1.7),JDK1.8中HashMap是有由数组+链表+红黑树组成

所有集合类都位于java.util包下。Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。

Collection:一次存一个元素,是单列集合;

   Collection集合主要有List和Set两大接口

      List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以重复。  

      Set:无序(存入和取出顺序有可能不一致),不可以存储重复元素。必须保证元素唯一性。

Map:一次存一对元素,是双列集合。Map存储的一对元素:键–值,键(key)与值(value)间有对应(映射)关系。

 

HashSet和HashMap的区别:
(1)HashSet实现了Set接口, 仅存储对象; HashMap实现了 Map接口, 存储的是键值对.

(2)HashSet也不允许出现重复值 HashSet底层其实是用HashMap实现存储的, HashSet封装了一系列HashMap的方法. 依靠HashMap来存储元素值,(利用hashMap的key键进行存储), 而value值默认为Object对象

ArrayList、LinkedList、Vector 的区别

   1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
     2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
     3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

ArrayList和HashMap的区别;

https://blog.csdn.net/yaodieteng1510/article/details/79582925

相同点:

    1)都是线程不安全,不同步 

    2)都可以储存null值

    3)获取元素个数方法一样,都用size()方法获取

区别:

    1)实现的接口

    ArrayList实现了List接口(Collection(接口)->List(接口)->ArrayList(类)),底层使用的是数组;而HashMap现了Map接口(Map(接口)->HashMap(类)),底层使用的是Hash算法存储数据。

    2)存储元素

     ArrayList是数组,里面的元素是有序的,可以重复的,

  HashMap是数组和链表(JDK1.7),数组+链表+红黑树(JDK1.8)组成的,里面的元素是无序的,key不能重复,value可以重复,(键的哈希码(hashCode)不可以相同,相同后面的值会将前面的值覆盖);

    3)添加元素的方法

    ArrayList用add(Object object)方法添加元素,而HashMap用put(Object key, Object value)添加元素。

    4)默认的大小和扩容

    在 Java 7 中,ArrayList的默认大小是 10 个元素,HashMap 的默认大小是16个元素(必须是2的幂)。

 

HashMap和HashTable的区别(简述版)

  1.继承的父类不同

  HashMap继承的是AbtractMap,HashTable继承的是Dictionary,但是两者均实现了Map接口。

  2.线程安全性不同

  HashMap是不安全的,HashTable是安全的。因为HashTable所有的方法全是 synchronized的。

  3.存放的元素是否可为空

  HashMap中key和value都允许为空,但是null为key的键值对只能有一对;而HashTable中key,value都不允许为空。

  4.是否保留了Contains方法

  HashMap不提供Contains方法,但是有containsValue和ContainsKey方法;

  而HashTable既有Contains方法也有containsValue和ContainsKey方法。其中Contains和containsValue功能相同。

  5.Hash值不同

  HashMap重新计算了key的Hash值,而HashTable直接使用了key的HashCode()。

  6.遍历方式不同

  HashMap和HashTable都可以使用Iterator遍历,但是HashTable还可以使用Enumeration的方式。 

  7.初始容量不同

  HashMap在不定义初始容量的情况下默认容量是16,而HashTable为11。

  8.扩容方式不同

  HashMap的扩容方式为乘以2,而HashTable的扩容方式为乘以2再减1。 

多线程有关的问题

https://blog.csdn.net/zl1zl2zl3/article/details/81868173

 Thread的run()与start()的区别

https://blog.csdn.net/xuxurui007/article/details/7685076

java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。


在Java当中,线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
  第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
  第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
  第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
  第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。
  第五是死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

实现并启动线程有两种方法
1、写一个类继承自Thread类,重写run方法。用start方法启动线程
2、写一个类实现Runnable接口,实现run方法。用new Thread(Runnable target).start()方法来启动

创建线程的四种方式

  1. 继承Thread类
  2. 实现Runnable接口
  3. 使用Callable和Future创建线程
  4. 使用Executor框架创建线程池

多线程原理:相当于玩游戏机,只有一个游戏机(cpu),可是有很多人要玩,于是,start是排队!等CPU选中你就是轮到你,你就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()。

调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点,没这个start不行。

1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。
记住:多线程就是分时利用CPU,宏观上让所有线程一起执行 ,也叫并发

Java中如何获取到线程dump文件

1)获取到线程的pid,可以通过使用jps命令,在Linux环境下还可以使用ps -ef | grep java

2)打印线程堆栈,可以通过使用jstack pid命令,在Linux环境下还可以使用kill -3 pid

 

多线程中wait和sleep的区别;

https://www.cnblogs.com/huangjianping/p/7874811.html

wait和sleep区别
共同点: 

1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。 
2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。 
 
不同点: 
1. Thread类的方法:sleep(),yield()等 
   Object的方法:wait()和notify()等 
2. 每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。 
   sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。 
3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用 
4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
所以sleep()和wait()方法的最大区别是:
  sleep()睡眠时,保持对象锁,仍然占有该锁;
  而wait()睡眠时,释放对象锁。
  但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)。
sleep()方法
sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;
   sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。
  在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。 
wait()方法
wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问;
  wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。
  wiat()必须放在synchronized block中,否则会在program runtime时扔出“java.lang.IllegalMonitorStateException”异常。

 

synchronized 和Lock区别

https://blog.csdn.net/hefenglian/article/details/82383569

    1. 来源: 
      lock是一个接口,而synchronized是java的一个关键字,synchronized是内置的语言实现;

    2. 异常是否释放锁: 
      synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁;而lock发生异常时候,不会主动释放占有的锁,必须手动unlock来释放锁,可能引起死锁的发生。(所以最好将同步代码块用try catch包起来,finally中写入unlock,避免死锁的发生。)

    3. 是否响应中断 
      lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断;

    4. 是否知道获取锁 
      Lock可以通过trylock来知道有没有获取锁,而synchronized不能;

    5. Lock可以提高多个线程进行读操作的效率。(可以通过readwritelock实现读写分离)

    6. 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。

    7. synchronized使用Object对象本身的wait 、notify、notifyAll调度机制,而Lock可以使用Condition进行线程之间的调度,

volatile和synchronized的区别

  1. volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  2. volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
  3. volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
  4. volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  5. volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化

 

AIO、BIO、NIO的区别

1.BIO (同步阻塞I/O模式)

数据的读取写入必须阻塞在一个线程内等待其完成。

这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

2.NIO(同步非阻塞)

同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。

3.AIO (异步非阻塞I/O模型)

异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。

 IO与NIO区别:IO是面向流,NIO是面向缓冲区,IO是阻塞IO,NIO是非阻塞IO.IO没有选择器,NIO有选择器。

 

 

java类加载过程与反射;

https://blog.csdn.net/eff666/article/details/52203406

类的加载过程
  一个java文件从被加载到被卸载这个生命过程,总共要经历5个阶段,JVM将类加载过程分为:
  加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->卸载

2.1 java反射的定义

       java反射机制是在运行状态中(不是编译时),对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java的语言的反射机制。

 

JVM内存模型

 

  JVM内存空间分为五部分,分别是:方法区、堆、Java虚拟机栈、本地方法栈、程序计数器

  方法区主要用来存放类信息、类的静态变量、常量、运行时常量池等,方法区的大小是可以动态扩展的,

  堆主要存放的是数组、类的实例对象、字符串常量池等。

  java虚拟机栈和本地方法栈容易会发生OutOfMemoryError(内存不足错误)

  方法区和堆都是线程共享的,在JVM启动时创建,在JVM停止时销毁,而Java虚拟机栈、本地方法栈、程序计数器是线程私有的,随线程的创建而创建,随线程的结束而死亡。

forward和redirect的区别是什么

https://blog.csdn.net/weixin_37766296/article/details/80375106

 

是servlet种的两种主要的跳转方式。forward又叫转发,redirect叫做重定向。

forward(转发)
1.是服务器内部的重定向,服务器直接访问目标地址的 url网址,把里面的东西读取出来,但是客户端并不知道,因此用forward的话,客户端浏览器的网址是不会发生变化的。
2.关于request: 由于在整个定向的过程中用的是同一个request,因此forward会将request的信息带到被重定向的jsp或者servlet中使用。

redirect(重定向):
1.是客户端的重定向,是完全的跳转。即服务器返回的一个url给客户端浏览器,然后客户端浏览器会重新发送一次请求,到新的url里面,因此浏览器中显示的url网址会发生变化。
2.因为这种方式比forward多了一次网络请求,因此效率会低于forward。

Cookie 和session 的区别;

   1、Cookie和Session都是会话技术,Cookie是运行在客户端,Session是运行在服务器端。 

   2、Cookie有大小限制以及浏览器在存cookie的个数也有限制,Session是没有大小限制和服务器的内存大小有关。
   3、Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击。 
   4、Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。
 

http接口与webservice接口的区别

  1. http接口走http协议,通过路径来区分调用方法,请求报文一般是key-value形式的,返回报文一般是json串,常用的是get和post方法来请求。
  2. webservice接口走的soap协议,通过http传输,请求报文和返回报文都是xml格式的。

单点登录

https://blog.csdn.net/xiaoguan_liu/article/details/91492110

 

Redis支持5种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

redis的持久化如何实现

  RDB持久化和AOF持久化

  RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。

  AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集

Redis缓存

什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?
缓存穿透
一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。
如何避免?
1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。
2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。
缓存雪崩
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。
如何避免?
1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待
2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期
3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

 

Java中aop的具体实现;

线程池的理解;
两个线程的交互调用(例如奇偶数);

Http请求中含有pdf要设置什么;
跨域怎么解决;

Dubbo;
Redis;
阶乘公式的代码;
为什么要用 spring boot 和spring cloud;

HashMap的hashcode相关概念

 

3.Spring两大核心ioc和aop理解;

https://blog.csdn.net/dkbnull/article/details/87219562

https://blog.csdn.net/luoshenfu001/article/details/5816408

 

spring aop 的理解

一、AOP是什么?
    AOP的全称是Aspect Orient Programming,即面向切面编程。是对OOP(Object Orient Programming)的一种补充,专门用于处理一些具有横切性质的服务。常常用于日志输出、安全控制等。

二、实现技术?
       AOP(这里的AOP指的是面向切面编程思想,而不是Spring AOP)主要的的实现技术主要有Spring AOP和AspectJ。

1、AspectJ的底层技术。

       AspectJ的底层技术是静态代理,即用一种AspectJ支持的特定语言编写切面,通过一个命令来编译,生成一个新的代理类,该代理类增强了业务类,这是在编译时增强,相对于下面说的运行时增强,编译时增强的性能更好。

2、Spring AOP

       Spring AOP采用的是动态代理,在运行期间对业务方法进行增强,所以不会生成新类,对于动态代理技术,Spring AOP提供了对JDK动态代理的支持以及CGLib的支持。

       JDK动态代理只能为接口创建动态代理实例,而不能对类创建动态代理。需要获得被目标类的接口信息(应用Java的反射技术),生成一个实现了代理接口的动态代理类(字节码),再通过反射机制获得动态代理类的构造函数,利用构造函数生成动态代理类的实例对象,在调用具体方法前调用invokeHandler方法来处理。

       CGLib动态代理需要依赖asm包,把被代理对象类的class文件加载进来,修改其字节码生成子类。

       但是Spring AOP基于注解配置的情况下,需要依赖于AspectJ包的标准注解,但是不需要额外的编译以及AspectJ的织入器,而基于XML配置不需要。

 spring相关面试题

https://blog.csdn.net/a745233700/article/details/80959716

spring中bean的生命周期流程(很重要)

   Spring中Bean的实例化过程:

   

  • Spring容器 从XML 文件中读取bean的定义,并实例化bean。

  • Spring根据bean的定义填充所有的属性。

  • 如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。

  • 如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。

  • 如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。

  • 如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。

  • 如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。

  • 如果bean实现了 DisposableBean,它将调用destroy()方法。

 

Spring的主要模块(组件)  

  主要由以下几个模块组成:
  Spring Core:核心类库,提供IOC服务;
  Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
  Spring AOP:AOP服务;
  Spring DAO:对JDBC的抽象,简化了数据访问异常的处理;
  Spring ORM:对现有的ORM框架的支持;
  Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传;
  Spring MVC:提供面向Web应用的Model-View-Controller实现

Spring的注入:

  Spring通过DI(依赖注入)实现IOC(控制反转),常用的注入方式主要有三种:构造方法注入,setter注入,基于注解的注入

 Spring的有哪几种配置方式

  1.基于XML文件配置;2.基于注解配置;3.基于Java配置

Spring中事务是如何实现的

Spring的注解;

https://blog.csdn.net/sha1024/article/details/82791098

 

springMVC的原理

https://blog.csdn.net/a745233700/article/details/80963758

2、SpringMVC的流程

 

 

  (1).用户发送请求至前端控制器DispatcherServlet。

  (2).DispatcherServlet收到请求调用HandlerMapping处理器映射器。

  (3).处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

  (4). DispatcherServlet调用HandlerAdapter处理器适配器。

  (5).HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

  (6).Controller执行完成返回ModelAndView。

  (7).HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

  (8).DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

  (9).ViewReslover解析后返回具体View.

  (10).DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。 

  (11).DispatcherServlet响应用户。

 

Mybatis相关面试题

https://blog.csdn.net/a745233700/article/details/80977133

Mybatis的循环语句中的标签

https://blog.csdn.net/weixin_40950778/article/details/78655288


Mybatis的一级缓存和二级缓存;

1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。

2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/> ;

3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。

Mybatis中#和$符号区别;

1.#{}相当于对数据加上双引号,预编译的时候表示一个占位符号。

通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。#{}可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,
如果传入的值是111,那么解析成sql时的值为order by "111"。
如果传入的值是id,则解析成的sql为order by "id"。

 

2. ${}相当于直接显示数据,预编译的时候表示拼接sql串。

通过parameterTypesqljdbc可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,{}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。

将传入的数据直接显示生成在sql中。如:order by $user_id$,
如果传入的值是111,那么解析成sql时的值为order by user_id。
如果传入的值是id,则解析成的sql为order by id。

spring boot和spring cloud

什么是微服务

        以前的模式是 所有的代码在同一个工程中 部署在同一个服务器中 同一个项目的不同模块不同功能互相抢占资源

        微服务 将工程根据不同的业务规则拆分成微服务 微服务部署在不同的机器上 服务之间进行相互调用

        Java微服务的框架有 dubbo(只能用来做微服务),spring cloud(提供了服务的发现,断路器等)

Spring Boot 的自动配置是如何实现的?

这个是因为@SpringBootApplication 注解的原因,我们知道 @SpringBootApplication 看作是 @SpringBootConfiguration、@EnableAutoConfiguration@ComponentScan 注解的集合。

  • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
  • @ComponentScan: 扫描被@Component (@Service,@Controller)注解的bean,注解默认会扫描该类所在的包下所有的类。
  • @SpringBootConfiguration:允许在上下文中注册额外的bean或导入其他配置类

@EnableAutoConfiguration是启动自动配置的关键

springboot常用的starter有哪些

        spring-boot-starter-web 嵌入tomcat和web开发需要servlet与jsp支持

        spring-boot-starter-data-jpa 数据库支持

        spring-boot-starter-data-redis redis数据库支持

        spring-boot-starter-data-solr solr支持

        mybatis-spring-boot-starter 第三方的mybatis集成starter

 

springboot读取配置文件的方式

        springboot默认读取配置文件为application.properties或者是application.yml

spring cloud 的主要组件

服务发现——Netflix Eureka
服务间的负载均衡——Netflix Ribbon
断路器——Netflix Hystrix
服务网关——Netflix Zuul
分布式配置——Spring Cloud Config

 

1)、线程和线程池问题
2)、线程池在项目的什么地方用到
3)、手写单例模式或工厂模式
4)、linux命令,主要自己使用了那些
5)、final的用法
6)、字符拼接
7)、rabbitmq如果消息未接收到,该如何处理
8)、hashmap的底层原理
9)、json的操作工具
10)、json相关,json是重点
11)、数据库优化
12)、底层数据结构(集合)arraylist,hashmap,这个也是重点
13)、以前工作内容
14)、遇到问题怎么解决的
15)、索引
16)、联合查询优化
17)、数据库范式
18)、用到了那些应用服务器
19)、orm
20)、HQL怎么写的
21)、类加载过程
22)、反射

 

posted on 2019-06-10 16:06  北朔  阅读(341)  评论(0编辑  收藏  举报