JAVA-面试题汇总

类型 存储需求 bit数 取值范围 备注
整型
byte 1字节 1*8 -128~127  
short 2字节 2*8 -32768~32767  
int 4字节 4*8    
long 8字节 8*8    
浮点型        
float 4字节 4*8   float类型的数值有一个后缀F(例如:3.14F)
double 8字节 8*8   没有后缀F的浮点数值(如3.14)默认为double类型
char类型        
char 2字节 2*8    
boolean类型        
boolean 1字节 1*8 false、true  

 

sql优化(点我)

LinkedeList和ArrayList的区别

数据结构不同
  ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。

效率不同
  当随机访问List(get和set操作)时,ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
  当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。

注意:
  如果 ArrayList:插入和删除的位置都在表末尾,LinkedList:读取数据位置离头部很近 那效率也是很高的。

@Component注解和@Bean注解的作用,以及两者的区别:

作用:

  @Component和@Bean都是用来注册Bean并装配到Spring容器中;

区别:

  1.@Component 作用于类,@Bean作用于方法。

  2.@Component(@Controller、@Service、@Repository)通常是通过类路径扫描自动装配到Spring容器中 (@ComponentScan、component-scan),

  @Bean 注解通常是我们在标有该注解的方法中定义产生这个bean的逻辑(见下图),@Bean 需要在配置类中使用Spring框架,即类上需要加上@Configuration注解,Spring Boot 框架需要加上 @SpringBootConfiguration 注解

  3.如果你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component注解的,因此就不能使用自动化装配的方案了,但是我们可以使用@Bean,当然也可以使用XML配置。

  •  如何让三个线程循序执行?

使用单个工作线程来执行任务,它的特点是能确保依照任务在队列中的顺序来串行执行,

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(t1);
executor.submit(t2);
executor.submit(t3);
executor.shutdown();

  • Spring Cloud Netflix-Zuul

是由netflix开源的API网关,实现动态路由、监控、授权、安全、调度等功能。

  • Eureka

用于服务的注册于发现

  • Feign

支持服务的调用以及均衡负载。

Feign服务之间调用超时时间:
  服务间调用其实走的是http请求,debug了一下默认的ReadTimeout时间为5s,ConnectTimeout时间为2s。用Fegin进行服务间调用,底层用的还是Ribbon。

  • Hystrix

处理服务的熔断防止故障扩散

Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入fallback代码。

  • XML 命名空间

提供避免元素命名冲突的方法

什么是业务中台

总体按轻前台、重中台的设计思想,

中台应具备支撑前台灵活、快速、多变特性的能力,同时中台承接核心经营业务逻辑,处理企业所有面向各类渠道、终端客户的经营业务,中台突出的是运营管控和协同能力,是基础生意逻辑,

而前台强调的是创新与灵活多变,适应多变的营销业务场景,满足差异化的用户体验。后台承载企业内部精细化成本绩效与内部阿米巴考核需要。

  • 单例、多例

单例(singleton):Spring如果不指定,默认就是单例的,创建容器时会立即创建单例对象。
多例(prototype):每次获取对象时才会创建对象,并且每次都会创建新的对象,如果 Spring 整合 struct2 框架需要设置为多例模式,因为 struct 的每个action对象都是一个新的对象。

配置:

方法一:
<
bean scope="singleton"> //prototype
方法二: @Scope(scopeName="prototype")
  • HashSet和TreeSet的区别

Set中元素不可以重复。

HashSet:

1.HashSet是无序的、是线程不安全的,可以放入null,但只能放入一个null (这里无序是指存入元素的先后顺序与输出元素的先后顺序不一致)。
2.内部的数据结构是哈希表,HashSet中保证集合中元素是唯一的方法:通过对象的hashCode和equals方法来完成对象唯一性的判断。
  如果对象的hashCode值不同,则不用判断equals方法,就直接存到HashSet中。
  如果对象的hashCode值相同,需要用equals方法进行比较,如果结果为true,则视为相同元素,不存,如果结果为false,视为不同元素,进行存储。
  注意:如果元素要存储到HashCode中,必须覆盖hashCode方法和equals方法。

