大厂面试题分享第一期

大厂面试题分享第一期

  • Redis持久化方式
    • AOF优缺点
    • RDB优缺点
  • 如何保证Redis和Myql的一致性
  • 索引下推
  • 输入url到浏览器发生了什么
  • ReentranLock底层原理
  • SpringBoot 的启动流程

Redis持久化方式

Redis提供了两种主要的持久化机制,分别是AOF(Append-Only File)和RDB(Redis Database)

  • AOF日志:每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里
  • RDB快照:将某一个时刻的内存数据,以二进制的方式写入磁盘
  1. AOF持久化:是将Redis的操作命令追加到一个只追加文件中。通过记录所有的写操作命令,AOF文件可以重建整个数据集。AOF持久化适用于数据的持久性和故障恢复。

这里以 [set name xiaolin」命令作为例子,Redis 执行了这条命令后,记录在 AOF 日志里的内容如下
在这里插入图片描述
Redis 提供了3种写回硬盘的策略,在 Redis.conf配置文件中的 appendfsync 配置项可以有以下3种参数可填:

  • Always,这个单词的意思是「总是」,所以它的意思是每次写操作命令执行完后,同步将 AOF 日志数据写回硬盘:
  • Everysec,这个单词的意思是「每秒」,所以它的意思是每次写操作命令执行完后,先将命令写入到AOF 文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写回到硬盘;
  • No,意味着不由 Redis 控制写回硬盘的时机,转交给操作系统控制写回的时机,也,就是每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,再由操作系统决定何时将缓冲区内容写回硬盘。在这里插入图片描述
  1. RDB持久化:是将Redis的内存数据以快照的方式写入磁盘文件。该机制会在指定的时间间隔或者达到一定的数据变化量时,将当前数据库的数据集合保存到磁盘上的一个二进制文件中。RDB持久化适用于数据备份和恢复,以及冷启动时快速加载数据。

AOF优缺点

优点:

  • 提供了更好的数据安全性,因为它默认每接受到一个写命令就会追加到文件末尾,即使Redis服务器宕机,也只会丢失最后一次写入前的数据;
  • AOF支持多种同步策略(如everysec、always等),可以根据需要调整数据安全性和性能之间的平衡。同时,AOF文件在Redis启动时可以通过重写机制优化,减少文件体积,加快恢复速度。

缺点:
因为记录了每一个写操作,所以AOF文件通常比RDB文件更大,消耗更多的磁盘空间。并且,频繁的磁盘IO操作(尤其是同步策略设置为always时)可能会对Redis的写入性能造成一定影响。

RDB优缺点

优点:

  • RDB通过快照的形式保存某一时刻的数据状态,文件体积小,备份和恢复的速度非常快。
  • RDB是在主线程之外通过fork子进程来进行的,不会阻塞服务器处理命令请求,对Redis服务的性能影响较小。最后,由于是定期快照,RDB文件通常比AOF文件小得多。

缺点:

  • RDB方式在两次快照之间,如果Redis服务器发生故障,这段时间的数据将会丢失。并且,如果在RDB创建快照到恢复期间有写操作,恢复后的数据可能与故障前的数据不完全一致

如何保证Redis和Myql的一致性

如何保证Redis和Myql的一致性

索引下推

在MySQL5.6之前,当查询使用到复合索引时,MySQL会先根据索引的最左前缀原则,在索引上查找到满足条件的记录的主键或行指针,然后再根据这些主键或行指针到数据表中查询完整的行记录。之后,MySQL再根据WHERE子句中的其他条件对这些行进行过滤。这种方式可能导致大量的数据行被检索出来,但实际上只有很少的行满足WHERE子句中的所有条件。

从MySQL5.6开始引入的一个特性,索引下推通过减少回表的次数来提高数据库的查询效率;

注意:索引下推是为了减少回表而发明的。

索引下推的产生一定围绕着回表,没有回表那就没必要产生索引下推,因为上面也说了索引下推的目的就是减少回表,而不是避免回表。(题外话:避免回表使用索引覆盖——建立覆盖索引)

为了解决这个问题,MySQL 5.6引入了索引下推优化。

索引下推(index condition pushdown )简称ICP,在Mysql5.6的版本上推出,用于优化查询。
需求: 建立了(name,age)组合索引,查询users表中 “名字第一个字是张,年龄为10岁的所有记录”。

SELECT * FROM users WHERE user_name LIKE '张%' AND user_age = 10;

根据最左前缀法则,该语句在搜索索引树的时候,只能匹配到名字第一个字是‘张’的记录,接下来是怎么处理的呢?当然就是从该记录开始,逐个回表,到主键索引上找出相应的记录,再比对 age 这个字段的值是否符合。

图1: 在 (name,age) 索引里面特意去掉了 age 的值,这个过程 InnoDB 并不会去看 age 的值,只是按顺序把“name 第一个字是’张’”的记录一条条取出来回表。因此,需要回表 4 次

image.png

MySQL 5.6引入了索引下推优化,可以在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表次数。

图2: InnoDB 在 (name,age) 索引内部就判断了 age 是否等于 10,对于不等于 10 的记录,直接判断并跳过,减少回表次数.
image.png
总结
如果没有索引下推优化(或称ICP优化),当进行索引查询时,首先根据索引来查找记录,然后再根据where条件来过滤记录;

在支持ICP优化后,MySQL会在取出索引的同时,判断是否可以进行where条件过滤再进行索引查询,也就是说提前执行where的部分过滤操作,在某些场景下,可以大大减少回表次数,从而提升整体性能。

输入url到浏览器发生了什么

  1. 用户输入URL(Uniform Resource Locator):用户在浏览器的地址栏输入网址,例如:https://www.example.com。
  2. DNS解析:浏览器将解析输入的URL,首先检查其是否符合有效URL的规范。接下来,浏览器会通过DNS(Domain Name System)将域名解析为对应的IP地址。DNS解析过程可能涉及本地缓存、本地域名服务器、根域名服务器、顶级域名服务器和权威域名服务器。
  3. 获取MAC地址:当浏览器得到IP 地址后,数据传输还需要知道目的主机 MAC 地址,因为应用层下发数据给传输层,TCP 协议会指定源端口号和目的端口号,然后下发给网络层。网络层会将本机地址作为源地址,获取的IP 地址作为目的地址。然后将下发给数据链路层,数据链路层的发送需要加入通信双方的 MAC 地址,本机的 MAC 地址作为源 MAC 地址,目的 MAC 地址需要分情况处理。

通过将 IP 地址与本机的子网掩码相结合,可以判断是否与请求主机在同一个子网里,如果在同一个子网里,可以使用 APR 协议获取到目的主机的MAC 地址,如果不在一个子网里,那么请求应该转发给网关,由它代头转发,此时同样可以通过 ARP 协议来获取网关的 MAC地址,此时目的主机的 MAC 地址应该为网关的地址

  1. 建立TCP连接:在获取到目标服务器的IP地址后,浏览器会向该服务器发送一个TCP连接请求。这个过程通常包括“三次握手”。
  2. 发送HTTP请求:TCP连接建立后,浏览器会通过这个连接向服务器发送一个HTTP(Hypertext Transfer Protocol)请求。请求中包含了请求方法(例如:GET或POST)、请求的资源路径、HTTP版本、请求头(包含浏览器信息、语言、编码等信息)等。
  3. 服务器处理请求:服务器接收到浏览器的请求后,会根据请求的资源路径查找对应的资源,并进行相关处理(例如执行服务器脚本、查询数据库等)。
  4. 服务器响应:服务器处理完请求后,会生成一个HTTP响应,包含HTTP响应状态码(例如200表示成功),响应头(包含响应内容类型、编码等信息)和响应体(请求的资源内容,如HTML文档)。
  5. 浏览器接收响应:浏览器收到服务器的响应后,会根据响应头信息解析响应体中的内容。如果响应内容是HTML文档,浏览器会进行下一步的解析和渲染

ReentranLock底层原理

简单介绍一下AQS
AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁 实现的,
在这里插入图片描述
ReentrantLock 主要利用 CAS + AQS队列来实现,通过重写了 AQS 的 tryAcquire 和 tryRelease方法实现的 lock 和 unlock。

  • 它的原理是基于AQS(AbstractQueuedSynchronizer ),多个线程抢锁时,如果争抢失败则会进入阻塞队列。等待唤醒,重新尝试加锁。
  • AQS的子类有公平锁FairSync和非公平锁NofairSync,ReentrantLock的无参构造默认是非公平锁,有参构造参数是true可以设置成公平锁。
    在这里插入图片描述
  • 公平锁:ReentrantLock调用lock方法,最终会调用Sync类的tryAcquire函数,获取资源。当前线程只有在队列为空或者时队首节点的时候,才能获取资源,否则会被加入到阻塞队列中。
  • 非公平锁:调用lock方法时 lock:直接利用CAS尝试将state从 0 改为 1,如果成功,拿锁直接走,如果失败了,执行sync的tryAcquire,不同的是tryAcquire还会调用nofairTryAcquire。在nofairTryAcquire中会再次判断当前锁是否被占用
    1. 如果当前锁没有占用(state==0),直接再次尝试将state从0 改为 1 如果成功,拿锁直接走。
    2. 如果当前锁被占用(state!=0):如果被自己占用,则计数器会state++(可重入锁),如果被其他线程占用加入AQS队列
  • 公平锁和非公平锁的区别: 非公平锁在调用NonfairSync的lock的时候就会马上进行CAS抢锁,抢不到就和公平锁一样进入tryAcquire方法尝试抢锁,如果发现锁被释放了(state==0),非公平锁马上CAS抢锁,而不会管阻塞队列里是否有线程等待。而公平锁会排队等待。

SpringBoot 的启动流程

构造方法

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 获取应用类型,根据是否加载Servlet类判断是否是web环境this.webApplicationType = WebApplicationType.deduceFromClasspath();this.bootstrappers = new ArrayList<>(getSpringFactoriesInstances(Bootstrapper.class));// 读取META-INFO/spring.factories文件,获取对应的ApplicationContextInitializer装配到集合setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 设置所有监听器setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 推断main函数this.mainApplicationClass = deduceMainApplicationClass();
}

