项目介绍
项目问题
Q1:用户鉴权、认证流程?
Q2:OAuth2是否了解 ?
- Oauth实质:OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
- 优点:保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全
- 授权种类:OAuth 2.0 规定了四种获得令牌的流程,经常使用授权码式。指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。 - 步骤:1、A网站跳转至授权网站,A网站提供clientId以及授权成功或失败后跳转url
2、授权网站要求登录,登录成功后跳转到制定url并返回授权码
3、A网站在后台拿着授权码和clientId及clientsecret(验证身份)向授权网站请求token
4、验证授权码后颁发令牌,A网站访问时携带HTTP请求头Authorization:token
Q3:项目架构?
- 服务注册发现:服务自动注册,向客户端提供服务注册表,服务健康检查,还可结合负载均衡,Zookeeper 、Eureka、Consul、Etcd
- 服务调用:feign与ribbon区别:ribbon使用 HttpClient 或 RestTemplate 模拟http请求,feign只需要创建一个接口,然后在上面添加注解即可
-service mesh:istio,服务栅格,将注册发现等功能结合在一起,与业务低侵入
Q4:网关作用?
网关定义:企业 IT 在系统边界上提供给外部访问内部接口服务的统一入口
主要功能:请求路由,安全认证
Q5:注册中心作用?
服务发现(各个节点将IP端口注册到server,缓存成注册表,提供节点调用,维护节点状态),远程调用。
Q6: 线程使用?
Java语法
Q1:怎么理解多态?封装?
Q2:双亲委派机制?如何打破?
除了启动类加载器,其他类加载器都应该有自己的父加载器。收到类加载请求后,首先递交给父类加载器,直至启动类加载器。只有父加载器不能加载时才会递交给子加载器加载。
双亲委派不是一个强制性的约束,如OSGi模型下,类加载不是树形结构,而是网状。收到请求,先检查是否时java.*开头,检查是否时委派名单,检查是否时import列表中的累,检查当前bundle的classpath
Q3:线程池参数?
创建一个线程池时需要以下几个参数:
- corePoolSize(线程池的基本大小):当提交一个任务到线程池时,线程池会创建一个线
程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任
务数大于线程池基本大小时就不再创建。如果调用线程池的 prestartAllCoreThreads 方法,
线程池会提前创建并启动所有基本线程。 - runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。可以选择以下
几个阻塞队列:
1.ArrayBlockingQueue:基于数组的有界阻塞队列,FIFO
2.LinkedBlockingQueue : 基 于 链 表 的 无 界 阻 塞 队 列 , FIFO , 吞 吐 量 高 于
ArrayBlockingQueue,Executors.newFixedThreadPoll()使用了这个队列
3.SynchronousQueue:一个只存储一个元素的阻塞队列,每个插入操作必须等到另一
个线程调用移除操作,否则插入一直处于阻塞状态,吞吐量高于 LinkedBlockingQueue,
Executors#newCachedThreadPoll()使用了这个队列
4.PriorityBlockingQueue:具有优先级的无界阻塞队列 - maximumPoolSize(线程池的最大数量):线程池允许创建的最大线程数。如果队列满了,
并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。如果使用了无
界队列该参数就没有意义了。 - ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设
置更有意义的名字。 - RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和
状态,或者当线程池已关闭时,会采用一种策略处理提交的新任务。这个策略默认是
AbortPolicy,表示无法处理新任务时抛出异常。有以下四种饱和策略:
1.AbortPolicy:直接抛出异常
2.CallerRunsPolicy:使用调用者所在线程来运行任务
3.DiscardOldestPolicy:丢弃队列中最近的一个任务,并执行当前任务
4.DiscardPolicy:不处理,直接丢弃
也可以自定义饱和策略。 - keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。出
现 timeout 情况下,而且线程数超过了核心线程数,会销毁销毁线程。保持在 corePoolSize
数。除非设置了 allowCoreThreadTimeOut 和超时时间,这种情况线程数可能减少到 0,最
大可能是 Integer.MAX_VALUE。
如果任务很多,每个任务执行的时间比较短,可以调大时间,提高线程的利用率。
allowCoreThreadTimeOut 为 true
该值为 true,则线程池数量最后销毁到 0 个。
allowCoreThreadTimeOut 为 false
销毁机制:超过核心线程数时,而且(超过最大值或者 timeout 过),就会销毁。 - TimeUnit(线程活动保持时间的单位)
Q4:线程加锁?
同步机制:synchronized、volatile 变量、显式锁、原子变量
Q5:synchronized与lock区别?
1)层次:前者是 JVM 实现,后者是 JDK 实现
2)功能:前者仅能实现互斥与重入,后者可以实现 可中断、可轮询、可定时、可公平、绑
定多个条件、非块结构
synchronized 在阻塞时不会响应中断,Lock 会响应中断,并抛出 InterruptedException 异常。
3)异常:前者线程中抛出异常时 JVM 会自动释放锁,后者必须手工释放
4)性能:synchronized 性能已经大幅优化,如果 synchronized 能够满足需求,则尽量使用
synchronized
Q6: 线程 状态?
初始态:NEW
创建一个 Thread 对象,但还未调用 start()启动线程时,线程处于初始态。
运行态:RUNNABLE
在 Java 中,运行态包括就绪态 和 运行态。
就绪态 READY
该状态下的线程已经获得执行所需的所有资源,只要 CPU 分配执行权就能运行。
所有就绪态的线程存放在就绪队列中。
运行态 RUNNING
获得 CPU 执行权,正在执行的线程。
由于一个 CPU 同一时刻只能执行一条线程,因此每个 CPU 每个时刻只有一条运行态的线程。
阻塞态 BLOCKED
阻塞态专指请求排它锁失败时进入的状态。
等待态 WAITING
当前线程中调用 wait、join、park 函数时,当前线程就会进入等待态。
进入等待态的线程会释放 CPU 执行权,并释放资源(如:锁),它们要等待被其他线程显式
地唤醒。
超时等待态 TIME_WAITING
当运行中的线程调用 sleep(time)、wait、join、parkNanos、parkUntil 时,就会进入该状
态;
进入该状态后释放 CPU 执行权 和 占有的资源。
与等待态的区别:无需等待被其他线程显式地唤醒,在一定时间之后它们会由系统自动唤醒。
终止态
线程执行结束后的状态。
Q7:rpc原理?
调用方调用服务,服务器将调用消息封装转化为二进制流通过socket发送给被调用方。
框架
Q1:spring bean加载?
Q2:beanFactory和apllication区别?
- beanFactory:spring中最底层接口。提供容器对于对象的创建、获取等功能。
-applicationContext:继承beanFactory,提供更多功能,例如:resourceLoader,AOP等
-两者装载bean区别:beanFactory只在bean使用时才实例化。ApplicationContext:在启动时将所有bean实例化,也可以单独设置lazy-init延迟实例化
延迟实例化优缺点: - 优点:启动速度快,对资源要求搞的应用有优势。
- 缺点:系统运行速度慢,不能在系统启动时发现配置问题导致的bean加载问题