Java常见面试题(2)

1.表单提交重复?怎么设置接口的幂等性?

场景:当用户在下单的时候,他已经支付过了,再返回支付结果的时候,出现网络抖动的问题,出现了一些异常,那这个时候用户已经消费过了,如果用户在点击这个按钮,就会二次消费,这就是因为没有实现幂等性。
解决
1.通过订单的id来标定该订单的唯一,然后付款的时候,判断该id是否存在,如果存在就表示支付过了,第二次支付的时候我们就让它返回付款成功的结果
2.使用token机制来实现幂等性,然后创建出唯一的的token,再将它存进redis中,然后在页面跳转的时候获取到这个token,然后将该token放在前端,然后下次请求的时候先提交token,后台在去效验下该token,然后在执行这个提交的逻辑提交成功,并删除该token,并生成一个新的token在redis里边进行更新,当第一次提交后,token更新了,页面再次提交携带这个token时是原来的token话,就验证嘛,如果验证失败就不让我提交

2.使用Object的wait和notify需要加同步锁吗?

  • 需要,首先为什么要上锁,只有两个线程抢一个资源的时候,才存在两个线程同一时刻只能有一个线程得到资源锁就是为了使两个线程抢同一个资源,如果没有锁,就意味着两个线程不存在抢资源的情况,那两个线程凭什么 你等我 /我等你,早就一起跑了。

3.多线程同步有哪些方法?

  • 使用 synchronized 关键字 (常用)
  • wait 和 notify
  • 使用特殊域变量 volatile 实现线程同步
  • 使用重入锁实现线程同步
  • 使用局部变量来实现线程同步
  • 使用阻塞队列实现线程同步
  • 使用原子变量实现线程同步

4.创建线程的三个方法是什么?

  • 通过继承 Thread 类创建线程类。
  • 实现 Runnable 接口创建线程类。
  • 通过 Callable 和 Future 接口创建线程。

5.Redis内存释放策略和过期键删除的策略?

在redis中,内存的大小都是有限的,所以为了防止内存出现饱和,需要实现某种建的淘汰策略,分为以下两种

  • (1)redis内存不足时采用内存释放策略
    redis中有专门释放内存的函数:freeMmoryIfNeeded(翻译:自由内存如果需要),每当执行一个命令的时候,就会调用该函数去判断内存是否够用,如果已用内存大于最大内存的限制,就会进行内存的释放
    当需要进行内存释放的时候,他就会去采取某种策略对保存的对象进行删除,而redis有8种内存释放策略
    1从已设置的过期时间中,挑选最少使用的数据淘汰
    2从已设置的过期时间中,任意挑选数据淘汰
    3从已设置的过期时间中,挑选即将过期的数据进行淘汰
    4从已设置的过期时间中,调选最少使用次数的数据进行淘汰
    5从数据中挑选最少使用的数据太淘汰
    6从数据中挑选最少使用次数的数据进行淘汰
    7从数据中任意挑选数据淘汰
    8禁止驱逐数据(默认)

    总结就一句:
    设置的过期时间中,任意淘汰/最少使用淘汰/最少使用次数淘汰/即将过期的淘汰;未设置过期时间的,任意淘汰/最少使用淘汰/最少使用次数淘汰,最后一种默认不删

  • (2)对过期键进行删除的策略
    1.惰性删除
    所有读写数据库命令在执行之前都会调用该函数expireIfNeeded(翻译:过期如果需要)如果key过期了就删除
    2.主动删除
    清理时,会依次调用所有的db(键值对),将过期的删掉,简单的说就是设置了过期时间,到点了就删除

6.说下你对微服务的理解?

  • 基于服务来说,所有的微服务都属于分布式,每个服务都有一个对应独立的服务器和数据库,这样开发起来效率高可扩展性也强

7.说一下消息中间件的事务执行流程

  • 1》生产者发送half(半消息)到mq判断mq是否还存活,如果mq是有问题的,半消息是根本发不出去的,此时半消息肯定就是失败的,如果半消息返回成功的响应的话说明mq是活着的;
  • 2》如果发送成功,半消息成功的响应回给订单系统,就更新订单数据,否则就进行事务回滚
  • 3》如果提交订单信息失败,mq也会有补偿机制,回调接口人判断是否重新发送commit请求

