面经整理(自用)

Shiro

1.shiro可以完成哪些工作?
shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等
2.Apache Shiro 的三大核心组件
a、Subject :当前用户的操作
b、SecurityManager:用于管理所有的Subject
c、Realms:用于进行权限信息的验证
3.shiro有哪些组件?
a、Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
b、Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验 证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
c、Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
d、Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储; e、Web Support:Web支持,可以非常容易的集成到Web环境;
f、Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
g、Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去; h、Testing:提供测试支持;
h、Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
i、Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
4.比较 SpringSecurity 和 Shiro
相比 Spring Security, Shiro 在保持强大功能的同时,使用简单性和灵活性。 SpringSecurity: 即使是一个一个简单的请求, 最少得经过它的 8 个Filter。SpringSecurity 必须在 Spring 的环境下使用。初学 Spring Security,曲线还是较大,需要深入学习其源码和框架, 配置起来也较费力.
5.Shiro 的优点
a、简单的身份认证, 支持多种数据源
b、对角色的简单的授权, 支持细粒度的授权(方法级) c、支持一级缓存,以提升应用程序的性能
d、内置的基于 POJO 企业会话管理, 适用于 Web 以及非 Web 的环境e、非常简单的加密 API
f、不跟任何的框架或者容器捆绑, 可以独立运行

redis

什么是nosql
NoSQL=Not Only SQL
1.NoSql数据库种类繁多,但数据之间都没有关系
2.Nosql无需事先为要存储的数据建立字段,随时可以存储自
定义的数据格式,而在关系数据库中,增删字段是一件很麻烦
的事情
3.键-值对存储,列存储,文档存储,图形数据库
dbms和nosql的区别
DBMS
高度组织化结构化数据
结构化查询语言(SQL)
数据和关系都存储在单独的表中。
数据操纵语言,数据定义语言
严格的一致性
基础事务
NoSQL
代表着不仅仅是SQL
没有声明性查询语言
没有预定义的模式
- 值对存储,列存储,文档存储,图形数据库
最终一致性,而非ACID属性
非结构化和不可预知的数据
高性能,高可用性和可伸缩性

java虚拟机

JVM是一种规范
JVM的版本
(1) 最早的虚拟机Sun Class Vm jdk 1.4
(2) Exact VM JDK 1.2
(3) HotSport 规范了所有虚拟机的应用 (服务端模式-运行效率),Client(客户端模式-进入程序的效率)
(4) JRockit

JVM结构图解

.java->javac->class文件
->类加载子系统

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xdl4WBpZ-1668073051346)(C:\Users\32817\AppData\Roaming\Typora\typora-user-images\image-20220802215501777.png)]

img

共享区:方法区+堆
(线程共享区:多线程并发访问,所有线程一起共享)
方法区存放:类文件,静态资源
堆存放:衍生的对象 (堆区=堆+方法区)
非共享区:本地方法栈+虚拟机栈+程序计数器
虚拟机栈:方法的执行,局部变量的定义(常规方法)
本地方法栈:native(本地方法)
程序计数器:多线程终端(wait)
执行引擎:执行方法
GC垃圾回收:

JIT即时编译器的原理

JIT即时编译器的原理,优化以及切换编译器类型

编译型语言和解释型语言
java -> class字节码文件 -> JVM 虚拟机指令 -> windows操作系统机器码执行指令
翻译的形式:
逐行解释,同声传译 -> 解释型语言 执行效率低
整体翻译,编译以后 -> 编译型语言 执行效率高,但是编译时间长
JIT 即时编译器:热点代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nm9BD81o-1668073051347)(C:\Users\32817\AppData\Roaming\Typora\typora-user-images\image-20220802221444951.png)]

hot 热点代码:不是一来就固定的,执行特别频繁
compiler :编译器
interpreter:解释器
-Xcomp 编译型
-Xint 解释型
热点方法探测次数
-XX:CompileThreshold=10000

方法内联优化

-XX:MaxInlineSize = 35 (小于35字节进行方法内联)
-XX:FreqInlineSize = 325 ()
JIT -> 方法内联,会将热点代码内联,
方法之间相互调用,会进行方法内联

