1、加密算法有哪些?

  • 对称加密算法,对称加密算法就是用同一个密钥对明文进行加密和解密,这样计算量小,加密效率高,加密速度快,可逆,但是交易双方都使用同一个密钥,安全性难以保障,并且对于密钥的管理也成为了一种负担,适用于对于大量数据的加密,比如保存用户手机号,身份证等敏感信息但能解密的信息,常见的对称加密算法有AES(128位密钥),DES(64位密钥),3DES
  • 非对称加密算法,非对称加密算法就是一对匹配的公钥和私钥,发送方通过获取接收方的公钥对明文加密,然后接收方用自己的私钥对密文进行解密,这样安全性更高,方便密钥的管理,但是不可逆,加密解密的时间长,速度慢,适用于对少量数据的加密,比如签名和认证,常见的非对称加密算法有RSA,DSA(数字签名用),ECC(移动设备用)

2、加密的种类

  • 不可逆加密,一旦加密就不可以反向解密,一般用于对密码或者卡号等不可解密的信息,常见的加密算法有MD5,SHA,HMAC!

3、验证码是怎么实现的,目的是什么?

  • 方式一,通过img的src属性进行get请求controller层,然后controller层定义一个图片缓冲区BufferedReader并获取一个画笔,通过画笔调整颜色和背景框,通过随机取字符串下标的方式获取验证码,并放到session中,最终转换成ImageIO返回给前端
  • 方式二,通过kaptcha工具类,通过配置文件配置他就可以了!
  • 目的:防止登录是暴力破解和恶意注册!

4、上传多张图片如果出现了网络异常怎么办?

  • 可以通过事务的方式处理,首先设置成手动提交事务,然后利用try,catch中的catch,如果发生异常则回滚,如果是未发生异常提交即可!

5、token认证的目的

  • 防止在未登录的情况下,通过url的方式获取数据
  • 实现方式是主要是利用了JWT框架,通过JWT的签名的方法获取一段字段串返回给前端,然后每次请求的时候都需要带上token,后端校验token是否正确,然后返回数据或者错误信息!

6、new方式和newInstance方式的区别

  • 如果想要获取对象的私有属性和方法只能通过反射的方式获取
  • new的话必须知道类名,反射可以事先不知道类名,通过参数的传递获取类名,比如Spring中的bean注入
  • new是静态编译,反射式动态编译,静态编译是把所有内容都生成exe文件,而动态遍历是需要谁调用谁,节省资源!

7、平常写代码的时候使用过哪些设计模式?

  • 单例模式,只能自己创建自己,并且只有一个实例。有饿汉式,懒汉式,双检索等方式。常见的地方有spring的bean,默认采用的是单例模式中的饿汉式,还有Runtime,采用也是饿汉式。他们都符合单例模式的特点,只能创建一个实例。
  • 代理模式,代理模式在生活中的体现未我要结婚,然后需要一个婚庆公司来帮我打理一些琐事,在代码中体现的话有加日志,事务等等。代理模式分别有静态代理和动态代理两种,静态代理事先就知道代理的对象,所以只能代理一个类,而动态代理在运行的时候才知道要代理的对象,可以代理接口,代理任意的实现类。

8、常用的排序有哪些,什么时候会用到排序?

  • 冒泡排序,两两比较,每次循环都会找到最大的放到最后,直接循环结束,时间复杂度是O(n^2)
  • 快速排序,首先选定一个基准,然后让基准左边的元素都小于它,右边的元素都大于它,然后递归基准左边的元素和右边的元素!时间复杂度是O(logn),但是不稳定
  • 插入排序,将每个元素和前面的元素依次比较,知道找到自己的位置放进入即可,时间复杂度是O(n^2)

9、锁有哪些?

  • 公平锁/非公平锁,公平锁就是按照申请锁的顺序来获取锁,非公平锁并非如此,ReentrantLock默认是非公平锁,但是可以通过构造函数设置为公平锁,Synchronized是非公平锁
  • 可重入锁,又称为递归锁,当进入外层带有锁的方法时候,内存的方法也会加上锁,可以避免死锁,ReentrantLock和Synchronized都是可重入锁
  • 独享锁和共享锁,共享锁代表一个锁可以被多个线程同时访问,独享锁代表一个锁只能被一个线程独享,ReentrantLock,Synchronized都是独享锁,而ReaderWriterLock是共享锁
  • 乐观锁和悲观锁,乐观锁认为当对同一个数据进行并发操作的时候是不会发生修改的,所以不必加锁,适用于大量数据的读写,悲观锁则认为对同一个数据进行并发操作的时候肯定会发生修改的,必须加锁,反而效率变低了
  • 偏向锁/轻量级锁/重量级锁
  • 分段锁,即使把锁的粒度变小了
  • 自旋锁,尝试获取锁的线程不会立即阻塞,然后通过循环的方式尝试获取锁,这样做的目的减少了线程之间的切换,但是增加了cpu的消耗!

10、使用@Transaction注解的坑

@Transaction注解失效的情况

  • @Transaction的方法必须是public
  • 同一个类中,两个@Transaction方法直接嵌套会失效