TreeSet:
1.Treeset中的数据默认是排好序的,是线程不安全的,不允许放入null值。
2.TreeSet的底层实现是采用二叉树(红-黑树)的数据结构。
3.TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key。

TreeMap特点(类似于TreeSet):

1.无序,不允许重复(无序指元素顺序与添加顺序不一致)
2.TreeMap集合默认会对键进行排序,所以键必须实现自然排序和定制排序中的一种
3..底层使用的数据结构是二叉树

  • String、StingBuffer、StringBuilder

(1)如果要操作少量的数据用 String;
(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;
(3)单线程操作字符串缓冲区下操作大量数据 StringBuilder。

  • @Autowired 注解与 @resource 注解的区别

@Autowired

由Spring提供,默认按类型装配

public class UserService {
    @Autowired
    private UserDao userDao; 
}

如上代码所示,这样装配回去spring容器中找到类型为UserDao的类,然后将其注入进来。这样会产生一个问题,当一个类型有多个bean值的时候,会造成无法选择具体注入哪一个的情况,这个时候我们需要配合着@Qualifier使用。

@Qualifier告诉spring具体去装配哪个对象。

public class UserService {
    @Autowired
    @Qualifier(name="userDao1")    
    private UserDao userDao; 
}

 

@resource
由J2EE提供,默认按照byName自动注入:如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

public class UserService {
    @Resource(name="userDao",type="UserDao")  
    private UserDao userDao; 
}    

总结:
Spring属于第三方的,J2EE是Java自己的东西。使用@Resource可以减少代码和Spring之间的耦合。

反射

什么是反射

通过反射机制,可以在运行时访问 Java 对象的属性,方法,构造方法等。

反射的应用场景

开发通用框架 - 反射最重要的用途就是开发各种通用框架。很多框架(比如 Spring)都是配置化的(比如通过 XML 文件配置 JavaBean、Filter 等),为了保证框架的通用性,它们可能需要根据配置文件加载不同的对象或类,调用不同的方法,这个时候就必须用到反射——运行时动态加载需要加载的对象。
动态代理 - 在切面编程(AOP)中,需要拦截特定的方法,通常,会选择动态代理方式。这时,就需要反射技术来实现了。
注解 - 注解本身仅仅是起到标记作用,它需要利用反射机制,根据注解标记去调用注解解释器,执行行为。如果没有反射机制,注解并不比注释更有用。
可扩展性功能 - 应用程序可以通过使用完全限定名称创建可扩展性对象实例来使用外部的用户定义类。

反射的缺点

性能开销 - 由于反射涉及动态解析的类型,因此无法执行某些 Java 虚拟机优化。因此,反射操作的性能要比非反射操作的性能要差,应该在性能敏感的应用程序中频繁调用的代码段中避免。
破坏封装性 - 反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
内部曝光 - 由于反射允许代码执行在非反射代码中非法的操作,例如访问私有字段和方法,所以反射的使用可能会导致意想不到的副作用,这可能会导致代码功能失常并可能破坏可移植性。反射代码打破了抽象,因此可能会随着平台的升级而改变行为。

 数据存放在内存哪个位置

栈内存:
1.栈内存中存放局部变量、基本数据类型、对象引用;
2.栈内存中存储的数据可以实现数据共享(常量池数据也是共享的);
3.栈内存被要求存放在其中的数据的大小、生命周期必须是已经确定的;

堆内存:
1.存放对象实体,如:使用new 关键字创建的对象;
2.堆内存可以被虚拟机动态的分配内存大小,无需事先告诉编译器的数据的大小、生命周期等相关信息。

 String s = "abc"和String s = new String("abc")两张声明方式的不同之处

方式一:String s = "abc"
由于String类是final的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中。

方式二:String s = new String("abc")
是使用关键字new这种形式声明创建的,则是在程序运行期被动态创建,存放在堆中。

对象创建:
这里指的注意的是,采用new的方式,虽然是在堆中存储对象,但是也会在存储之前检查常量池中是否已经含有此对象,如果没有,则会先在常量池创建对象,然后在堆中创建这个对象的”拷贝对象“。这也就是为什么有道面试题:String s = new String(“xyz”);产生几个对象?的答案是:一个或两个的原因。因为如果常量池中原来没有”xyz”,就是两个。


还有值得注意的一点的就是:我们知道局部变量存储于栈内存当中。那么成员变量呢?答案是:成员变量的数据存储于堆中该成员变量所属的对象里面。
而栈内存与堆内存的另一不同点在于,堆内存中存放的变量都会进行默认初始化,而栈内存中存放的变量却不会。
这也就是为什么,我们在声明一个成员变量时,可以不用对其进行初始化赋值。而如果声明一个局部变量却未进行初始赋值,如果想对其进行使用就会报编译异常的原因了。

 拦截器和过滤器区别

1.拦截器是基于Java的反射机制,而过滤器(Filter)是基于函数回调;
2.从灵活性上说拦截器功能更强大些,过滤器能做的事情拦截器都能做;
3.过滤器在拦截器之前执行。

Spring MVC中的拦截器(Interceptor)

简介:
它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、登陆认证、记录请求信息的日志等。
实现方式:
1.通过实现HandlerInterceptor接口、或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter);
2.通过实现WebRequestInterceptor接口、或继承WebRequestInterceptor接口的实现类。
HandlerInterceptor 与 WebRequestInterceptor 的区别:
1.WebRequestInterceptor间接实现了HandlerInterceptor,只是他们之间使用WebRequestHandlerInterceptorAdapter适配器类联系;
2.接收参数不同,HandlerInterceptor 使用 HttpServletRequest接收参数、WebRequestInterceptor通过WebRequest获取参数,WebRequest是进一步封装了HttpServletRequest 和HttpServletResponse的,通过WebRequest获取Request中的信息更简便;
3.WebRequestInterceptor的preHandle是没有返回值的,HandlerInterceptor 的 preHandle 会返回布尔值。
方法说明:
preHandle() 方法:该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;
当其返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。
postHandle()方法:该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。
afterCompletion()方法:该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。