类的加载机制和类的加载器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CkZ0ZdeD-1668073051348)(C:\Users\32817\AppData\Roaming\Typora\typora-user-images\image-20220803224447137.png)]

若干个类+一套流程+一套机制
类加载的过程:加载,连接,初始化,使用,卸载
(验证,准备,解析)
类加载器的种类
启动类加载器:自带的工具类,常用的工具类,object String 由C,汇编编写
在java中为null,所有的类加载器都是由启动类加载器启动。
扩展类加载器:ext包下的类 ExtClassLoader
应用类加载器:写的类,自己定义的类 APPClassLoader
连接
验证:验证class文件,是否符合jvm运行的规范
准备:为变量分配空间,初始值,static类型变量默认设定为0,final类型变量保持不变
解析:将符号引用替换为直接引用过程
初始化
执行类构造器init方法的过程,其中将所有的类变量赋值动作和静态语块中的语句合并产生
先初始化类,如果发现父类未初始化,则先初始化父类
使用
正常使用
卸载
类的卸载,回收
JVM停止,加载这个类的加载器被卸载
类只加载一次,而且一直存在不会自动销毁

双亲委派机制模型

类加载的机制

应用类加载器,扩展类加载器,启动类加载器
ClassNotFindException
最开始尝试加载的加载器是应用类加载器
启动类加载器:1.是否已加载 Y:直接加载 N:尝试加载
(如果在自己的加载范围内,则加载,中断加载流程,如果没有,向下指派加载器加载)
扩展类加载器:1.是否已加载 Y:直接加载 N:向上委托
(如果在自己的加载范围内,则加载,中断加载流程,如果没有,向下指派加载器加载)
应用类加载器:1.是否已加载 Y:直接加载 N:向上委托
类的加载依靠类的全限定名:类名+包名
优点:安全性高,避免重名类对系统的影响
缺点:加载类的速度会变慢
全盘委托机制
类加载的流程相同

jvm内存模型

虚拟机栈

GC垃圾回收

垃圾回收算法

虚拟机调优jvisualvm 内存追踪工具

进程和线程 的区别

1.线程是进程的子集,一个进程中可以包含多个线程,每条线程执行不同的任务; 2.不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间;
3.每个线程拥有单独的栈内存用来存储本地数据。

创建线程的七个方式

方法 含义
Executors.newFixedThreadPool() 创建一个大小固定的线程池,可控制并发的线程数,超出的线程会在队列中等待
Executors.newCachedThreadPool() 创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程
Executors.newSingleThreadExecutor() 创建单个线程的线程池,可以保证先进先出的执行顺序
Executors.newScheduledThreadPool() 创建一个可以执行延迟任务的线程池
Executors.newSingleThreadScheduledExecutor() 创建一个单线程的可以执行延迟任务的线程池
Executors.newWorkStealingPool() 创建一个抢占式执行的线程池
ThreadPoolExecutor() 手动创建线程池,可自定义相关参数

创建线程的参数

corePoolSize:核心线程数量。当线程数少于corePoolSize的时候,直接创建新的线程,尽管其他线程是空闲的。当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。
maximunPoolSize:线程池最大线程数。只有在缓冲队列满了之后才会申请超过核心线程数的线程。当线程数量大于最大线程数且阻塞队列满了这时候就会执行一些策略来响应该线程。
workQueue:阻塞队列。存储等待执行的任务,会对线程池的运行产生很大的影响。当提交一个新的任务到线程池的时候,线程池会根据当前线程数量来选择不同的处理方式。
keepAliveTime:允许线程的空闲时间。当超过了核心线程数之外的线程在空闲时间到达之后会被销毁。
unit:keepAliveTime的时间单位。
threadFactory:线程工厂。用来创建线程,当使用默认的线程工厂创建线程的时候,会使得线程具有相同优先级,并且设置了守护性,同时也设置线程名称。
handler:拒绝策略。当workQueue满了,并且没有空闲的线程数,即线程达到最大线程数。就会有四种不同策略来处理

在这里插入图片描述

三次握手

四次挥手

这里写图片描述

