JAVA高级架构师面试
以面试为主,整理常见JAVA高级架构师面试资料,供求职者参考
mischen520
JAVA高级架构师
展开
-
接口性能优化方法总结
将一些经常查询需要的固定不变的数据加入到缓存中,请求的时候优先从缓存里面去取数据,这样会大大提高接口的查询性能,因为缓存是存在内存中的,避免了大量的数据库查询。在操作Redis和数据库时,要么两者都成功,要么都失败,使用数据库的事务可以保证这一点。当系统发展到一定阶段,用户并发量增加,会有大量的数据库请求,这不仅需要占用大量的数据库连接,还会带来磁盘IO的性能瓶颈问题。为了提升接口性能,尤其在高并发场景下,可以考虑数据冗余,将用户信息、积分和成长值的数据统一存储在一个地方,比如Redis。原创 2024-06-23 14:54:01 · 1489 阅读 · 0 评论 -
TCP 和 UDP 可以同时绑定相同的端口吗?
端口号是一个16位的数字,范围从0到65535,其中0到1023是知名端口号,通常用于特定的服务,例如HTTP服务通常使用TCP端口80,DNS服务通常使用UDP端口53。协议号字段指定了传输层协议的类型,例如TCP的协议号是6,UDP的协议号是17。假设有一台服务器同时提供DNS服务,DNS服务既支持使用TCP协议(用于处理较大的请求),也支持使用UDP协议(用于处理较小的请求)。TCP/UDP 各自的端口号也相互独立,如 TCP 有一个 80 号端口,UDP 也可以有一个 80 号端口,二者并不冲突。原创 2024-06-22 08:21:41 · 987 阅读 · 0 评论 -
java接口设计需要考虑哪些方面
业务调用接口前先获取token,然后调用业务接口请求时,把token携带过去,服务端判断token是否存在redis中,存在则表示第一次请求,可以继续执行业务,执行完成后把redis中的token删除。(2)使用Hibernate Validator框架进行校验(如@Size、@Length、@Max等)。(4)API接口网关服务验证传递的sign值,与自己生成的sign值对比,若相等则认为是有效请求。(1)使用消息中间件。(1)记录请求url、参数、头信息、请求方式、响应数据和响应时间等。原创 2024-06-10 15:15:58 · 520 阅读 · 1 评论 -
如何实现接口的幂等性
2.服务端提供发送token的接口,业务调用接口前先获取token,然后调用业务接口请求时,把token。携带过去,服务端判断token是否存在redis中,存在表示第一次请求,可以继续执行业务,执行业务。每次操作,都根据操作和内容生成唯一的id,在执行之前先判断id是否存在,如果不存在。例如订单有状态已支付 未支付 支付中 支付失败,当处于未支付的时候才允许修改为支。将业务中有唯一标识的字段保存到去重表,如果表中存在,则表示已经处理过了。增加版本号,当版本号符合时,才能更新数据。原创 2024-06-01 07:24:25 · 222 阅读 · 0 评论 -
分布式事务Seata的实现原理。谈谈对Seata的理解。Seata支持的4种分布式事务模式
Saga 模式一阶段就会提交本地事务,无锁,长流程情况下可以保证性能,多用于渠道层、集成层业务系统,事务参与者可以是其它公司的服务也可以是遗留系统的服务,并且对于无法进行改造和提供 TCC 要求的接口,也可以使用 Saga 模式。1.在微服务架构下,由于数据库和应用服务的拆分,导致原本一个事务单元中的多个DML操作,变成了跨进程或者跨数据库的多个事务单元的多个DML操作,而传统的数据库事务无法解决这类的问题,所以就引出了分布式事务的概念。CP模式:各个子事务执行后互相等待,同时提交,同时回滚,达成强一致。原创 2023-03-14 13:00:00 · 417 阅读 · 0 评论 -
Integer a=100,b=100,a==b的运行结果?Integer c=1000,d=1000,c==d的运行结果?
比较得到的结果必然是true。而第二个问题,因为不在-128-127之间,则指向的内存地址都不一样,故用==比较必然为false。Integer a=100,b=100时候a。原创 2022-10-14 20:10:27 · 1031 阅读 · 0 评论 -
多线程工具类以及运用多线程详细示例代码
3.ChildTask类。4.LoopTask类。原创 2022-10-13 11:06:21 · 612 阅读 · 0 评论 -
java保证线程安全的方式有哪些?
同时,针对不同的应用场景,还可以使用分布式锁来实现线程安全,比较常用的分布式锁实现方式有,基于数据库实现的分布式锁(不常用,除非是单数据库,但是不便于后期扩展),基于redis实现的分布式锁、基于zookeeper实现的分布式锁。让这些变量在多线程环境下访问(get/set)时能保证各个线程里的变量相对独立于其他线程内的变量。ThreadLocal采⽤了“以空间换时间”的⽅式,为每⼀个线程都提供⼀份变量的副本,从⽽实现同时访问⽽互不影响,但因为每个线程都维护着⼀份副本,对内存空间的占⽤会增加。原创 2022-10-05 13:31:27 · 4008 阅读 · 0 评论 -
一个空的Java object 对象占多大内存?
对象头: 1.MakeOop :存储hashcode 垃圾回收时候的分代年龄 synchronized锁升级过程中的锁标记 (无锁、偏向锁、轻量级锁、重量级锁) 32位操作系统占4个字节 64位操作系统占8个字节。在开启了压缩指针的情况下,Object默认会占用12个字节,但是为了避免伪共享问题,JVM会按照8个字节的倍数进行填充,所以会填充4个字节变成16个字节长度。在关闭压缩指针的情况下,Object默认会占用16个字节,16个字节正好是8的整数倍,因此不需要填充。原创 2022-10-03 20:06:14 · 2807 阅读 · 3 评论 -
如何打破双亲委派模型?打破双亲委派模型示例?什么是双亲委派模型?
双亲委派模型:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。3.双亲委派就是类加载器之间的层级关系,加载类的过程是一个递归调用的过程,首先一层一层向上委托父类加载器加载,直到到达最顶层启动类加载器,启动类加载器无法加载时,再一层一层向下委托给子类加载器加载。为什么要打破双亲委派模型?原创 2022-09-10 09:36:53 · 1143 阅读 · 0 评论 -
RabbitMQ如何确保消息发送 ? 消息接收?
发送方确认机制:信道需要设置为 confirm 模式,则所有在信道上发布的消息都会分配一个唯一 ID。一旦消息被投递到queue(可持久化的消息需要写入磁盘),信道会发送一个确认给生产者(包含消息唯一ID)。如果 RabbitMQ 发生内部错误从而导致消息丢失,会发送一条 nack(未确认)消息给生产者。所有被发送的消息都将被 confirm(即 ack) 或者被nack一次。但是没有对消息被 confirm 的快慢做任何保证,并且同一条消息不会既被 confirm又被nack发送方确认模式是异原创 2022-07-08 08:25:14 · 695 阅读 · 0 评论 -
ConcurrentHashMap实现原理
jdk7:数据结构:ReentrantLock+Segment+HashEntry,一个Segment中包含一个HashEntry数组,每个 HashEntry又是一个链表结构。元素查询:二次hash,第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部。锁:Segment分段锁 Segment继承了ReentrantLock,锁定操作的Segment,其他的Segment不受影响,并发度为segment个数,可以通过构造函数指定,数组扩容不会影响其他的segment。get方原创 2022-07-03 08:34:00 · 105 阅读 · 0 评论 -
Aspect切面类的实际应用
切面,面向切面编程原创 2022-06-02 21:03:40 · 774 阅读 · 0 评论 -
with as 的使用方式详解
一. WITH AS 的含义WITH AS 短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在 UNION ALL 的不同部分,作为提供数据的部分。特别对于 UNION ALL 比较有用。因为 UNION ALL 的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,所以可以使用 WITH AS 短语,则只要执行一遍即可。如果原创 2022-06-02 19:14:26 · 11154 阅读 · 0 评论 -
oracle面试题解析(用一条sql语句实现批量一对一更新)
需求:现在有一个项目表project,里面的字段主要有proj_Id,money,主键字段为id,proj_Id可能为空,money字段类型为NUMBER(17,2),在某种条件下,会关联表proj_appl表字段proj_Id,另外一个表proj_appl,里面的字段主要有proj_Id,appl_money,主键字段为proj_Id,appl_money字段类型为NUMBER(17,2),现在两边的金额不一致,需要把两个表金额不一致的替换为金额一致的表,金额以表proj_appl表字段proj_I原创 2022-05-31 19:00:00 · 612 阅读 · 0 评论 -
如何利用一条sql语句进行批量更新(需要满足一对一更新)
需求:现在有一个项目表project,里面的字段主要有proj_Id,money,主键字段为id,proj_Id可能为空,money字段类型为NUMBER(17,2),在某种条件下,会关联表proj_appl表字段proj_Id,另外一个表proj_appl,里面的字段主要有proj_Id,appl_money,主键字段为proj_Id,appl_money字段类型为NUMBER(17,2),现在两边的金额不一致,需要把两个表金额不一致的替换为金额一致的表,金额以表proj_appl表字段proj_I原创 2022-05-31 18:00:00 · 7405 阅读 · 0 评论 -
C/S和B/S两种架构风格各自的优点和缺点
C/S架构风格的优点:(1)客户机应用程序和服务器程序分离,二者的开发既可以分开进行,也可以同时进行;(2)技术成熟,允许网络分布操作,交互性强,具有安全的存取模式;(3)网络压力小,响应速度快,有利于处理大量数据;(4)模型思想简单,易于人们理解和接受等。C/S架构风格的缺点:(1)客户机与服务器的通信依赖于网络,服务器的负荷过重;(2)无法实现快速部署和安装,维护工作量大,升级困难;(3)开发成本较高,客户端程序设计复杂,灵活性差;(4)用户界面风格不一,软件移植性和数据集成困难;(原创 2022-03-29 20:35:37 · 6788 阅读 · 0 评论 -
SQL优化的基本思路
(1)建立物化视图或尽可能减少多表查询。(2)以不相干子查询替代相干子查询。(3)只检索需要的列。(4)用带in的条件子句等价替换or子句。(5)经常提交commit,以尽早释放锁。(6)避免嵌套的游标(Cursor)和多重循环等。...原创 2022-03-29 08:25:00 · 3377 阅读 · 0 评论 -
关系型数据库可能带来的问题以及产生的原因
采用关系型数据库可能带来的问题:1.用户执行读写操作时,响应时间均变得很慢;2.随着系统功能的扩充,原有数据格式发生变化,又出现新的数据格式,维护困难;3.数据容量很快超过系统原有的设计上限,数据库扩容困难;4.软件系统不断出现宕机,整个系统可用性较差。产生的主要原因:1.用户响应时间慢。大型网络系统要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强可以,但是应对原创 2022-03-25 08:44:55 · 1927 阅读 · 0 评论 -
认识Netty 线程模型
Netty 使用 EventLoop 来处理连接上的读写事件,而一个连接上的所有请求都保证在一个 EventLoop 中被处理,一个 EventLoop 中只有一个 Thread,所以也就实现了一个连接上的所有事件只会在一个线程中被执行。一个 EventLoopGroup 包含多个 EventLoop,可以把一个 EventLoop 当做是 Reactor 线程模型中的一个线程,而一个 EventLoopGroup 类似于一个 ExecutorService...原创 2021-11-13 07:49:47 · 250 阅读 · 0 评论 -
TCP 粘包/拆包的解决办法
1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。2、发送端将每个数据包封装为固定长度(不够的可以通过补 0 填充),这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。3、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开。...原创 2021-10-22 07:19:30 · 1224 阅读 · 0 评论 -
什么是 TCP 粘包/拆包
1、要发送的数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包。2、待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包。3、要发送的数据小于 TCP 发送缓冲区的大小,TCP 将多次写入缓冲区的数据一次发送出去,将会发生粘包。4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。...原创 2021-10-22 07:16:04 · 1225 阅读 · 0 评论 -
Spring AOP 的实现原理
Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理。JDK 动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK 动态代理的核心是 InvocationHandler 接口和 Proxy 类。如果目标类没有实现接口,那么 Spring AOP 会选择使用 CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB 是通过继承的.原创 2021-10-22 07:02:55 · 185 阅读 · 0 评论 -
浏览器发出一个请求到收到响应经历了哪些步骤?
1.浏览器解析用户输入的URL,生成一个HTTP格式的请求2.先根据URL域名从本地的hosts文件查找是否有映射IP,如果没有就将域名发送给电脑配置的DNS进行域名解析,得到IP地址3.浏览器通过操作系统将请求通过四层网络协议发送出去4.途中可能会经过各种路由器、交换机、最终到达服务器5.服务器收到请求后,根据请求所指定的端口,将请求传递给绑定了该端口的应用程序,比如8080被tomcat占用了6.Tomcat接收到请求数据后,按照http协议的格式进行解析,解析得到所要访问的servlet7原创 2021-10-22 06:54:24 · 2723 阅读 · 0 评论 -
Spring支持几种bean的作用域?
singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。该对象的生命周期是与Spring IOC容器一致的(但在第一次被注入时才会创建)。prototype:为每一个bean请求提供一个实例。在每次注入时都会创建一个新的对象request:bean被定义为在每个HTTP请求中创建一个单例对象,也就是说在单个请求中都会复用这一个单例对象。session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,b原创 2021-10-22 06:34:02 · 154 阅读 · 0 评论 -
spring是怎么解决循环依赖的?
Spring创建bean主要分为两个步骤,创建原始bean对象,接着去填充对象属性和初始化,每次创建bean之前,我们都会从缓存中查下有没有该bean,因为是单例,只能有一个,当我们创建beanA的原始对象后,并把它放到三级缓存中,接下来就该填充对象属性了,这是时候发现依赖了beanB,接着就又去创建beanB,同样的流程,创建完beanB填充属性时又发现他依赖了beanA又是同样的流程,不同的是,这时候可以在三级缓存中查到刚放进去的原始对象beanA,所以不需要继续创建,用它注入beanB,完成beanB原创 2021-10-20 20:18:18 · 160 阅读 · 0 评论 -
HashMap如何解决Hash冲突
通过引入单向链表来解决 Hash 冲突。当出现 Hash 冲突时,比较新老 key 值是否相等,如果相等,新值覆盖旧值。如果不相等,新值会存入新的 Node 结点,指向老节点,形成链式结构,即链表。当 Hash 冲突发生频繁的时候,会导致链表长度过长,以致检索效率低,所以 JDK1.8 之后引入了红黑树,当链表长度大于 8 时,链表会转换成红黑书,以此提高查询性能。...原创 2021-10-19 21:03:56 · 910 阅读 · 0 评论 -
说说几种常见的消息中间件的区别?
中小型公司⾸首选RabbitMQ:管理理界⾯面简单,高并发。大型公司可以选择RocketMQ:更⾼高并发,可对rocketmq进行定制化开发。日志采集功能,首选kafka,专为⼤大数据准备。原创 2021-10-19 20:59:21 · 267 阅读 · 0 评论 -
MQ如何保证分布式事务的最终一致性
分布式事务:业务相关的多个操作,保证他们同时成功或者同时失败最终一致性:与之对应的就是强一致性MQ中要保证事务的最终一致性,就需要做到两点1.生产者要保证100%的消息投递。事务消息机制2.消费者这一端需要保证幂等消费。唯一ID+业务自己实现的幂等分布式MQ的三种语义:at least onceat most onceexactly once:RocketMQ并不能保证exactly once。商业版本当中提供了exactly once的实现机制。Kafka:在最新版本的源码当中,提供了e原创 2021-10-19 20:47:23 · 3016 阅读 · 0 评论 -
如何排查CPU占用过高的问题?谈谈你的分析思路和定位步骤
1.使用top命令找出CPU占比最高的2.使用ps -ef或者jps进一步定位 示例:jps -l 或 ps -ef | grep java|grep -v grep3.定位到具体线程或者代码ps -mp 进程 -o THREAD,tid,time-m 显示所有的线程-p pid进程使用cpu的时间-o 该参数后是用户自定义格式4.将需要的线程ID转换为16进制格式(英文小写格式) printf “%x\n” 有问题的线程ID5.jstack 进程ID | grep tid(16进制线程I原创 2021-10-19 20:25:42 · 855 阅读 · 0 评论 -
spring事务传播机制
多个事务方法相互调用时,事务如何在这些方法间传播方法A是一个事务的方法,方法A执行过程中调用了方法B,那么方法B有无事务以及方法B对事务的要求不同都会对方法A的事务具体执行造成影响,同时方法A的事务对方法B的事务执行也有影响,这种影响具体是什么就由两个方法所定义的事务传播类型所决定。REQUIRED(Spring默认的事务传播类型):如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行MANDATO原创 2021-10-16 05:18:31 · 150 阅读 · 0 评论 -
真实项目中如何排查jvm问题
对于还在正常运行的系统:1.可以使用jmap来查看jvm中各个区域的使用情况2.可以通过使用jstack来查看线程的运行情况,比如哪些线程阻塞、是否出现了死锁3.可以通过jstat命令来查看垃圾回收的情况,特别是fullgc,如果发现fullgc比较频繁,那么就得进行调优了4.通过各个命令的结果,或者jvisualvm等工具来进行分析5.首先,初步猜测频繁发送fullgc的原因,如果频繁发生fullgc但是又一直没有出现内存溢出,那么表示fullgc实际上是回收了很多对象了,所以这些对象最好能在y原创 2021-10-14 07:00:46 · 694 阅读 · 0 评论 -
谈谈你对AOP的理解
系统是由许多不同的组件所组成的,每一个组件各负责一块特定功能。除了实现自身核心功能之外,这些组件还经常承担着额外的职责。例如日志、事务管理和安全这样的核心服务经常融入到自身具有核心业务逻辑的组件中去。这些系统服务经常被称为横切关注点,因为它们会跨越系统的多个组件。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。在OOP设计中原创 2021-10-02 04:16:25 · 174 阅读 · 0 评论 -
GC如何判断对象可以被回收
引用计数法:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收可达性分析法:从 GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GCRoots没有任何引用链相连时,则证明此对象是不可用的,那么虚拟机就判断是可回收对象。引用计数法,可能会出现A引用了 B,B又引用了 A,这时候就算他们都不再使用了,但因为相互引用计数器=1永远无法被回收。GC Roots的对象有:虚拟机栈(栈帧中的本地变量表)中引用的对象方法区中类静态属性引用的对象方原创 2021-10-01 07:22:31 · 161 阅读 · 0 评论 -
Spring框架中用到了哪些设计模式(最全面的面试答案)
1.简单工厂:由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。2.工厂方法:实现了FactoryBean接口的bean是一类叫做factory的bean。其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该bean的getObject()方法,所以返回的不是factory这个bean,而是这个原创 2021-10-01 07:06:51 · 545 阅读 · 0 评论 -
多线程交替输出问题3种常用解法(多线程经典面试题)
题目:让两个多线程交替输出距离:“ABCDEF”和“123456”,输出结果为固定“A1B2C3D4E5F6”1.利用synchronized+wait/notifypackage com.mooc.house.user.controller;/** * @ClassName sync_wait_notify * @Description DOTO * @Author mischen * @Date 2021/9/30 0030 6:11 * @Version 1.0 **/pub原创 2021-09-30 06:24:47 · 820 阅读 · 0 评论 -
多线程经典面试题(show me the Difference)
指出以下两段程序的差别,并分析:final class Accumulator{ private double result=0.0D; public void addAll(double[] values){ for (double value :values){ result += value; } }}final class Accumulator2{ private double result=0.0D;原创 2021-09-26 06:32:31 · 192 阅读 · 0 评论 -
Java 是如何实现线程间通信的?
正常情况下,每个子线程完成各自的任务就可以结束了。不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了。本文涉及到的知识点:thread.join(),object.wait(),object.notify(),CountdownLatch,CyclicBarrier,FutureTask,Callable 。下面我从几个例子作为切入点来讲解下 Java 里有哪些方法来实现线程间通信。如何让两个线程依次执行?那如何让 两个线程按照指定方式有序交叉运行呢?四原创 2021-09-21 07:55:15 · 296 阅读 · 0 评论 -
如何配置多个线程池来隔离任务?
什么是线程池的隔离,为什么要隔离可能有的小伙伴还不太了解什么是线程池的隔离,为什么要隔离?。所以,我们先来看看下面的场景案例:package com.mooc.house.user.controller;import com.mooc.house.user.config.AsyncTasks;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annot原创 2021-09-19 06:45:23 · 1098 阅读 · 0 评论 -
亿级流量架构怎么做资源隔离?
为什么要资源隔离常见的资源,例如磁盘、网络、CPU等等,都会存在竞争的问题,在构建分布式架构时,可以将原本连接在一起的组件、模块、资源拆分开来,以便达到最大的利用效率或性能。资源隔离之后,当某一部分组件出现故障时,可以隔离故障,方便定位的同时,阻止传播,避免出现滚雪球以及雪崩效应。常见的隔离方式有:线程隔离进程隔离集群隔离机房隔离读写隔离动静隔离爬虫隔离等等线程隔离网络上很多帖子,大多是从框架开始聊的,这儿说人话其实就是对线程进行治理,把核心业务线程与非核心业务线程隔开,不同的业务需原创 2021-09-19 06:08:43 · 171 阅读 · 0 评论