过滤器(Filter)

简介:
依赖于servlet容器,一个过滤器实例只能在容器初始化时调用一次,通常用的场景是:解决中文乱码问题、权限访问控制、过滤敏感词汇等。
方法说明(这三个方法返回值都是void):
init:属于Filter的生命周期方法、当web应用程序启动时,web服务器将创建Filter的实例对象,调用init方法,完成对象的初始化功能,从而能对用户的请求进行拦截。Filter对象只会创建一次,因此init方法也只会执行一次。
doFilter:对request和response进行一些预处理
destroy:属于Filter的生命周期方法、在服务器关闭之前执行,仅执行一次,用于释放过滤器使用的资源。

什么时候会出现线程安全问题

多线程并发操作做同一数据

线程池有哪几种

newFixedThreadPool(int nThreads)
创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程规模将不再变化,当线程发生未预期的错误而结束时,线程池会补充一个新的线程
newScheduledThreadPool(int corePoolSize)
创建了一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。
newCachedThreadPool()
创建一个可缓存的线程池,如果线程池的规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制
newSingleThreadExecutor()
这是一个单线程的Executor,它创建单个工作线程来执行任务,如果这个线程异常结束,会创建一个新的来替代它;它的特点是能确保依照任务在队列中的顺序来串行执行

进程与线程区别

1.线程是属于进程的,线程运行在进程空间内,一个程序至少有一个进程,一个进程至少有一个线程; 2.进程有独立的地址空间,线程有自己的堆栈和局部变量,但线程之间没有独立的地址空间。当进程退出时该进程所产生的线程都会被强制退出并清除;
3.在进程内创建、终止线程比创建、终止进程要快,同一进程内的线程间切换比进程间的切换要快;
4.同一个进程中的多个线程可以并发执行;
5.进程是运行中的程序,线程是进程内部的一个执行序列;
6.进程是资源分配的单元,线程是执行单元。

运行进程两种方法(windows系统)