因为TCP是全双工的,因此,每个方向都要单独关闭
当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着
一方向不会再收到数据了,但是这个TCP连接上仍然能够发送数据,直到这一方也发送了FIN.
首先进行关闭的一方执行主动关闭,另一方执行被动关闭.第一个关闭的最后等待2MSL

Linux命令

netstats -tunpl|grep port
kill
1 (HUP):重新加载进程。
9 (KILL):杀死一个进程。
15 (TERM):正常停止一个进程。

数据库水平划分,垂直划分

水平划分是同一个表结构,存不同数据
垂直划分是按不同功能划分

单例模式

懒汉
public class LazySington {
//懒汉式,线程不安全,时间换空间
private LazySington(){
}
//类加载时不初始化,获取对象时才初始化,类加载快,获取对象时较慢
private volatile static LazySington instance=null;
public static LazySington getInstance(){
if(instance==null){
synchronized (Singleton1.class) {
if (instance == null) {
instance = new Singleton1();
}
}
}
return instance;
}
}

HTTP1.0和HTTP2.0的区别,以及HTTP和HTTPS的区别

总的区别就是:
HTTP/2采用二进制格式而非文本格式
HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个连接即可实现并行
使用报头压缩,HTTP/2降低了开销
HTTP/2让服务器可以将响应主动“推送”到客户端缓存中

tcp和udp协议

(1)TCP是可靠传输,UDP是不可靠传输;
(2)TCP面向连接,UDP无连接;
(3)TCP传输数据有序,UDP不保证数据的有序性;
(4)TCP不保存数据边界,UDP保留数据边界;
(5)TCP传输速度相对UDP较慢;
(6)TCP有流量控制和拥塞控制,UDP没有;
(7)TCP是重量级协议,UDP是轻量级协议;
(8)TCP首部较长20字节,UDP首部较短8字节;
TCP/UDP属于传输层,HTTP属于应用层.

get和post的区别

上次面试被问到,今天重新整理了一下。
1.POST 和GET本质都是一样一样的。
2.POST和GET都是HTTP请求的基本方法。
3.区别主要有以下几个:
3-1 GET请求在浏览器刷新或者回退的时候是无害的。POST的话数据会被重新提交。
3-2 GET可以被书签收藏,POST不行
3-3 GET可以存在缓存中。POST不行
3-4 GET 会将数据存在浏览器的历史中,POST不会
3-5 GET 编码格式只能用ASCII码,POST没有限制
3-6 GET 数据类型urlencode,POST是URLENCODE,form-data
3-7 可见性 参数在URL用户可以看见,POST的参数在REQUSET BODY中不会被用户看见
3-8 安全性 GET相对不安全 POST相对安全些
3-9 长度 参数一般限制2048(和WEB服务器相关),参数无限制。
4.GET 和POST在请求的时候
4-1 GET 是将数据中的hearder 和 data 一起发送给服务端,返回200code
4-2 POST 是先将hearder发给服务器返回100continue,再发送data给到服务器,返回200
4-3 GET 就发送了一个TCP数据包给服务器而POST发送了两次TCP数据包给服务器
4-4 GET和POST是已经有定义好的说明的,最好不要混用。
5. GET和POST本质上是一样一样的,GET可以加Request Body ,POST也可以在URL中添加参数。实现是可以的。

乐观锁和悲观锁

1、悲观锁
顾名思义,就是比较悲观的锁,总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
2、乐观锁
反之,总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

MyISAM索引与InnoDB索引的区别?

InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。
MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。
InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。
Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。
MyIASM引擎(原本Mysql的默认引擎):不提供事务的支持,也不支持行级锁和外键。
MEMORY引擎:所有的数据都在内存中,数据的处理速度快,但是安全性不高。

常用的 JVM 调优的参数都有哪些?

Xms2g:初始化推大小为 2g;
Xmx2g:堆最大内存为 2g;
XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4;
XX:SurvivorRatio=8:设置新生代 Eden 和 Survivor 比例为 8:2;
XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合;
XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合;
XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合;
XX:+PrintGC:开启打印 gc 信息;
XX:+PrintGCDetails:打印 gc 详细信息。

__EOF__

本文作者Reisen7
本文链接https://www.cnblogs.com/reisen7/p/18547121.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Reisen7  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示