面试
说说乐观锁和悲观锁的用法
- 悲观锁:对于并发间操作产生的线程安全问题持悲观状态,每次对某资源进行操作时,都会持有一个独占的锁,直接上了锁就操作资源了
- synchronized 互斥锁
采用synchronized修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。
每个对象都有一个monitor(锁标记),当线程拥有这个锁标记时才能访问这个资源,没有锁标记便进入锁池。任何一个对象系统都会为其创建一个互斥锁,这个锁是为了分配给线程的,防止打断原子操作。每个对象的锁只能分配给一个线程,因此叫做互斥锁。 - ReentrantLock 排他锁(悲观锁,有罪假设)
ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,不能同时发生,这在一定程度上降低了吞吐量。
- synchronized 互斥锁
- 乐观锁:对于并发间操作产生的线程安全问题持乐观状态,所以它不需要持有锁,将”比较-替换”这两个动作作为一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有相应的重试逻辑。
- ReentrantReadWriteLock
读写锁内部又分为读锁和写锁,读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。
读锁和写锁分离从而提升程序性能,读写锁主要应用于读多写少的场景。
- ReentrantReadWriteLock
介绍一下项目
蓝天权限管理后端系统是一个BS权限系统,主要针对公司员工实现不同角色访问的资源不同.主要是采用SSM+Spring cloud Alibaba微服务框架,
主要模块由UI模块(里面所有的前端页面,采用http+css+js)
网关模块:采用gateway网关组件实现由了对客户端发来的请求转发到具体的资源服务
认证模块:采用springsecurity安全框架实现了用户的认证授权功能
日志模块:分为登录日志和操作日志,采用Spring aop技术实现了系统登录日志查询包含登录异常
操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询
用户模块:采用SSM框架实现完成系统用户配置
角色管理模块:采用SSM框架,实现了角色菜单权限分配、设置角色按机构进行数据范围权限划分
部门管理模块:采用SSM框架实现了配置系统组织机构(公司、部门、小组),树结构展现支持数据权限
介绍spring IOC AOP思想
- IOC
控制反转,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。 - AOP
面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
springboot有哪些注解
@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
@ComponentScan:Spring组件扫描。
@mapperScan注解为接口创建代理对象
简述一下你做过的项目
待定!!!
redis的数据结构,在项目中应用的场景。
String类型,存字符串 实现博客点赞
- HashMap:储存对象信息,实现存储用户信息
- list:双向链表,热销榜,最新评论
- Set无序结合微博关注
请解释spring的aop和ioc实现原理==?==
IOC:控制反转也叫依赖注入,IOC利用java反射机制,AOP利用代理模式。所谓控制反转是指,本来被调用者的实例是有调用者来创建的,这样的缺点是耦合性太强,IOC则是统一交给spring来管理创建,将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的时候,就把它已经初始化好的那些bean分配给你需要调用这些bean的类。
AOP:面向切面编程。(Aspect-Oriented Programming)
AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。
实现AOP的技术,主要分为两大类:
- 一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;
- 二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码,属于静态代理
exception与error的区别
- Error类和Exception类都是继承Throwable类
- Error(错误)是系统中的错误,程序员是不能改变的和处理的,是在程序编译时出现的错误,只能通过修改程序才能修正。
- Exception(异常)表示程序可以处理的异常,可以捕获且可能恢复。
JAVA基础,基本类型,集合,反射
基本类型
类型名称 | 字节空间 | 取值范围 | |
---|---|---|---|
整数型 | byte | 1 | -27到27-1 或者 -128到127 |
- | short | 2 | -215到515-1 |
- | int | 4 | -231到531-1 |
- | long | 8 | -263到563-1 |
浮点型 | float | 4 | 单精度,对小数部分的精度要求不高 |
- | double | 8 | 双精度,精确的小数部分并操作值很大时 |
字符型 | char | 2 | 0到65535 |
布尔型 | boolean | 1 | 真true 假false |
mybatis中#和$的区别
#{} 这种取值是编译好SQL语句再取值
${} 这种是取值以后再去编译SQL语句
#{} 方式能够很大程度防止sql注入。
$ 方式无法防止Sql注入。
$ 方式一般用于传入数据库对象,例如传入表名.
一般能用 # 的就别用 $。
redis有几种数据类型,并说下各自的使用场景
一共五种
- String
最常规的set/get操作,value可以是String也可以是数字。 - List
使用List的数据结构,可以做简单的消息队列的功能。 - Hash
这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。 - Set
set堆放的是一堆不重复值的集合。 - sorted set
sorted set多了一个权重参数score,集合中的元素能够按score进行排列。
wait()与sleep()区别
- wait() 方法时object类的方法 sleep()是Thread类的方法
sleep() 让线程暂停一段时间,时间一到自动恢复执行,不设计线程间的通信 调用sleep()方法不会释放锁。 - Wait() 调用后线程会释放占用的锁,用于线程间的通信,只有其他线程调用notify()方法或者notifyall()才醒来
- 使用域不同
wait() 方法必须放在同步代码块和同步控制方法中使用,sleep() 方法则可以放在任何地方使用
sleep() 方法必须捕获异常 而wait() notify() notifyall() 不需要捕获异常
基于何种情况需要对数据库进行分库分表,如何分库分表
MySQL 分库分表是指:把 MySQL 数据库物理地拆分到多个实例或者机器上去。从而降低单台 MySQL 实例的负载。
垂直拆分:有多个业务,每个业务单独分到一个实例里面。
在一个实例中有多个库,把这些库分别放到单独的实例中。
在一个库中存在过多的表,把这些表拆分到多个库中。
把字段过多的表拆分成多个表,每张表包含一部分字段。
- 水平拆分
一般水平拆分是根据表中的某一字段(通常是主键 ID )取模处理,将一张表的数据拆分到多个表中。这样每张表的表结构是相同的但是数据不同。 - 垂直拆分
当一张表的字段过多时则可以考虑垂直拆分。
通常是将一张表的字段才分为主表以及扩展表,使用频次较高的字段在一张表,其余的在一张表
一个项目中有哪些类不需要注解
service接口和pojo层中自己写get/set/构造方法时不需要
平时遇到过什么bug?怎么解决的?
401 : 访问资源时没有认证。
403 : 访问资源时没有权限。
404:访问的资源找不到(一定要检查你访问资源的url)
405: 请求方式不匹配(客户端请求方式是GET,服务端处理请求是Post就是这个问题)
springboot常用注解,及对他的理解
请说出springboot常用注解
待定
spring相关问题
待定
常用设计模式
- 单一实例模式(唯一实例模式):就是指类在内存中至多只能有一个对象。
单列模式的实现
单列模式实现的要求
A: 外界不能够随意创建对象。(通俗的来讲就是把构造方法私有)
B: 类本身要创建一个对象(自己内部创建)。
C: 通过公共的方式把对象(单列的)提供给别人。 - 工厂模式
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象 - 装饰者模式概述
- 就是给接口(或者类)的 子类 创建一个装饰类对象,通过装饰类对象增强接口中实现类中的功能。
- 书写装饰类要求:
- 装饰类和被装饰的类实现相同的接口
- 要重写接口的所有方法
- 代理模式:动态代理就是给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问
spring进行事务管理就是通过动态代理 来进行的。
oracle中delete和drop,truncate的用法和区别
待定
redis的集群模式有几种,说说他们的区别
待定
spring boot有没有配置文件和spring注解
@Service=@Controller=@Component(注解作用相等)扫描包
@Autowired DI依赖注入,自动装配,自动布线
@CrossOrigin 解决跨域问题
@Value 从Spring容器内部为属性赋值
@Autowired 注解注入一个属性(有多个实现类的时候)的时候,由于它是按照类型查找的,
@Qualifie
@PropertySourcespring 容器启动时,动态添加配置文件 一般需要修改字符集
redis是单线程还是多线程
一开始的时候,Redis采用的是单线程模型,因为Redis是一个基于内存的数据库,将所有的数据放入内存,所以使用单线程的操作效率是最高的,多线程会上下文切换消耗大量时间,对于内存系统来说,单线程才能产生更高的效率。
数据库优化
- 数据库设计:数据表设计遵循三范式,使用合适的数据类型,使用合适的存储引擎
适当创建索引 - 数据库扩展:数据库的分表分库,读写分离等
SQL语句优化等
添加
请说出git常用命令
springboot自动装配原理
在spring程序main方法中 添加**@SpringBootApplication或者@EnableAutoConfiguration**会自动去maven中读取每个starter中的spring.factories文件 该文件里配置了所有需要被创建spring容器中的bean
springboot
@PreAuthorize(“hasAuthority(‘sys:res:create’)”)
oracle中如何创建索引,索引使用中应该注意哪些问题
待定
sql调优怎么做
查询SQL尽量不要使用select *,而是具体字段
避免在where子句中使用or来连接条件
使用varchar代替char
尽量使用数值替代字符串类型
查询尽量避免返回大量数据
使用explain分析你SQL执行计划
是否使用了索引及其扫描类型
spring容器
待定
数据库中union和unionall的区别
待定
什么是接口?接口在什么情况下使用?
待定
自己在上一家公司的工作内容。
待定
springboot如何切换环境配置
待定
docker
待定
springboot常用注解,以及分别做什么用
待定
说几个springboot 中常用的注解
待定
map,list,set区别,collection与collections区别
docker ?
redis的数据类型有哪些?说一下比较熟悉的组件;说一下对kafka的认识。
待定
数据库分库分表问题
待定
过滤器和拦截器的区别
- 过滤器:
是在javaweb中,你传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符。 - 拦截器 :
是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
项目功能
待定
spring aop的登录日志和操作日志的业务实现流程
待定
redis缓存数据类型
待定
是否为单线程
待定
时间复杂度
待定
缓存穿透
待定
rabbitmq的模式
待定
消息挤压
待定
多线程实现方式
- 继承Thread类的方式
- 实现Runnable接口的方式
- 实现Callable接口(1.5):需要借助FutureTask类,比如获取返回结果
- 使用线程池(1.5):提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中
线程的状态
阻塞(对象堵塞,等待堵塞,其他阻塞),新建,死亡,可运行(就绪),运行
线程池
待定
分布式缓存
待定
spring aop的登录日志和操作日志的业务实现流程
待定
spring后端服务部署
待定
mycat组件
待定
查看mysql的执行计划
explain
hashmap的实现原理(哈希碰撞)
待定
hashmap与hashtable的区别,实现原理
待定
equals与==的区别
待定
String的理解
待定
字符转反转
StringBuffer 或 StringBuilder 的 reverse 成员方
哈希碰撞
待定
复合索引(mysql)查询的条件有什么主意的地方
待定
like怎么写才可以走索引
满足最左前缀like ‘aa%’
git
待定
String为什么不可以被继承
被final修饰的类是不可以被继承的
异常的分类
空指针异常
cookie与session区别
待定
throws与throw区别
待定
mybaits如何避免sql注入
待定
final finally finalize
-
final
final是java中的一个关键字,学过C++的朋友可以将其和C++中的const关键字进行联想记忆,final这个关键字可以被应用在以下场景中:
final修饰类:该类不能被继承,所以一个类不能既被final修饰,又被abstract声明。
final修饰方法:该方法不能被重写。
final修饰变量:该变量就变成了一个常量,无法被重新赋值,且在定义的时候就必须赋初值,之后就无法被重新赋值了,就算是赋予相同的值也不行,在这个变量的生命周期中,它只能被读取,不能被修改。 -
finally
就如他字面意思一样:最终,不管发生什么,最终都会执行。
一般和try catch捕获异常一起进行使用,当在try代码块中出现异常,程序就会跳转到catch代码中执行,不至于让整个程序崩溃,而当try代码块中没有出现异常的时候,那么就会顺利的执行完整个try代码块,而有些时候,我们无法判断是否会出现异常,而且不管他有没有出现异常,有些代码段是一定要执行的,比如资源释放,断开连接等等,这些代码块就应该放到finally代码块中,这些代码块是无论try代码块中有无异常都是最终会被执行的 -
finalize
首先,他是一个方法名,是又Object类里面定义的一个方法,也就是说所有类中都存在这么一个方法,这个方法也可以类比C++中析构函数(就是在这个对象被清理前会自动调用的一种方法),在Java中存在垃圾回收机制,当检测到这个对象没有被引用的时候,就会自动调用这个方法,当然我们可以重写这个方法,去进行定制化的清理内存等功能。
实现短信发送(高并发)
待定
jvm堆栈
待定
servlet作用
待定