// 方法一
Runtime run = Runtime.getRuntime();
run.exec("notepad");
// 方法二
ProcessBuilder pb = new ProcessBuilder("notepad");
pb.start();

线程的实现方式及区别?

继承 Thread 类,实现Runnable、Callable接口。

采用实现Runnable、Callable接口的方式创建多线程时,优势是:
1.线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。
2.Runnable的 public abstract void run(); 方法没有返回值,并且不能抛异常,Callable的 V call() throws Exception; 方法有返回值,并且能抛出异常。

实现Runnable接口代码:

public class SubRunnable implements Runnable{

    @Override
    public void run () {
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName()+"_"+i);
        }
    }

    public static void main(String[] args) {
        SubRunnable sr = new SubRunnable();
        Thread t = new Thread(sr);
        // 更改线程名字
        t.setName("123");

        t.start();
    }

}

/* 结果:
 * 123_0
 * 123_1
 * 123_2
 */

实现Callable接口代码:

public class SubCallable implements Callable<String> {

    @Override
    public String call () {
        return "call";
    }

    public static void main(String[] args) throws Exception{
        SubCallable sc = new SubCallable();
        FutureTask<String> ft = new FutureTask<String>(sc);
        Thread t = new Thread(ft);
        t.start();
        String s = ft.get();
        System.out.println(s);
    }

}

// 结果:call

实现Callable接口代码获取返回值,线程池方式:

  https://blog.csdn.net/rocgege/article/details/78442235

使用继承Thread类的方式创建多线程时优势是:
编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

劣势是:
线程类已经继承了Thread类,所以不能再继承其他父类。

Spirng MVC 是线程安全的吗

spring mvc默认是单例的,在不定义成员变量的情况下是线程安全的,否则是线程不安全的。
原因:

设置成员变量,那么在多个请求状态下,每次请求过来调用的Controller对象都是一个,该成员变量的值是被共享的;(也就是该成员变量在单例模式下是非线程安全的),如果只存在读取的操作,则不会有问题。如果存在写值的操作,则会出现问题,当成员变量值被改变之后,其他请求会请求到修改之后的值。
解决方法:
1.把spring mvc 通过注解@Scope(“prototype”)变成多实例模式;
2.在Controller中使用ThreadLocal变量;
注意:
所以在使用spring开发web 时要注意,默认Controller、Dao、Service都是单例的。

BYTE

byte 字节长度为:1字节,存放数据范围是:127/-128
如果这八位二进制数是有符号的:
最大数是127:是2的7次方减1,也就是127,最大数的二进制代码是01111111,由于是有符号的,所以最高位是符号位,0表示正数,其余位7个位全1表示最大数;
最小的数是-128:10000000所表示的数是-128。
如果这八位二进制数是无符号的:
最大的数是255。最高位参于数值计算,不再是符号位,最大数对应的二进制位是11111111,也就是2的8次方减1。
最小的数是0。对应的二进制位是00000000。

ERROR 和 Exception 结构图及区别

java.lang.Error: An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.

java.lang.Exception: The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.

在 Java 中,所有的异常都有一个共同的祖先 Throwable。Throwable 有两个重要的子类:java.lang.Exception(异常)和 java.lang.Error(错误),各自都包含大量子类。 


