Java面试Day16

1.Dubbo 是什么?是否了解过它的架构设计?

Dubbo官网:Apache Dubbo

Dubbo是一个高性能、轻量级的开源Java RPC框架,它提供了完整的RPC协议栈,包括服务发布、服务引用、负载均衡、容错、服务治理和服务监控等功能,同时提供了可扩展的RPC协议、数据模型、序列化和网络传输等组件,支持多语言和多协议。

Dubbo的架构设计主要包括服务提供者、服务消费者、注册中心和监控中心四个角色。其中,服务提供者提供服务的实现,并通过注册中心将自己注册到服务治理中心;服务消费者则通过注册中心发现可用的服务,并通过负载均衡策略选择一个服务提供者进行调用;注册中心主要负责服务的注册、发现和路由;监控中心则负责服务的统计和监控。

Dubbo的架构设计采用了分层架构模式,将不同的功能模块进行分离,以达到模块化和可扩展的目的。同时,Dubbo还提供了丰富的扩展点和插件机制,用户可以通过自定义扩展点和插件来满足不同的业务需求。

2.synchronized 关键字是什么,有什么作用?

说一说自己对于 synchronized 关键字的了解

  • synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行

  • 在 Java 早期版本中, synchronized属于重量级锁,效率低下,因为锁监视器(monitor)是依赖于底层的操作系统来实现的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,这也是为什么早期的synchronized 效率低的原因.

  • Java 官方对从 JVM 层面对synchronized 较大优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。 所以现在的 synchronized 锁效率也优化得很不错了。

说说自己是怎么使用 synchronized 关键字

  • 修饰非静态方法, 锁的是this(当前对象), 也就是一个对象用一把锁

  • 修饰静态方法, 锁的是 类.class , 也就是类的所有对象公用一把锁

  • 修饰代码块.

  • 尽量不要使用 synchronized(String a) 因为JVM中,字 符串常量池具有缓存功能

synchronized原理

synchronized 同步语句块的实现使用的是 monitorentermonitorexit 指令,其中 monitorenter 指令指向同步代码块的开始位置, monitorexit 指令则指明同步代码块的结束位置

  • 当多个线程同时访问该方法,那么这些线程会先被放进对象的锁池,此时线程处于blocking状态

  • 当一个线程获取到了实例对象的监视器(monitor)锁,那么就可以进入running状态,执行方法,此时 lock record 中的 owner 设置为当前线程,count加1表示当前对象锁被一个线程获取

  • 当running状态的线程调用wait()方法,那么当前线程释放monitor对象,进入waiting状态, lock record 中的 owner 变为null,count减1,同时线程进入等待池,直到有线程调用notify()方法唤醒该线程,则该线程重新获取monitor对象进入owner

  • 如果当前线程执行完毕,那么也释放monitor对象,进入waiting状态,lock record 中的 owner 变为null,count减1

JDK1.6 之后的 synchronized 底层做了哪些优化?

java的线程模型是1对1的, 加锁需要调用操作系统的底层原语mutex, 所以每次切换线程都需要操作系统切换到内核态, 开销很大. 这也是之前synchronized的问题所在, jdk1.6对其进行了优化, 从无锁到偏向锁到轻量级锁到重量级锁 自旋锁就不需要阻塞, 也就不需要操作系统切换为内核态去做, 所以短时间的自旋开销是比较低的.

JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态:无锁状态(unlocked)、偏向锁状态(biasble)、轻量级锁状态(lightweight locked)和重量级锁状态(inflated)。 虚拟机对象头里锁标志位, 就记录了这4中状态.

偏向锁

大多数时候是不存在锁竞争的,常常是一个线程多次获得同一个锁,因此如果每次都要竞争锁会增大很多没有必要付出的代价,为了降低获取锁的代价,才引入的偏向锁。

  • 当锁对象第一次被线程获得的时候,使用 CAS 操作将线程 ID 记录到对象头的MarkWord中,这个线程以后每次进入这个锁相关的同步块就不需要再进行任何同步操作。

  • 当有另外一个线程去尝试获取这个锁对象时,偏向状态就宣告结束,此时撤销偏向后恢复到未锁定状态或者轻量级锁状态。

