Java基础
1.常用的Java集合有哪些,有什么应用场景
Java集合可以分为Collection和Map两种体系
Collection接口:单列数据,定义存取一组对象的方法的集合
LIst:元素有序、可重复的集合
Set:元素无序、不可重复的集合
Map接口:双列数据,保存具有映射关系“Key-value对”的集合
2. Java线程创建方式有几种,分别是什么,有哪些适用场景
继承Thread类创建线程类
(1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
(2)创建Thread子类的实例,即创建了线程对象。
(3)调用线程对象的start()方法来启动该线程。通过Runnable接口创建线程类
(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
(2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
(3)调用线程对象的start()方法来启动该线程。覆写Callable接口实现多线程(JDK1.5)
通过线程池启动多线程
(1)使用Executors类中的newFixedThreadPool(int num)方法创建一个线程数量为num的线程池。
(2)调用线程池中的execute()方法执行由实现Runnable接口创建的线程;调用submit()方法执行由实现Callable接口创建的线程。
(3)调用线程池中的shutdown()方法关闭线程池。 其中
Callable和线程池是JDK5之后新增的,与使用Runnable相比,Callable功能更强大些相比run()方法,可以有返回值
方法可以抛出异常
支持泛型的返回值
需要借助FutureTask类,比如获取返回结果
3. Java线程start方法和run方法的区别
- start方法启动了一个新的线程,而run方法不能启动一个新线程,还是在main线程下运行,程序依然是主线程一个线程在运行。
- 调用start方法可以启动线程,而run方法只是thread的一个普通方法还是在主线程中执行。
- 通过start()方法来启动的新线程,处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行相应线程的run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。start()不能被重复调用。而run方法能被重复调用,因为它就是一个普通的成员方法。
- start方法在执行线程体中代码时,在不执行完的情况下可以进行线程切换,而run方法不能,run方法只能进行顺序执行。
篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记【点击此处即可】免费获取
4. 多线程编程下,怎么解决线程的数据安全问题?
- 如果线程存在竞争临界资源,多线程访问下添加同步代码块synchronized解决,或者分布式排他锁进行临界资源控制。
- 在分布式多线程环境下,线程的数据安全尽量不要产生连接资源,使用线程本地化ThreadLocal实现线程资源隔离。
5.SpringIOC依赖注入怎么理解,spring有几种方式
- 属性注入,setter
- 构建pojo实体类和有参构造方法
- 工厂方法注入 (此种用的不多,扩展)
6.SQL注入是怎么产生的,怎么避免?
SQL 注入就是在用户输入的字符串中加入 SQL 语句,如果在设计不良的程序中忽略了检查,那么这些注入进去的 SQL
语句就会被数据库服务器误认为是正常的 SQL 语句而运行,攻击者就可以执行计划外的命令或访问未被授权的数据。 SQL 注入的原理主要有以下 4 点:
- 恶意拼接查询 我们知道,SQL 语句可以查询、插入、更新和删除数据,且使用分号来分隔不同的命令。例如:
SELECT * FROM users WHERE user_id = $user_id
其中,user_id 是传入的参数,如果传入的参数值为“1234;DELETE FROM users”,那么最终的查询语句会变为:SELECT * FROM users WHERE user_id = 1234; DELETE FROM users
如果以上语句执行,则会删除 users 表中的所有数据。- 利用注释执行非法命令。
SQL 语句中可以插入注释。例如:SELECT COUNT(*) AS 'num' FROM game_score WHERE game_id=24411 AND version=$version
如果 version 包含了恶意的字符串’-1’ OR 3 AND SLEEP(500)–,那么最终查询语句会变为:SELECT COUNT(*) AS 'num' FROM game_score WHERE game_id=24411 AND version='-1' OR 3 AND SLEEP(500)--
以上恶意查询只是想耗尽系统资源,SLEEP(500) 将导致 SQL 语句一直运行。如果其中添加了修改、删除数据的恶意指令,那么将会造成更大的破坏。- 传入非法参数
- 添加额外条件在 SQL
语句中添加一些额外条件,以此来改变执行行为。条件一般为真值表达式。例如:UPDATE users SET userpass='$userpass' WHERE user_id=$user_id;
如果 user_id 被传入恶意的字符串“1234 OR TRUE”,那么最终的 SQL 语句会变为:UPDATE users SET userpass= '123456' WHERE user_id=1234 OR TRUE;
这将更改所有用户的密码。
避免SQL注入 对于 SQL 注入,我们可以采取适当的预防措施来保护数据安全。下面是避免 SQL 注入的一些方法。
- 过滤输入内容,校验字符串
- 参数化查询
参数化查询目前被视作是预防 SQL 注入攻击最有效的方法。参数化查询是指在设计与数据库连接并访问数据时,在需要填入数值或数据的地方,使用参数(Parameter)来给值。
MySQL 的参数格式是以“?”字符加上参数名称而成,如下所示:
UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4
在使用参数化查询的情况下,数据库服务器不会将参数的内容视为 SQL 语句的一部分来进行处理,而是在数据库完成 SQL 语句的编译之后,才套用参数运行。因此就算参数中含有破坏性的指令,也不会被数据库所运行。- 安全测试、安全审计
除了开发规范,还需要合适的工具来确保代码的安全。我们应该在开发过程中应对代码进行审查,在测试环节使用工具进行扫描,上线后定期扫描安全漏洞。通过多个环节的检查,一般是可以避免SQL 注入的。
有些人认为存储过程可以避免 SQL注入,存储过程在传统行业里用得比较多,对于权限的控制是有一定用处的,但如果存储过程用到了动态查询,拼接 SQL,一样会存在安全隐患。下面是在开发过程中可以避免 SQL 注入的一些方法。
- 避免使用动态SQL
避免将用户的输入数据直接放入 SQL 语句中,最好使用准备好的语句和参数化查询,这样更安全。- 不要将敏感数据保留在纯文本中
加密存储在数据库中的私有/机密数据,这样可以提供了另一级保护,以防攻击者成功地排出敏感数据。- 限制数据库权限和特权
将数据库用户的功能设置为最低要求;这将限制攻击者在设法获取访问权限时可以执行的操作。- 避免直接向用户显示数据库错误
攻击者可以使用这些错误消息来获取有关数据库的信息。
7. MyBatis中#占位符和$占位符有什么区别?
关于#{}和${}的区别
- #{}是预编译处理,$ {}是字符串替换。
- MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;MyBatis在处理$ { } 时,就是把 ${ } 替换成变量的值。
- 使用 #{} 可以有效的防止SQL注入,提高系统安全性。 预编译的机制。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。
业务场景:
select * from user where id= "1";
上述 sql 中,我们希望对应的id可以变化,根据不同的id查询出不同的学生,在 Mapper.xml文件中使用如下的 sql 可以实现动态传递参数 id:
关于#的使用
select * from user where id= #{id};
当传来参数id=2的时候,解析为:select * from user where id= ?;
关于$的使用
select * from user where id= ${id};
当传来参数id=2的时候,解析为:select * from user where id = "2";
小结: ${ } 变量的替换阶段是在动态 SQL 解析阶段,而 #{ }变量的替换是在 DBMS 中。
篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记【点击此处即可】免费获取
8.springboot和springcloud区别。 boot里的starter是什么,@Configuration作用
springboot和springcloud的区别主要是:
- 作用不同:前者的作用是为了提供一个默认配置,从而简化配置过程;后者的作用是为了给微服务提供一个综合管理框架。
- 使用方式不同:springboot可以单独使用;springcloud必须在springboot使用的前提下才能使用。SpringBoot专注于快速方便的开发单个个体微服务,SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并且管理起来,为各个服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、精选决策、分布式会话等集成服务。
springboot和springcloud都是从spring生态圈中衍生出来的软件开发框架,但是二者的创作初衷是完全不同的,springboot的设计目的是为了在微服务开发过程中可以简化配置文件,提高工作效率,而springcloud的设计目的是为了管理同一项目中的各项微服务,因此二者是完全不同的两个软件开发框架。
9.常用设计模式,解决什么问题:工厂、策略、责任链
一、工厂模式最主要解决的问题就是创建者和调用者的耦合,那么代码层面其实就是取消对new的使用。
工厂模式可以分为:简单工厂模式、工厂方法模式和抽象工厂模式。
简单工厂模式又叫 静态方法模式,因为工厂类中定义了一个静态方法用于创建对象。简单工厂让使用者不用知道具体的参数就可以创建出所需的 ”产品“类,即使用者可以直接消费产品而不需要知道产品的具体生产细节。
工厂类负责创建的对象比较少:由于创建的对象比较少,不会造成工厂方法中业务逻辑过于复杂。
客户端只需知道传入工厂类静态方法的参数,而不需要关心创建对象的细节。工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫多态工厂(Polymorphic Factory)模式,它属于类创建型模式。
在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象, 这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。
但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。二、策略模式可以解决在有多种算法相似的情况下,使用if…else 或swith…case所带来的复杂性和臃肿性。
在日常业务开发中,策略模式适用于以下场景:
- 针对同一类型问题,有多种处理方式,每一种都能独立解决问题;
- 算法需要自由切换的场景;
- 需要屏蔽算法规则的场景。 策略模式中的上下文环境 (Context) ,其职责本来是隔离客户端与策略类的耦合,让客户端完全与上下文环境沟通,无需关系具体策略。
策略模式的优缺点
优点 :
- 策略模式符合开闭原则。
- 避免使用多重条件转移语句,如 if…else… 语句、 switch 语句
- 使用策略模式可以提高算法的保密性和安全性。
缺点 :
- 客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
- 代码中会产生非常多策略类,增加维护难度。
三、责任链模式 (Chain of Responsibility Pattern) 是将链中每一个节点看作是一个对象,每个节点处理的清求均不同,且内部自动维护—个下—节点对象。当—个清求从链式的首端发出时,会沿看链的路径依次传递给每—个节点对象,直至有对象处理这个清求为止。
责任链模式的本质是解耦请求与处理,让请求在处理链中能进行传递与被处理;理解责任链模式应当理解的是其模式(道)而不是其具体实现(术),责任链模式的独到之处是其将节点处理者组合成了链式结构,并允许节点自身决定是否进行请求处理或转发,相当于让请求流动了起来。责任链模式的优缺点 优点:
- 将请求与处理解耦;
- 请求处理者(节点对象)只需关注自己感兴趣的请求进行处理即可,对于不感兴趣的请求,直接转 发给下一级节点对象;
- 具备链式传递处理请求功能,请求发送者无需知晓链路结构,只需等待请求处理结果;
- 链路结构灵活,可以通过改变链路结构动态地新增或删减责任;
- 易于扩展新的请求处理类(节点),符合开闭原则。
缺点:
- 责任链太长或者处理时间过长,会影响整体性能
- 如果节点对象存在循环引用时,会造成死循环,导致系统崩溃;
10. 常用的注解有哪些,有什么作用
一.用于创建对象的注解
作用:和在xml配置文件中编写一个标签实现的功能一样。
- @Component : 用于把当前类对象存入Spring容器中。 属性:value — 用于指定bean的id。如果不写该属性,id的默认值是当前类名,且首字母改为小写。
- @Controller : 一般用在表现层。
- @Service : 一般用在业务层。
二.用于注入数据的注解
作用:和在xml配置文件中的标签中写一个标签的功能一样。
- @Autowired : 自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。可以作用在变量或者方法上。
- @Qualifier : 在按照类型注入的基础之上再按照名称注入,它在给类成员注入时要和@Autowired配合使用,但是在给方法参数注入是可以单独使用。
- @Resource : 直接按照bean的id注入,可以独立使用。 属性:name — 用于指定bean的id。 备注:以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。另外,集合类型的注入只能通过xml来实现。
- @Value : 用于注入基本类型和String类型的数据。 属性:value — 用于指定数据的值,它可以使用Spring中的SpEL(也就是Spring中的el表达式)。SpEL的写法:${表达式}
三.用于改变作用范围的注解
作用:和在xml配置文件中的标签中使用scope属性实现的功能一样。
- @Scope : 用于指定bean的作用范围。 属性:value — 指定范围的取值。常用取值:singleton(单例)和prototype(多例)。
四.和生命周期相关的注解
作用:和在xml配置文件中的标签中使用init-method和destory-method属性实现的功能一样。
- @PreDestory : 用于指定销毁方法。
- @PostConstruct : 用于指定初始化方法。
五.Spring新注解
- @Configuration : 用于指定当前类是一个配置类。
- @ComponentScan : 用于通过注解指定Spring在创建容器时要扫描的包。
- @Bean : 用于把当前方法的返回值作为bean对象存入Spring的IOC容器中。 属性:name — 用于指定bean的id。当不写时,默认值为当前方法的名称。
- @Import : 用于导入其他的配置类。 属性:value — 用于指定其他配置类的字节码。当我们使用@Import注解时,有@Import注解的类就是父配置类。
- @PropertySource : 用于指定properties文件的位置。 属性:value — 指定文件的名称和路径。关键字classpath表示类路径下。
- @Entity:@Table(name=”“):表明这是一个实体类。一般用于jpa这两个注解一般一块使用,但是如果表名和实体类名相同的话,@Table可以省略
11. JVM调优的目标是什么
JVM调优的主要目的:减少full gc、降低gc停顿时间、提高吞吐量;调优的顺序=“提高吞吐量”>“降低gc停顿时间”;在满足吞吐量的前提下,再降低gc停顿时间;若不能同时满足以上,则选择最适合系统的一种调优结果
一般JVM调优,重点在于调整JVM堆大小、调整垃圾回收器.
JVM常用命令:
- jstat命令用于监视虚拟机的运行状态。命令格式【jstat -参数命令 进程号 间隔毫秒数 总输出次数】
- jinfo可以查看启动jar包时未显式指定的系统默认值,以及动态修改这些默认值。命令格式【jinfo -flag 默认的参数 进程id】
- jmap查看java内存信息。命令格式【jmap -参数 进程id】
- jstack可以查看正在运行的线程的堆栈信息,比如查看后天没有相应的线程在做些什么,在等待什么资源。命令格式【jstack 参数项 进程号】
常见的调优策略
- 减少创建对象的数量。
- 减少使用全局变量和大对象。
- 调整新生代、老年代的大小到最合适。
- 选择合适的GC收集器,并设置合理的参数。
微服务体系栈
1. SpringCloud是什么/Cloud Alibaba是什么,有哪些组成与功能
注册中心/RPC/限流熔断、网关/接口治理、配置、事件总线;监控配套:调用链、性能监控;
spring cloud五大组件分别为:服务发现–Netflix Eureka 主要提供服务的自动注册和发现
客户端负载均衡–Netflix Ribbon
断路器–Netflix Hystrix
服务网关–Netflix Zuul
分布式配置–Spring Cloud Config此外Ribbon是和Feign以及Eureka紧密协作的,具体如下:
首先Ribbon会从Eureka Client里获取到对应的服务注册表,知道所有的服务都部署在了哪些机器上,在监听哪些端口号。
然后Ribbon就使用默认的Round Robin轮询算法,从中选择一台机器;
最后Feign就会针对这台机器,构造并发起请求。
微服务的框架一般都会分为以下一个大部分:
微服务网关-负责请求转发,路由,权限控制
注册、配置中心–服务发现和注册
客户端负载器—负责微服务内部的负载
限流控制–负责微服务调用的限流和流量控制
篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记【点击此处即可】免费获取
2. 了解或者使用过哪些主流厂商微服务框架
蚂蚁SOFA、阿里EDAS、腾讯TSF、京东JSF
3. 对于微服务的降级,限流,熔断怎么理解,项目中怎么使用的,都解决什么问题
熔断和降级的区别?
相同点
都是为了保证服务的可用性,防止系统发生崩溃
都导致了系统的某些服务、功能不可用
不同点
熔断是由某个下游服务故障引起的,降级一般从系统的整体负荷去考虑
在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。
服务熔断解决如下问题:
- 当所依赖的对象不稳定时,能够起到快速失败的目的;
- 快速失败后,能够根据一定的算法动态试探所依赖对象是否恢复。
自动降级分类
1)超时降级:主要配置好超时时间和超时重试次数和机制,并使用异步机制探测回复情况
2)失败次数降级:主要是一些不稳定的api,当失败调用次数达到一定阀值自动降级,同样要使用异步机制探测回复情况
3)故障降级:比如要调用的远程服务挂掉了(网络故障、DNS故障、http服务返回错误的状态码、rpc服务抛出异常),则可以直接降级。降级后的处理方案有:默认值(比如库存服务挂了,返回默认现货)、兜底数据(比如广告挂了,返回提前准备好的一些静态页面)、缓存(之前暂存的一些缓存数据)
4)限流降级:秒杀或者抢购一些限购商品时,此时可能会因为访问量太大而导致系统崩溃,此时会使用限流来进行限制访问量,当达到限流阀值,后续请求会被降级;降级后的处理方案可以是:排队页面(将用户导流到排队页面等一会重试)、无货(直接告知用户没货了)、错误页(如活动太火爆了,稍后重试)
4. 对于RPC技术原理的理解,RPC整体调用过程
RPC 框架----- 远程过程调用协议RPC(Remote Procedure Call Protocol)-----允许像调用本地服务一样调用远程服务。
总的来说可以归纳为以下几步:
1,远程服务之间建立通讯协议
2,寻址:服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么
3,通过序列化和反序列化进行数据传递
4,将传递过来的数据通过java反射原理定位接口方法和参数
5. 微服务之前的循环依赖问题怎么产生的?有什么解决方案。
循环依赖的坏处
1、服务功能不内聚,耦合严重,导致研发效率低下
假设A依赖B,B又依赖A,会导致每次A和B部署的时候必须耦合,部署了A就得部署B,不然就会报错;
上面这些还不算严重的,比较麻烦的是A升级或者改了些接口,B要测试下;反过来B改了接口A也要测试下,浪费研发和测试资源;
2、增加了系统的复杂性,很容易出错
一些线上操作升级可能也会比较麻烦,像我们在升级JDK8的时候就必须梳理各种依赖关系,梳理不当就可能会有线上故障;
3、系统的扩展性受到限制
这里的扩展性分系统和业务2方面,系统上来说假如大促我要升级扩容,如果正常不依赖其它应用,或者只依赖少量应用,只升级自己就可以了,如果依赖了其它应用,还得考虑其它应用的容量;还涉及到部署的情况,当你的业务做的很大,以前只是垂直应用,现在升级成平台型应用的时候,对部署有了更高的要求,可能要单独的隔离环境进行部署,如果依赖了不依赖的应用,会使这些几乎不可能。
业务扩展性也是一样的,如果业务发展比较快,要支持更多的场景,那就必须考虑新的业务和这些依赖的应用是否兼容,增加研发成本,也不利于扩展。
如何避免循环依赖
按上面的情况,如果应用A依赖B,B依赖A,要做到不循环依赖,有以下办法:
1、改为异步调用
微服务解耦,做到服务自治,可以发送MQ消息,这样发送方就不用关心消费方的存在了。
2、微服务分层建设
对微服务进行分层规划,上层微服务可以调用下层微服务,下层微服务禁止调用上层微服务,把公用的部分沉淀下放到基础微服务层。
标签:服务,八股文,面试,线程,SQL,2024java,方法,id,注入 From: https://blog.csdn.net/2401_87704405/article/details/143181985篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记【点击此处即可】免费获取