①.Exception(异常)是应用程序中可能的可预测、可恢复问题,通常出现在代码的特定方法和操作中。 Exception类有一个重要的子类RuntimeException,RuntimeException类及其子类表示“JVM常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。
②.Error(错误)表示运行应用程序中较严重问题。最常见的错误有程序进入死循环、内存泄漏、系统错误或底层资源的错误,在这种情况下,程序运行时本身无法解决 ,Error类对象由java虚拟机生成并抛出。
例:Java 内存溢出(java.lang.OutOfMemoryError。

异常处理

1.创建全局异常处理类;

2.把异常信息封装到消息类、返回给前端。

@ExceptionHandler:统一处理某一类异常,从而能够减少代码重复率和复杂度
@ControllerAdvice:异常集中处理,更好的使业务逻辑与异常处理剥离开
@ResponseStatus:可以将某种异常映射为HTTP状态码

Spirng Boot 的好处

1.约定大于配置原则、使用 Spring 项目引导页面可以在几秒构建一个项目,使开发人员更专注业务逻辑;
2.集成tomcat,不需要在服务器上去部署 tomcat,因为 Spring Boot 内嵌了 tomcat,我们只需要将项目打成 jar 包,使用 java -jar xxx.jar一键式启动项目
3.自动管理依赖;
缺点:
缺点是集成度较高,使用过程中不太容易了解底层。

JAVA 8新特性

Lambda 表达式。
接口有默认方法,允许给接口添加一个非抽象的方法实现,只需要使用 default关键字即可。
在包java.time新增了一组全新的时间日期API。

Spring 工具类

System.out.println(org.springframework.util.StringUtils.isEmpty(s));
System.out.println(org.springframework.util.StringUtils.hasLength(s));
org.springframework.util.Assert.isNull(s,"s不是null抛异常");
org.springframework.util.Assert.notNull(s,"s是null抛异常");

事务隔离级别

SERIALIZABLE(串行化)
REPEATABLE READ(可重复读)
READ COMMITTED(读已提交数据)
READ UNCOMMITTED(读未提交数据)

Mysql默认的事务隔离级别是可重复读,点我

Redis目前支持5种数据类型

String(字符串)
Hash(字典)
List(列表)
Set(集合)
Zset(有序集合)

Redis持久化

RDB:RDB通过快照全量数据备份,存储的是二进制序列化形式。

  缺点:在快照持久化期间修改的数据不会被保存,可能丢失数据。

AOF:Redis会将每一个收到的写命令通过write函数追加到文件中。

  缺点:RDB 在恢复大量数据时速度比 AOF 的恢复速度要快。

Oracle索引类型

逻辑上:
Single column 单行索引
Concatenated 多行索引
Unique 唯一索引
NonUnique 非唯一索引
Function-based函数索引
Domain 域索引
物理上:
Partitioned 分区索引
NonPartitioned 非分区索引
b-tree
Normal 正常型B树
Rever Key 反转型B树
Bitmap 位图索引

排除不扫描的包路径类文件

 排除扫描的包

	@ComponentScan(excludeFilters =
			{
					@ComponentScan.Filter(type = FilterType.REGEX,pattern = "com.action.other.*")
			})
参数说明:
FilterType.REGEX:根据正则过滤

 排除扫描的类文件

@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {MyConfig.class})})		

RabbitMQ、kafka、Redis的区别

rabbitMQ:
MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。
可以处理比较重的数据量,但是因为其他可靠性比较好,所以如果数据量大的话,效率也会比较低。
kafka:
追求高吞吐量,用来处理海量日志,但是可靠性比较低。
redis:
轻量型的mq,如果量大,那么效率低。

ZooKeeper是什么(分布式协调服务)?

它是一个为分布式应用提供一致性服务的软件,提供的功能包括:共享配置、协调锁资源、提供命名服务、配置维护、域名服务、分布式同步、组服务等。

RabbitMQ 有几种工作模式?

工作队列模式
发布订阅模式
路由模式
通配符模式
  符号#:匹配一个或多个词;
  符号*:只能匹配一个词。
Header模式
RPC工模式

参考:https://www.cnblogs.com/Jeely/p/10784013.html

IN走不走索引?

MySQL 4.1 以上版本的 IN 是走索引的, 但4.0及其以下版本是不走索引的。
可以用 exist 代替in,exist 的执行效率要高。

union和union all区别

union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;
union All:对两个结果集进行并集操作,包括重复行,不进行排序;

Jquery如何根据id获取元素值

获取对象:$("#id")
获取value值:$("#id").val()
获取对象属性:$("#id").attr("属性名")

详细:

input标签可以用$("#id").val();
span标签可以用$("#id").text(),赋值:在text后边的括号里加上值就好

SQL优化

Spring Boot中常用的三个注解

Java数据存储区域

:存放在运行期间用到的一些局部变量(基本数据类型的变量)和指向其他对象的引用地址。