8.Feign远程调用的原理

  • feign是一个http请求调用的轻量级,可以使用java接口注解@FeignClient的方式调用http请求。基于面向接口的动态代理方式生成实现类,然后讲这些本地动态代理实例化,注入Spring IOC容器中。当远程接口方法被调用,用动态代理实例去完成真正的远程访问,并且返回结果。

9.说一下你使用过哪些的Spring cloud 组件?

  • 因为是微服务嘛,所以会划分多个服务,有可能会随时增加,在这些服务中我们要统一的去进行管理,所以我们这里就会用到nacos,在找的时候我们可以根据它去调用;这是第一个主键,而在这些服务当中因为每个服务都是相对独立的,如果我想调用别的服务的方法的时候,我们可以通过远程调用的方式,就是使用feign跟ribbon负载均衡,这是第二个跟第三个主键;然后在服务区可能出现问题的时候,就需要用到一个降级熔断,这里我们使用的是sentinel,这是第四个组件;多个服务有多个配置,配置多了我们要对他们进行管理,对配置文件进行统一管理我们这边也使用的是nacos;第五个组建呢就是网关,因为我们多个服务的地址是不一样的,而这些服务最终都是要暴露给前端的调用的,而前端呢如果是一个服务一个地址的话,调用起来是非常麻烦的,所以我们使用统一的一个地址,这是第一个作用,第二个作用我们可以对访问微服务做一个鉴权的处理

10.说说请求转发(forward)和重定向(redirect)?

  • 转发是服务器行为,重定向是客户端行为。

  • 从地址栏显示来说
    forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
    redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

  • 从数据共享来说
    forward:转发页面和转发到的页面可以共享request里面的数据.
    redirect:不能共享数据.

  • 从运用地方来说
    forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
    redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等

  • 从效率来说
    forward:高.
    redirect:低.

11.开发中,集合如何进行选取?

  • 主要根据集合的特点来进行选择,例如我们需要根据键值对获取元素的时候,我们实现map接口下的集合需要排序的时候使用treemap不需要排序的时候使用hashmap;需要保证线程安全的时候使用concurrentHashMap当只需要存放值的时候,我们实现collection接口的集合,当要保证元素的一致性(唯一性)的时候,选择实现set接口的集合,比如使用treeset和hashset,不需要唯一的时候,选择实现list的接口集合,比如arraylist和linkedlist,然后根据这些集合的特点来使用

12.MySql的索引引用有哪些?

  • 普通索引:是最基本的索引,他没有任何的限制
  • 唯一索引:与普通索引不一样的是,索引列的值必须是唯一的,但允许有空值,
  • 组合索引:指多个字段上创建的索引,只有查询条件中使用了创建索引时的第一个字段,索引才会被使用
  • 全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值相比较
  • 主键索引:是一种特殊的唯一索引,一个表中只能有一个主键,不允许出现空值

13.Redis的数据结构?以及与memcached的区别?

  • redis的数据结构有
    String-字符串,hash-字典,list-列表,set-集合,zset-有序集合
  • 使用场景:
    如果有需要持久方面的需求或对数据类型和处理有要求优先选择redis
    如果简单的kv对存储就选择使用memcached

14.列举工作中常用的几个git命令?

  • 新增文件的命令:git add file或者git add .
  • 提交文件的命令:git commit –m或者git commit –a
  • 查看工作区状况:git status –s
  • 拉取合并远程分支的操作:git fetch/git merge或者git pull
  • 查看提交记录命令:git reflog

15.提交时发生冲突,你能解释冲突是如何产生的吗?你是如何解决的?

  • 产生:开发过程中,我们都有自己的特性分支,所以冲突发生的并不多,但也碰到过。诸如公共类的公共方法,我和别人同时修改同一个文件,他提交后我再提交就会报冲突的错误。

  • 解决:发生冲突,在IDE里面一般都是对比本地文件和远程分支的文件,然后把远程分支上文件的内容手工修改到本地文件,然后再提交冲突的文件使其保证与远程分支的文件一致,这样才会消除冲突,然后再提交自己修改的部分。特别要注意下,修改本地冲突文件使其与远程仓库的文件保持一致后,需要提交后才能消除冲突,否则无法继续提交。必要时可与同事交流,消除冲突。

  • 发生冲突,也可以使用命令。

  • 通过git stash命令,把工作区的修改提交到栈区,目的是保存工作区的修改;

  • 通过git pull命令,拉取远程分支上的代码并合并到本地分支,目的是消除冲突;

  • 通过git stash pop命令,把保存在栈区的修改部分合并到最新的工作空间中;