当启动springboot应用程序时,会先创建SpringApplication对象,在其构造方法中进行参数的初始化工作:

  1. 推断并设置当前web应用类型
  2. 获取所有初始化器、监听器。扫描所有META-INF/spring.factories文件中分别读取key为ApplicationContextInitializer、ApplicationListener 三种接口类型的实现类,并分别设置对应的属性,将文件中的内容放到缓存对象中,方便后续获取
  3. 定位main应用程序类
/*** Run the Spring application, creating and refreshing a new* {@link ApplicationContext}.** @param args the application arguments (usually passed from a Java main method)* @return a running {@link ApplicationContext}*/public ConfigurableApplicationContext run(String... args) {// 启动一个秒表计时器,用于统计项目启动时间StopWatch stopWatch = new StopWatch();stopWatch.start();// 创建启动上下文对象即spring根容器DefaultBootstrapContext bootstrapContext = createBootstrapContext();// 定义可配置的应用程序上下文变量ConfigurableApplicationContext context = null;/*** 设置jdk系统属性* headless直译就是无头模式,* headless模式的意思就是明确Springboot要在无鼠键支持的环境中运行,一般程序也都跑在Linux之类的服务器上,无鼠键支持,这里默认值是true;*/configureHeadlessProperty();/*** 获取运行监听器 getRunListeners, 其中也是调用了上面说到的getSpringFactoriesInstances 方法* 从spring.factories中获取配置*/SpringApplicationRunListeners listeners = getRunListeners(args);// 启动监听器listeners.starting(bootstrapContext, this.mainApplicationClass);try {// 包装默认应用程序参数,也就是在命令行下启动应用带的参数,如--server.port=9000ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);///*** 准备环境 prepareEnvironment 是个硬茬,里面主要涉及到* getOrCreateEnvironment、configureEnvironment、configurePropertySources、configureProfiles* environmentPrepared、bindToSpringApplication、attach诸多方法可以在下面的例子中查看*/ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);// 配置忽略的 beanconfigureIgnoreBeanInfo(environment);// 打印 SpringBoot 标志,即启动的时候在控制台的图案logo,可以在src/main/resources下放入名字是banner的自定义文件Banner printedBanner = printBanner(environment);// 创建 IOC 容器context = createApplicationContext();// 设置一个启动器,设置应用程序启动context.setApplicationStartup(this.applicationStartup);// 配置 IOC 容器的基本信息 (spring容器前置处理)prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);/*** 刷新IOC容器* 这里会涉及Spring容器启动、自动装配、创建 WebServer启动Web服务即SpringBoot启动内嵌的 Tomcat*/refreshContext(context);/*** 留给用户自定义容器刷新完成后的处理逻辑* 刷新容器后的扩展接口(spring容器后置处理)*/afterRefresh(context, applicationArguments);// 结束计时器并打印,这就是我们启动后console的显示的时间stopWatch.stop();if (this.logStartupInfo) {// 打印启动完毕的那行日志new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}// 发布监听应用上下文启动完成(发出启动结束事件),所有的运行监听器调用 started() 方法listeners.started(context);// 执行runner,遍历所有的 runner,调用 run 方法callRunners(context, applicationArguments);} catch (Throwable ex) {// 异常处理,如果run过程发生异常handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {// 所有的运行监听器调用 running() 方法,监听应用上下文listeners.running(context);} catch (Throwable ex) {// 异常处理handleRunFailure(context, ex, null);throw new IllegalStateException(ex);}// 返回最终构建的容器对象return context;}
复制代码
  1. 在SpringApplication对象创建完成后,开始执行run方法,来完成整个启动,启动过程中最主要有两个方法,一个是prepareContext,另外一个是refreshContext,之前的处理逻辑包含创建定时器、上下文对象的创建、banner的打印等各个准备工作,方便后续来进行调用
  2. 在prepareContext方法主要完成对上下文对象的初始化操作,包括属性的设置,比如把Environment环境变量设置给Spring容器
  3. 在refreshContext方法中会进行整个容器刷新过程,会调用Spring中AbstractApplicationContext#refresh方法,其中有13个关键的方法,来完成整个spring IOC容器的创建过程,这里会涉及Spring容器启动、自动装配、创建 WebServer启动Web服务即SpringBoot启动内嵌的 Tomcat
  4. listeners.started(context); 发布容器已启动的事件
  5. callRunners(context, applicationArguments); 遍历运行器,并调用run方法

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

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

相关文章

Python 数据可视化,怎么选出合适数据的图表

数据可视化最佳实践 1. 引言&#xff1a;为什么数据可视化最佳实践很重要 数据可视化是数据分析和决策过程中不可或缺的一部分。通过有效的可视化&#xff0c;复杂的数据可以转化为易于理解的信息&#xff0c;从而帮助观众快速做出正确的判断。然而&#xff0c;糟糕的可视化可…

单片机IO灌入5V电压导致其他IO电压测量到大于供电电压问题

最近用GD32F103RCT6做项目&#xff0c;用了3个485收发器&#xff0c;都是直接接在单片机IO上的。 485收发器是5V供电的&#xff0c;这个时候就出现5V电平和3.3V电平兼容的问题了。 一开始只用了PA10、PC11这两个串口&#xff0c;他俩是兼容5V的&#xff0c;从手册可以看出IO最…

企业源代码也需要加密!十款好用的源代码加密软件排行榜

在当今竞争激烈的商业环境中&#xff0c;企业的源代码是其核心资产之一。为了保护这些宝贵的知识产权不被泄露&#xff0c;源代码加密成为了众多企业的重要举措。2024 年&#xff0c;市面上出现了众多功能强大的源代码加密软件。接下来&#xff0c;就让我们一同来探索十款备受好…

DockerCompose编排Nginx+Mysql并实现Nginx配置Mysql(TCP协议)负载均衡

场景 Nginx配置实例-负载均衡实例&#xff1a;平均访问多台服务器&#xff1a; Nginx配置实例-负载均衡实例&#xff1a;平均访问多台服务器_我想访问五个服务器的信息用nginx怎么做-CSDN博客 以上实现Nginx的http协议的负载均衡&#xff0c;如果使用Nginx实现TCP协议的负载…

Java的JVM中的概念之——新生代和老年代

JVM新生代和老年代是JVM中非常重要的概念&#xff0c;那么他们在JVM中扮演者什么样的角色和含义呢&#xff1f; 在Java虚拟机&#xff08;JVM&#xff09;的垃圾回收&#xff08;GC&#xff09;中&#xff0c;内存被分为不同的区域&#xff0c;其中两个主要区域是新生代&#…

PHP餐厅点餐系统小程序源码

&#x1f37d;️【餐厅点餐新纪元&#xff0c;点餐系统让用餐更便捷&#xff01;】&#x1f4f1; &#x1f50d; 一键浏览&#xff0c;菜单尽在掌握 &#x1f4f1; 走进餐厅&#xff0c;无需再担心找不到服务员或菜单被抢光&#xff01;餐厅点餐系统让你轻松扫描桌上的二维码…

HarmonyOS Developer之图片帧动画播放器

创建image-animator组件 在pages/index目录下的hml文件中创建一个image-animator组件&#xff0c;css文件中编写组件样式&#xff0c;js文件中引用图片。 设置image-animator组件属性 添加iteration&#xff08;播放次数&#xff09;、reverse&#xff08;播放顺序&#xf…

LVS原理及实例

目录 LVS原理 LVS概念 lvs集群的类型 lvs-nat 解释 传输过程 lvs-dr 解释 传输过程 特点 lvs-tun LVS&#xff08;Linux Virtual Server&#xff09;常见的调度算法 防火墙标记&#xff08;Firewall Marking&#xff09;结合轮询调度 实战案例 lvs的nat模式配置 …

使用Linux实现FTP云盘1

关于FTP服务器 FTP&#xff08;文件传输协议&#xff09;服务器是在互联网上提供文件存储和访问服务的计算机&#xff0c;它们依照FTP 协议提供服务。 FTP是File Transfer Protocol(文件传输协议)。 程序运行&#xff0c;服务端不断接收客户端指令&#xff0c;服务 端可同时处…

提取含有特定字符的行和列grep函数(含有替换)

目录 ①grep提取含有特定字符的列 ②grep提取含有特定字符的行 R语言进行字符的替换和删减gsub&#xff0c;substr函数R语言进行字符的替换和删减gsub&#xff0c;substr函数_r语言数据框字符替换-CSDN博客 ①grep提取含有特定字符的列 在一个dataframe中&#xff0c;需要提…

Element学习(axios异步加载数据、案例操作)(5)

1、这次学习的是上次还未完成好的恶element案例&#xff0c;对列表数据的异步加载&#xff0c;并渲染展示。 ——>axios来发送异步请求 &#xff08;1&#xff09; &#xff08;2&#xff09;在vue当中安装axios &#xff08;注意在当前的项目目录&#xff0c;并且安装完之后…

Xcode 在原生集成flutter项目

笔者公司有一个从2017年就开始开发的iOS和安卓原生项目&#xff0c;现在计划从外到内开始进行项目迁徙。 1》从gitee拉取flutter端的代码&#xff1b;&#xff08;Android报错Exception: Podfile missing&#xff09; 2》替换Xcode里的cocopods里Podfile的路径 然后报警 然后…

Linux从0到1——进程池

Linux从0到1——进程池 1. 进程池的概念2. 进程池实现思路3. 进程池的代码实现3.1 创建管道&#xff0c;创建子进程3.2 封装任务3.3 Work接口3.4 发送任务3.5 回收资源&#xff0c;关闭管道&#xff08;重点&#xff09;3.6 改造CreatChannels接口 4. 完整代码 1. 进程池的概念…

ECMAScript6模板字面量:反引号、${}占位符的使用

ECMAScript 6 中引入了模板字面量&#xff0c;主要通过多行字符串和字符串占位符对字符串进行增强操作。如下&#xff1a; //使用ECMAScript6模板字面量拼接字符串&#xff0c;例如&#xff1a;2024年8月12日 15:38:28 星期一 let dateRet ${Year}年${Month}月${Dates}日 ${H…

lvs、集群

1.集群和分布式 当多个用户当用户访问一个服务器时&#xff0c;服务器server1可能就会崩&#xff0c;假如这时候我们新加一个服务器server2来缓解server1的压力&#xff0c;那么就需要一个调度器lvs来分配&#xff0c;所以现在就是用户的访问就需要通过调度器之后到达服务器&a…

简述MYSQL聚簇索引、二级索引、索引下推

一丶聚簇索引 InnoDB的索引分为两种&#xff1a; 聚簇索引&#xff1a;一般创建表时的主键就会被mysql作为聚簇索引&#xff0c;如果没有主键则选择非空唯一索引作为聚簇索引&#xff0c;都没有则隐式创建一个索引作为聚簇索引&#xff1b;辅助索引&#xff1a;也就是非聚簇索…

KillWxapkg 自动化反编译微信小程序,小程序安全评估工具,发现小程序安全问题,自动解密,解包,可还原工程目录,支持修改Hook,小程序

纯Golang实现&#xff0c;一个用于自动化反编译微信小程序的工具&#xff0c;小程序安全利器&#xff0c;自动解密&#xff0c;解包&#xff0c;可还原工程目录&#xff0c;支持微信开发者工具运行 由于采用了UPX压缩的软件体积&#xff0c;工具运行时可能会出现错误报告&…

在等保测评中,如何平衡技术风险和非技术风险的评估?

在等保测评中平衡技术风险和非技术风险的评估&#xff0c;需要一个综合的方法来确保所有相关的风险都得到适当的考虑。以下是一些关键步骤&#xff1a; 1. 全面风险识别&#xff1a;首先识别所有可能影响组织的风险&#xff0c;包括技术风险&#xff08;如系统漏洞、恶意软件&…

企业大模型落地从0到0.1

现在人工智能里的“大明星”——大模型&#xff0c;正在悄悄改变各行各业。这就像给企业装上了一颗聪明的大脑&#xff0c;能帮助解决各种棘手问题&#xff0c;提升工作效率。今天&#xff0c;我们就来分析下企业如何一步一步让这个“大脑”在自家地盘里真正派上用场&#xff0…

九、OpenCVSharp 中的图像形态学操作

文章目录 简介一、腐蚀1. 腐蚀的原理和数学定义2. 结构元素的形状和大小选择3. 腐蚀操作的代码实现和效果展示二、膨胀1. 膨胀的概念和作用2. 与腐蚀的对比和组合使用(如开运算、闭运算)三、开运算1. 开运算的定义和用途(去除小的明亮区域)2. 开运算在去除噪声和分离物体方…