:堆主要存放Java在运行过程中new出来的对象。类的非静态成员变量、跟随对象也放在堆中。
       备注:在类中声明的变量是成员变量,也叫全局变量,放在堆中。

方法区:它用于存储class二进制文件,包含了虚拟机加载的类信息、常量、静态变量。是各个线程共享的内存区域,因为是共享的区域,如果静态成员变量的值或者常量值被修改了直接就会应用到其它类的对象中。
              常量池:常量池是方法区的一部分内存。常量池在编译期间就将一部分数据存放于该区域,包含基本数据类型如int、long等以final声明的常量值,和String字符串。
              静态域:位于方法区的一块内存。存放类中以static声明的静态成员变量。

cookie 和 session

为什么使用 cookie和session?

在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。

cookie作用?

第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,
服务器通过浏览器携带的数据就能判断当前用户是哪个了。

区别:

1.cookie数据存放在客户的浏览器上(客户端),session数据放在服务器上。
2.cookie有安全隐患,放在浏览器上,内容可能被修改。
3.cookie 存放在浏览器上大小有限制。
4.session存在服务器上,当访问增多时,会比较占用服务器的资源。

Mysql与Oracle区别

Oracle收费 - Mysql开源的。

事务:

Oracle很早就完全支持事务。
Mysql使用innodb存储引擎才支持事务。

提交方式:

Oracle默认不自动提交,需要用户手动提交。
Mysql默认是自动提交。

分页:

Oracle需要使用rownum,最少写两层嵌套查询。
Mysql使用limit分页,参数一指定当前第几页,参数二:一页多少条记录。

数据类型:

Oracle - Mysql
NUMBER - int/DECIMAL
Date - DATATIME

函数名称区别:

Oracle - Mysql
nvl(u.email_address, 10) - IFNULL(u.email_address, 10)或ISNULL(u.email_address)
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
-
select date_format(now(),'%Y-%m-%d '%H:%i:%S');
length(str)- char_length()
SUBSTR('1234',2,2) - substring('1234',2,2)
decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值) - 无

MyBatis 与 Hibernate 区别

MyBatis的SQL语句是由程序员编写的,放在XML文件中执行,所以SQL的编写更加灵活。
SQL优化上,MyBatis要比Hibernate方便很多。
Hibernate是全自动,而MyBatis是半自动。
Hibernate数据库移植性远大于MyBatis。
MyBatis配置使用简单,而Hibernate配置使用相对复杂。
Hibernate拥有完整的日志系统,MyBatis则欠缺一些。

Redis为什么是单线程

Redis4.0之前是单线程运行的;Redis4.0后开始支持多线程。

  Redis 通过多线程方式在后台删除对象

简单来说,Redis在4.0之前使用单线程的模式是因为以下三个原因:
  使用单线程模式的Redis,其开发和维护更简单,因为单线程模式方便开发和调试。
  即使使用单线程模型也能够并发地处理多客户端的请求,主要是因为Redis内部使用了基于epoll的多路复用。
  对于Redis来说,主要的性能瓶颈是内存或网络带宽,而非CPU。

 线程状态

@Autowired和new的区别

什么是跨域请求及解决方案

如何产生跨域问题?

  协议+域名+端口+子域名 不同都会产生跨域问题,即 “同源策略”是浏览器最核心最基础的安全策略。

解决方案:

JSONP 

  实现原理概述:JSONP 本质上是利用 <script><img><iframe> 等标签不受同源策略限制,可以从不同域加载并执行资源的特性,来实现数据跨域传输。

  优点:兼容性好,在更加古老的浏览器中都可以运行。

  缺点:它只支持 GET 请求,而不支持 POST 请求等其他类型的 HTTP 请求。

CORS

  实现原理概述:是一个新的 W3C 标准,它新增的一组HTTP首部字段,允许服务端声明哪些源站有权限访问哪些资源。换言之,它允许浏览器向声明了 CORS 的跨域服务器,发出 XMLHttpReuest 请求,从而克服 Ajax 只能同源使用的限制。

  优点:开发者可以是使用普通的 XMLHttpRequest 发起请求和获取数据,比起 JSONP 有更好的错误处理。

  缺点:兼容性比  JSONP 差一些。