11、#,$的区别

  • #通过占位符的方式来替换内容,$是通过字符串替换的方式
  • #是会在还没有替换内容的时候,进行一次预编译,当替换的时候,不是在编译sql,所以有效的防止了sql注入

12、IO用到了哪些设计模式,代理模式和装饰模式的区别

  • 使用到了适配器模式 适配器模式是将一个接口转换成客户期望的接口,比如说将字符串转换成字节数据,字节数据转换成流数据,
  • 还使用到了装饰模式,装饰模式是在类本身的基础上添加一些额外的功能,比如说把InputStreamReader转成BufferedReader
  • 代理模式强调的是找一个对象来帮你处理一些事情,对代理的对象施加控制,而装饰模式强调的增强自身

13、什么情况下ArrayList增删比LinkedList快

  • 在中间增删的时候,ArrayList是比LinkedList快的
  • 因为通过源码我们可以看到Linked在增删的时候,会有一个加速,如果此索引小于链表长度的二分之一的时候,从左往右遍历, 否则从右往左遍历,当数据量大的时候,如果插入了中间则会从右往左遍历比ArrayList往后移动慢

14、为什么双检索要在对象上加volatile?

  • 首先双检索的方式保证了线程的安全性(通过加锁的方式)并且还提升了效率(就是当初始化对象完毕之后,不需要在竞争锁了,第一份if循环就进不去了)
  • volatile关键字可以保证原子性和禁止指令重排序,因为初始化对象和指向对象分配内存地址两个不存在依赖关系,在运行的时候发生重排序,不一定谁先执行,如果先执行指向分配内存地址,另外一个线程进来了,还未初始化,但是变量此时不是null了,则很有可能发生异常,所以必须加volatile

15、SpringBoot中依赖有哪些,其中starter中哪些,作用是什么?

  • spring-boot-starter-web+spring-boot-starter-jdbc+mysql-connect-java
  • spring-boot-starter主要包含了自动配置和日志和YAML
  • spring-boot-maven-plugin,maven打包的依赖

16、SpringBoot的入口主类是什么,启动流程是什么?

  • @SpringBootApplication注解下的SpringApplication中的run方法

17、为什么要用SpringBoot ,自动配置的原理是什么?

  • 首先我们知道SSM的配置文件有很多个,简称是“配置地狱”,然后SpringBoot就诞生了,他有一些自动配置,节省了配置
  • 自动配置的原理其实就是因为@SpringBootApplication注解中的@EnableAutoConfiguration
  • @EnableAutoConfiguration中有@AutoConfigurationPackage自动导入配置到和@Import(AutoConfigurationImportSelector.class)自动导入选择器

18、redis五种键值类型

  • String,字符串
  • Hashs,哈希表,哈希表的元素是字符串
  • Lists,list集合
  • Sets,set集合
  • Sorted sets,有序集

19、java的优点,三个以上

  • 分布式,跨平台,一次编译到处运行
  • 语言简单,很像C+
  • 面向对象,相对于面向过程来说,面向对象更加符合人的想法

20、IO流了解哪些,怎么读写文件

  • 按照流的方向分为输入流和输出流,按照处理的单位不同有分为字符流和字节流
  • 输入流是把其他地方的内容输入到程序中,输出流是把程序中的内容写到其他地方,字节流是每次只读取一个字节,字符流每次读取两个字节
  • bio是同步阻塞IO,一个连接一个线程,nio是同步非阻塞io,一个请求一个线程,aio是异步非阻塞io,一个有效的请求一个线程
  • 读文件可以通过fileinputstream(字节),inputstreamreader(字符),bufferreader(行),输出的话有bufferedwriter和filewriter

21、游标了解不,怎么使用

  • 游标是处理数据的一种方法,可以查看或者处理结果集中的数据,只适用于存储过程和函数
  • 可以通过declare 定义游标,通过open和close打开和关闭游标,fetch处理结果

22、为什么使用索引提高了查询的效率?

  • 使用索引的目的就是为了提高查询效率,而提高查询效率的方法就是检查数据检索的范围
  • 索引是利用b+树的方式来减少数据检索的范围,数据检索的次数和树的高度有关,主要过程就是从上往下遍历,如果比这个数小就找左子树,在区间的话就找中间,大的话找右边的

23、开发中常见的规范

  • 命名规范,比如类名用大驼峰,方法名用小驼峰等,常量名大写
  • mysql中window下是不区分大小写,Linux区分,所以命名一般用下划线

24、jdk1.8之后的新特性

  • lambda表达式,函数式接口
  • 接口中可以有默认的方法(default)和静态方法

25、设计模式六大原则

  • 单一职责原则
  • 开闭原则
  • 接口隔离原则
  • 里氏替换原则
  • 依赖倒置原则
  • 迪米特原则

26、vue和jq的本质区别

  • jq式通过选择器($)获取DOM对象并进行赋值取值等操作,想当于一个js封装库,简化了js代码,但是数据和视图并没有分离
  • vue把视图和数据分离开了,通过v-mode的方式进行双向绑定,采用的式MVVM设计模式!