轻量级锁

轻量级锁考虑的是竞争锁对象的线程不多,而且线程持有锁的时间也不长的情景。因为阻塞线程需要CPU从用户态转到内核态,代价较大,如果刚刚阻塞不久这个锁就被释放了,那这个代价就有点得不偿失了,因此这个时候就干脆不阻塞这个线程,让它自旋这等待锁释放。

轻量级锁是相对于传统的重量级锁而言,它使用自旋 + CAS 操作来避免重量级锁使用互斥量的开销。

长时间的自旋会使CPU一直空转, 浪费CPU, 所以这里自旋是适应性自旋, 自旋时间由上一个线程自旋的时间决定的.

  • 线程自旋的次数到了阈值, 另外一个线程还没释放锁, 那么就膨胀为重量级锁。

  • 如果有两条以上的线程争用同一个锁,那轻量级锁就不再有效,要膨胀为重量级锁。

锁消除

锁消除是指对于被检测出不可能存在竞争的共享数据的锁进行消除。

锁消除主要是通过逃逸分析来支持,如果堆上的共享数据不可能逃逸出去被其它线程访问到,那么就可以把它们当成私有数据对待,也就可以将它们的锁进行消除。

锁粗化

如果一系列的连续操作都对同一个对象反复加锁和解锁,频繁的加锁操作就会导致性能损耗。

比如连续使用StringBuffer的append() 方法就属于这类情况。如果虚拟机探测到由这样的一串零碎的操作都对同一个对象加锁,将会把加锁的范围扩展(粗化)到整个操作序列的外部, 这样只需要加锁一次就可以了。

3.如何设计一个点赞系统?

设计一个点赞系统可以分为以下几个步骤:

  1. 确定需求:需要明确点赞的对象是什么,是否需要计数等信息,同时需要考虑点赞的业务场景,如用户点赞、文章点赞等。

  2. 数据库设计:需要设计点赞相关的数据表,可以包含点赞者 ID、被点赞对象 ID、点赞时间等字段。

  3. 接口设计:需要设计点赞相关的接口,包括点赞、取消点赞、查询点赞数等操作。

  4. 业务逻辑实现:在接口中实现点赞相关的业务逻辑,包括判断点赞状态、更新点赞数、更新点赞状态等操作。

  5. 安全性考虑:需要考虑并发访问的情况,可以使用分布式锁来保证数据一致性和安全性。

  6. 性能优化:如果点赞系统的访问量很高,可以使用缓存来提高性能,比如使用 Redis 来缓存点赞数等信息。

  7. 监控和日志:需要对点赞系统进行监控和日志记录,以便及时发现和排查问题。

总之,设计一个点赞系统需要综合考虑需求、数据库设计、接口设计、业务逻辑实现、安全性、性能优化等方面,同时需要不断优化和完善。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/7431.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 学习记录45(C++篇)