16.Redis的Bigkey怎么产生?

这个问题就可以作为面试的时候,你在使用Redis中出现的问题

一般来说,bigkey的产生都是由于程序设计不当,或者对于数据规模预料不清楚造成的,来看几个🌰:

(1) 社交类:粉丝列表,如果某些明星或者大v不精心设计下,必是bigkey。

(2) 统计类:例如按天存储某项功能或者网站的用户集合,除非没几个人用,否则必是bigkey。

(3) 缓存类:将数据从数据库load出来序列化放到Redis里,这个方式非常常用,但有两个地方需要注意,第一,是不是有必要把所有字段都缓存,第二,有没有相关关联的数据。

例如我之前遇到过一个例子,该同学将某明星一个专辑下所有视频信息都缓存一个巨大的json中,造成这个json达到6MB,后来这个明星发了一个官宣。。。这个我就不多说了,领盒饭去吧。

17.常见垃圾收集算法有哪些?

  1. 标记-清除算法
  2. 复制算法
  3. 标记-整理算法
  4. 分代收集算法

18.get和post请求的区别

  • GET 请求只能 URL 编码,而 POST 支持多种编码方式
  • GET 请求只接受 ASCII 字符的参数,而 POST 则没有限制
  • GET 请求的参数通过 URL 传送,而 POST 放在 Request Body 中
  • GET 相对于 POST 更不安全,因为参数直接暴露在 URL 中
  • GET 请求会被浏览器主动缓存,而 POST 不会(除非自己手动设置)
  • GET 请求在 URL 传参有长度限制,而 POST 则没有限制
  • GET 产生的 URL 地址可以被收藏,而 POST 不可以
  • GET 请求的参数会被完整的保留在浏览器的历史记录里,而 POST 的参数则不会
  • GET 在浏览器回退时是无害的,而 POST 会再次提交请求

19.Cookie和Session的的区别

  • 1,session 在服务器端,cookie 在客户端(浏览器)
  • 2,session 默认被存在在服务器的一个文件里(不是内存)
  • 3,session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
  • 4,session 可以放在文件、数据库、或内存中都可以。
  • 5,用户验证这种场合一般会用 session

20.JDBC访问数据库的基本步骤是什么?

  • 1,加载驱动
  • 2,通过DriverManager对象获取连接对象Connection
  • 3,通过连接对象获取会话
  • 4,通过会话进行数据的增删改查,封装对象
  • 5,关闭资源

21.什么是事务?

  • 就是被绑定在一起作为一个逻辑工作单元的 SQL 语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务

22.在MyBatis中,#{}和${}的区别是什么?

  • #{}是预编译处理,${}是字符串替换。
  • Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
  • Mybatis在处理${}时,就是把${}替换成变量的值。
  • 使用#{}可以有效的防止SQL注入,提高系统安全性。

23.Spring 管理事务的方式有几种?

  1. 编程式事务,在代码中硬编码。(不推荐使用)
  2. 声明式事务,在配置文件中配置(推荐使用)

声明式事务又分为两种:

  1. 基于XML的声明式事务
  2. 基于注解的声明式事务

24.Spring中的常用注解

(1)声明bean的注解

  • @Component 组件,没有明确的角色
  • @Service 在业务逻辑层使用(service层)
  • @Repository 在数据访问层使用(dao层)
  • @Controller 在展现层使用,控制器的声明(C)

(2)注入bean的注解

  • @Autowired:由Spring提供
  • @Inject:由JSR-330提供
  • @Resource:由JSR-250提供

(3)java配置类相关注解

  • @Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)
  • @Bean 注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式(方法上)
  • @Configuration 声明当前类为配置类,其中内部组合了@Component注解,表明这个类是一个bean(类上)
  • @ComponentScan 用于对Component进行扫描,相当于xml中的(类上)

(4)切面(AOP)相关注解

Spring支持AspectJ的注解式切面编程。

  • @Aspect 声明一个切面(类上)

使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。

  • @After 在方法执行之后执行(方法上)
  • @Before 在方法执行之前执行(方法上)
  • @Around 在方法执行之前与之后执行(方法上)
  • @PointCut 声明切点

(5)@Bean的属性支持

  • @Scope 设置Spring容器如何新建Bean实例(方法上,得有@Bean) 其设置类型包括:

Singleton (单例,一个Spring容器中只有一个bean实例,默认模式),
Protetype (每次调用新建一个bean),
Request (web项目中,给每个http request新建一个bean),
Session (web项目中,给每个http session新建一个bean),
GlobalSession(给每一个 global http session新建一个Bean实例)

  • @StepScope 在Spring Batch中还有涉及
  • @PostConstruct 由JSR-250提供,在构造函数执行完之后执行,等价于xml配置文件中bean的initMethod
  • @PreDestory 由JSR-250提供,在Bean销毁之前执行,等价于xml配置文件中bean的destroyMethod

(6)@Value注解

  • @Value 为属性注入值

(7)环境切换

  • @Profile 通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。(类或方法上)
  • @Conditional
    Spring4中可以使用此注解定义条件话的bean,通过实现Condition接口,并重写matches方法,从而决定该bean是否被实例化。(方法上)

(8)异步相关

  • @EnableAsync 配置类中,通过此注解开启对异步任务的支持,叙事性AsyncConfigurer接口(类上)
  • @Async
    在实际执行的bean方法使用该注解来申明其是一个异步任务(方法上或类上所有的方法都将异步,需要@EnableAsync开启异步任务)

(9)定时任务相关

  • @EnableScheduling 在配置类上使用,开启计划任务的支持(类上)
  • @Scheduled 来申明这是一个任务,包括cron,fixDelay,fixRate等类型(方法上,需先开启计划任务的支持)

(10)@Enable*注解说明

这些注解主要用来开启对xxx的支持。

  • @EnableAspectJAutoProxy 开启对AspectJ自动代理的支持
  • @EnableAsync 开启异步方法的支持
  • @EnableScheduling 开启计划任务的支持
  • @EnableWebMvc 开启Web MVC的配置支持
  • @EnableConfigurationProperties 开启对@ConfigurationProperties注解配置Bean的支持
  • @EnableJpaRepositories 开启对SpringData JPA Repository的支持
  • @EnableTransactionManagement 开启注解式事务的支持
  • @EnableTransactionManagement 开启注解式事务的支持
  • @EnableCaching 开启注解式的缓存支持

(11)测试相关注解

  • @RunWith 运行器,Spring中通常用于对JUnit的支持

25.SpingMVC需要接受前台JSON字符串并注入到对象中需要使用什么注解

  • @RequestBody:将前端传来的json格式的数据转为自己定义好的javabean对象
  • 需要注意的是:前台传来的数据属性名称一定要与后端的javabean对象中的某个字段一致

26.Spring框架中用到了哪些设计模式

  • 1.工厂设计模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。
  • 2.代理设计模式:Spring AOP功能的实现。
  • 3.单例设计模式:Spring中的bean默认都是单例的。
  • 4.模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。
  • 5.包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
  • 6.观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。
  • 7.适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。

27.说说常见的HTTP相应状态码?

  • 200:请求被正常处理
  • 204:请求被受理但没有资源可以返回
  • 206:客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。
  • 301:永久性重定向
  • 302:临时重定向
  • 303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上
  • 304:发送附带条件的请求时,条件不满足时返回,与重定向无关
  • 307:临时重定向,与302类似,只是强制要求使用POST方法
  • 400:请求报文语法有误,服务器无法识别
  • 401:请求需要认证
  • 403:请求的对应资源禁止被访问
  • 404:服务器无法找到对应资源
  • 500:服务器内部错误
  • 503:服务器正忙

28.线程池参数有哪些?

  • corePoolSize 核心线程大小。
  • maximumPoolSize 线程池最大线程数量。
  • keepAliveTime 空闲线程存活时间。
  • unit 空间线程存活时间单位。
  • workQueue 工作队列。
  • threadFactory 线程工厂。
  • handler 拒绝策略。

29.Volatile关键字的作用?

  • 多线程下变量可见性
    可见性是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果,另一个线程马上就能看到。
  • 禁止重排序
    避免多线程的情况下乱序执行
  • volatile关键字修饰的变量看到的随时是自己的最新值
  • 不保证原子性

30.yml与properties的区别?

  • 在properties文件中是以”.”进行分割的, 在yml中是用”:”进行分割;
  • 在yml中缩进一定不能使用TAB,否则会报很奇怪的错误;(缩进只能用空格)
  • yml配置有序,在一些特殊的场景下,配置有序很关键
  • yml支持数组,数组中的元素可以是基本数据类型也可以是对象
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值