文章一:清楚说明跨域的请求,及解决方案

文章二:解决方案比较全面

ThreadLocal 线程本地变量

用来提供线程局部变量,变量值只对当前线程可见,每一个使用此变量值的新线程都会提供一个独立的变量值的副本,
并且每一个线程都可以独立地改变自己的副本,而不会影响其他线程的变量副本,实现线程之间的数据隔离。

使用场景:
Spring 事务并发、数据库连接、Session管理等。

文章一:简约的说明

文章二:详细的说明

 Docker部署Java服务

配置好 Dockerfile 和 docker-compose.yml 文件后

#打镜像
docker build -t docker_dbfc:1.0.0 .

#启动服务
docker-compose up -d

#查看日志
docker logs -f --tail="11" docker_dbfc

Mybatis-plus

简介:

MyBatis-plus是一款MyBatis的增强工具,在MyBatis 的基础上只做增强不做改变。
是国内团队苞米豆在MyBatis基础上开发的增强框架,扩展了一些功能,以提高效率。
引入 Mybatis-Plus 不会对现有的 Mybatis 构架产生任何影响,而且 MyBatis-plus 支持所有 Mybatis 原生的特性。

增强功能:

预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击。
支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码(生成自定义文件,避免开发重复代码),支持模板引擎、有超多自定义配置等。
通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作
支持 Lambda 形式 QueryWrapper 条件构造器进行条件查询,方便的编写各类查询条件,无需再担心字段写错
支持多达4种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题 。
内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询。
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询 。
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作。

悲观锁 & 乐观锁的原理及应用场景(点我)

java程序执行顺序(点我)

java中重载与重写的区别

Spring(IOC、AOP) && SpringMVC

Spring 是一个容器框架、核心是IOC、AOP。

AOP(面向切面编程)能够将业务模块所共同调用的逻辑,封装、抽取出来,提高代码的复用性,降低模块间的耦合度,并有利于未来的可维护性和扩展性。例如 日志管理、权限控制、事务处理、性能统计等
AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用 CGLIB 方式实现动态代理。
案例:
  比如业务A和业务B现在需要一个相同的操作,传统方法我们可能需要在A、B中都加入相关操作代码,而应用AOP就可以只写一遍代码,A、B共用这段代码。并且,当A、B需要增加新的操作时,可以在不改动原代码的情况下,灵活添加新的业务逻辑实现。

 

IOC(控制反转):把对象由程序员手动创建管理交给Spring容器管理,Spring 容器使用了工厂模式为我们创建了所需要的对象。

详细说明:

IOC(控制反转),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 调用构造方法创建一个对象,这个过程是由程序员自己来控制的。

而在 Spring 开发模式中,Spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用 Spring 提供的对象就可以了,这是控制反转的思想,把对象的管理工作交给了Spring容器。
简单点说,就是创建对象的控制权,被反转到了Spring框架上。

依赖注入 DI(Dependency Injection)
把当前对象所需要的外部资源动态的注入进来是通过DI来实现的,依赖注入的方式主要有四种:
  注解注入方式
  set注入方式
  构造器注入方式
  静态工厂注入方式

 

Spring MVC 是 Spring 提供给 Web 应用的框架。 

Spring Mvc框架处理请求流程:

* 前端控制器(DispatcherServlet)接收到请求后依据 处理器映射器(HandlerMapping)找到处理请求的 Controller

* Controller 调用Service、dao业务逻辑处理后返回 ModelAndView对象

* 如果是前后端不分离的项目,前端控制器(DispatcherServlet)请求视图解析器(ViewResolver)去进行视图解析并返回,进行视图渲染,向用户响应结果

HashMap底层:

 时间复杂度、空间复杂度:

  不复杂,入门不错,慢慢看可以看懂,点我跳转~

 

posted @ 2019-09-29 23:32  唐胜伟  阅读(271)  评论(0)    收藏  举报