Linux 学习记录45(C篇) 本文目录 Linux 学习记录45(C篇)一、纯虚函数和抽象类1. 纯虚函数2. 抽象类 二、C中的异常处理1. 抛出异常2. 处理/捕获异常 三、模板(template)1. 模板函数(1. 模板函数的定义和调用(2. 模板函数需要显性调用的时机 2. 模板类3. 模板函数和模板类实现的…

只出现一次的数字

题目链接 只出现一次的数字 题目描述 注意点 1 < nums.length < 30000-30000 < nums[i] < 30000除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次 解答思路 最初想到使用一种数据结构将元素存储起来&#xff0c;但是空间复杂度为O(n)&#xff0…

kafka的broker和replica和文件存储

zookeeper中存储的kafka信息 /brokers/ids&#xff0c;记录存在的服务器id/brokers/topics/test/partitions/0/state&#xff0c;记录leader和可用副本服务器/comsumers&#xff0c;0.9版本之前存储消费者的offset信息&#xff0c;但是会产生zookeeper和broker的跨节点通信/co…

MyBatis—操作数据库

MyBatis &#x1f50e;前置铺垫创建数据库MyBatis 的执行流程创建对应流程 &#x1f50e;MyBatis—查询查询用户信息执行流程创建实体类创建 Interface 与 xml在 xml 中编写 SQL 语句模拟执行流程 &#x1f50e;单元测试定义优点执行单元测试引入依赖生成单元测试编写代码Asser…

计讯物联5G数采仪助力打造化工园区企业工况监测系统

项目背景 随着我国化工行业的快速发展&#xff0c;化工园区已成为化工行业发展的重要阵地&#xff0c;化工企业聚集&#xff0c;危险化学品安全风险集中&#xff0c;安全规范问题逐渐成为行业关注的焦点。然而&#xff0c;我国化工园区发展水平发展参差不齐&#xff0c;尤其是…

吴恩达ChatGPT《Building Systems with the ChatGPT API》笔记

1. 课程介绍 使用ChatGPT搭建端到端的LLM系统 本课程将演示使用ChatGPT API搭建一个端到端的客户服务辅助系统&#xff0c;其将多个调用链接到语言模型&#xff0c;根据前一个调用的输出来决定使用不同的指令&#xff0c;有时也可以从外部来源查找信息。 课程链接&#xff1a…

SpringBoot整合RabbitMQ实现消息延迟队列(含源码)

环境依赖 SpringBoot 3.1.0 JDK 17 前期准备 安装MQ: liunxdockerrabbitmq安装延迟队列插件 实例 实现延迟队列的一种方式是在 RabbitMQ 中使用消息延迟插件&#xff0c;这个插件可以让你在消息发送时设置一个延迟时间&#xff0c;超过这个时间后消息才会被消费者接收到…

【Squid 代理服务器应用】

目录 一、Squid 代理服务器1、代理的工作机制2、代理服务器的概念及其作用3、Squid 代理的类型 二、安装 Squid 服务1&#xff0e;编译安装 Squid2&#xff0e;修改 Squid 的配置文件3&#xff0e;Squid 的运行控制1、检查配置文件语法是否正确2、启动 Squid&#xff0c;第一次…

Spring Boot中的Elasticsearch自动配置:原理与使用

Spring Boot中的Elasticsearch自动配置&#xff1a;原理与使用 简介 在Spring Boot中&#xff0c;Elasticsearch是非常流行的搜索引擎。为了方便开发人员使用Elasticsearch&#xff0c;Spring Boot提供了Elasticsearch自动配置功能。本文将介绍Elasticsearch自动配置的原理与…

mysql ——基本约束以及语法 以及 Dbeaver基本使用

1. 规约 说到约束&#xff0c;就不得不想到命名规范&#xff0c;跟java一样&#xff0c;mysql也有一套自己的命名要求 库名尽量与业务名称一致&#xff0c;比如这是一个办公系统&#xff0c;你可以命名 将数据库命名为office, 多个单词组成全小写 例如&#xff1a;officeoa 表…

Python_装饰器

目录 简单装饰器 语法糖 *args、**kwargs处理有参数的函数 带参数的装饰器 类装饰器 不带参数的类装饰器 带参数的类装饰器 装饰器执行顺序 functools.wraps 讲 Python 装饰器前&#xff0c;我想先举个例子&#xff0c;虽有点污&#xff0c;但跟装饰器这个话题很贴切。…

【javascript】二维码

javascript二维码的生成可以用第三方库qrcode.js。 下载地址&#xff1a;https://gitcode.net/mirrors/davidshimjs/qrcodejs 解压后打开index.html文件输入百度地址回车&#xff0c;就可以看到指定页面的二维码了。 html代码&#xff1a; <!DOCTYPE html PUBLIC "-/…