秋招面经——结合各方面试经验
Mysql
mysql事务
共享锁与排他锁
共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。(读都允许读,但我在读不允许你去改)
排他锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。(我在修改数据,别的操作都被禁止)
事务特性
事务四个特性:ACID
- 原子性(Atomicity):指事务是一个不可分割的最小工作单位,事务中的操作只有都发生和都不发生两种情况
- 一致性(Consistency):数据库总是从一个一致性的状态转换到另外一个一致性的状态。
- 隔离性(Isolation):一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持久性(Durability):一个事务一旦提交成功,它对数据库中数据的改变将是永久性的,接下来的其他操作或故障不应对其有任何影响。
如何实现这些特性
- 原子性:靠Undo log实现,即如果一个事务异常或执行失败后进行回滚
- 当事务对数据库进行修改时,InnoDB会生成对应的 undo log;
- 如果事务执行失败或调用了 rollback,导致事务需要回滚,便可以利用 undo log 中的信息将数据回滚到修改之前的样子。
- undo log 属于逻辑日志,它记录的是sql执行相关的信息。
- 当发生回滚时,InnoDB 会根据 undo log 的内容做与之前相反的工作
- 一致性:事务的最终目的,即需要数据库层面保证,又需要应用层面进行保证,并且MySQL底层通过两阶段提交事务保证了事务持久化时的一致性。
- 隔离性:靠锁和MVCC实现
- 锁:
- 在 InnoDB 事务中,行锁通过给索引上的索引项加锁来实现。
- 只有通过索引条件检索数据,InnoDB才使用行级锁,否则将使用表锁。
- 行级锁定同样分为两种类型:共享锁和排他锁
- 使用Record Lock和Gap Lock(解决幻读)
- MVCC:多版本并发控制
- DB_TRX_ID:事务 ID,是根据事务产生时间顺序自动递增的
- DB_ROLL_PTR:回滚指针,本质上就是一个指向记录对应的undo log的一个指针,InnoDB 通过这个指针找到之前版本的数据
- MVCC在事务开启时会为事务生成一个ID,并且在查询时生成一个快照,能看到当前活跃的事务,然后通过比较快照的生成时间和活跃事务的提交时间进行对比,判断读取哪个版本的数据。
- 锁:
- 持久性:靠Redo log实现
- mysq|修改数据的时候会在redo log中记录一份日志数据,就算数据没有保存成功,只要日志保存成功了,数据仍然不会丢失
- 当一条数据需要更新时,InnoDB会先将数据更新,然后记录redoLog 在内存中,然后找个时间将redoLog的操作执行到磁盘上的文件上。
mysql隔离级别
mysql具有四种隔离级别
| 隔离级别 | 说明 |
|---|---|
| 读未提交 | 一个事务还没提交时,它做的变更就能被别的事务看到 |
| 读已提交 | 一个事务提交之后,它做的变更才会被其他事务看到 |
| 一个事务提交之后,它做的变更才会被其他事务看到 | 一个事务中,对同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。InnoDB默认级别 |
| 串行化 | 事务串行化执行,每次读都需要获得表级共享锁,读写相互都会阻塞,隔离级别最高,牺牲系统并发性。 |
不同的隔离级别是为了解决不同的问题。也就是脏读、幻读、不可重复读。
| 问题 | 说明 |
|---|---|
| 脏读 | 读到了其他事务未提交的数据 |
| 不可重复读 | 在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据出现不一致的情况 |
| 幻读 | 在一个事务中,后续读取的数据,在最开始读取的数据中不存在 |
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交 | 可以出现 | 可以出现 | 可以出现 |
| 读已提交 | 不允许出现 | 可以出现 | 可以出现 |
| 一个事务提交之后,它做的变更才会被其他事务看到 | 不允许出现 | 不允许出现 | 可以出现 |
| 串行化 | 不允许出现 | 不允许出现 | 不允许出现 |
Mysql和MangoDB的比较
Mysql:
- 关系数据库系统,相关信息可能存储在单独的表中,但通过使用关联查询来关联。通过使用这种方式,使得数据重复量被最小化。
- 关系型数据库的最大特点就是事务的一致性
- 为了维护一执行需要消耗大量的性能
MangoDB:
- 少量数据时,数据存在内存中。当内存不够时,只将热点数据放在内存,其他存入磁盘
- 数据存储在类似JSON的文档中,并且文档中每个json串结构可能有所不同
- 使用动态模式,这意味着您可以在不首先定义结构的情况下创建记录,例如字段或其值的类型
- 支持多种存储格式(mysql只支持基本类型)
- 设计了高可用性和可扩展性,并提供了即用型复制和自动分片功能。
- 简化了开发,因为 MongoDB 文档自然映射到现代的面向对象编程语言。使用 MongoDB 可以避免将代码中的对象转换为关系表的复杂对象关系映射(ORM)层。
sql优化
select *浪费资源,减少使用,且不走索引union all比union更快(但是不去重)- 小表驱动大表:大表
in小表 ; 小表exists大表; - 批量插入数据尽量使用
insertBatch,而不是循环(循环会多次请求数据库) - 多使用
limit,减少内存消耗 - 海量数据查询分页,使用条件查询结合
limt size,去替代limit start size - 使用连接查询代替子查询(子查询会为子查询额外创建一个表)
join的表不能太多,否则容易选错索引- 索引不宜太多,因为在增删改查的时候都需要更新索引表(使用联合索引)
- 将
group by后接的having条件适当提到前面的where中
Spring
maven中版本 版本冲突
maven依赖中不允许存在两个不同版本的同名依赖。(添加<exclusion>标签来解决冲突)
Kafka
Kafka和其他消息队列对比
| 对比 | Kafka | RocketMQ | RabbitMQ |
|---|---|---|---|
| 优先级队列 | 不支持 | 通过建立不同的队列 | 通过建立不同的队列 |
| 延迟队列 | 不支持 | 基于队列的延迟 | 基于队列的延迟 |
| 死信队列 | 不支持 | 支持 | 支持 |
| 消费模式 | pull | pull/push | pull/push |
| 广播模式 | 发布订阅 | 发布订阅 | 点对点 (但可以由交换机实现发布订阅模式) |
| 消息回溯 | offset和timestamp | 按时间回溯 | 不支持 |
| 消息堆积&持久化 | 磁盘堆积:所有消息都存在磁盘 每个partition对应一个或多个segment file | 基于磁盘存储 使用commit Log存储消息(顺序写到文章末尾) 后台异步线程同步到consumerQueue 使用内存映射文件加速消息读取 | 内存堆积(换页操作存储到磁盘) (或使用惰性队列将消息持久化到磁盘) |
| 流量控制 | 支持client和user级别 | 多种维度的流量控制 | 流量控制基于credit-base算法,是内部被动触发的保护机制,作用于生产者层面 |
| 顺序性消息 | 同分区内有序 | Broker消息队列锁(分布式锁) Consumer消息队列锁(本地锁) Consumer消息处理队列消费锁(本地锁) | 无法保证全局有序 |
| 性能 | 最快 | 中等 | 最慢 |
| 高可用和容错 | 包含Leaer和Follower Leader失效后随机选举Leader | Master和Slave | cluster(集群),federation(联盟),shovel |
| 定时消息 | 不支持 | 支持 | 支持 |
| 负载均衡 (三者都是软件负载均衡) | consumer端实现 每个消费者组都有指定一个broker为coordinator(群组协调器) | consumer端实现 所有的consumer都能得到consumer的订阅表,每个consumer自己做负载均衡 | 设置Prefetch count来限制Queue每次发送给每个消费者的消息数 |
| 刷盘策略 | 异步刷盘 每3s钟调用1次fsync 支持同步刷盘 | CommitRealTimeService 异步刷盘 && 开启内存字节缓冲区 第一 FLushRealTimeService 异步刷盘 && 关闭内存字节缓冲区 第二 GroupCommitService 同步刷盘 第三 | 优先内存存储,Buff不够再刷盘 |
| 消息中间件 | Kafka | RocketMQ | RabbitMQ |
|---|---|---|---|
| 特点 | 高吞吐量 持久性 分布式 发布订阅 | 高可用性 顺序消息 分布式事务 高扩展性 | 灵活路由 点对点+发布订阅+请求响应 可靠性 插件扩展 |
| 适用场景 | 流式处理(日志收集 实时分析) 大数据集成 可靠性(持久化)要求高 | 异步消息处理 顺序消息 分布式事务 | 复杂路由 灵活消息模式 异步任务处理 |
Redis
缓存穿透、击穿、雪崩
缓存穿透
指访问一个缓存和数据库中都不存在的key,由于这个key在缓存中不存在,则会到数据库中查询,数据库中也不存在该key,无法将数据添加到缓存中,所以每次都会访问数据库导致数据库压力增大。
解决办法
将访问过的key设置为空key,加入到缓存中
缓存击穿
指大量请求访问缓存中的一个key时,该key过期了,导致这些请求都去直接访问数据库,短时间大量的请求可能会将数据库击垮。
解决办法
添加互斥锁或分布式锁,让一个线程去访问数据库,将数据添加到缓存中后,其他线程直接从缓存中获取。
热点数据key不过期,定时更新缓存
缓存雪崩
指在系统运行过程中,缓存服务宕机或大量的key值同时过期,导致所有请求都直接访问数据库导致数据库压力增大
解决办法
将key的过期时间打散,避免大量key同时过期。
对缓存服务做高可用处理。
加互斥锁,同一key值只允许一个线程去访问数据库,其余线程等待写入后直接从缓存中获取。
缓存不一致
数据库中的数据和Redis缓存中的数据不一致的问题
出现原因:
缓存和数据库中都需要更新数据,对二者的操作无法保证原子性的情况下,就会出现不一致问题
解决办法:
- 重试机制:使用消息队列暂存要操作的数据,操作失败再从消息队列取回
- 延迟双删:先删除缓存数据 ->再执行update更新数据表 ->最后(延迟N秒)再删除缓存
Redis的优势
数据存在内存中,直接与内存相连,读写速度很快。
使用单线程模型,无多线程 竞争 锁 等问题
支持数据持久化
支持数据备份 master-slave模式数据备份(需要多个redis实例)
操作均为原子性的
Redis持久化
- AOF:采用日志的形式来记录每个写操作,追加到AOF文件的末尾(默认情况是不开启AOF)重启时再重新执行AOF文件中的命令来恢复数据(AOF是执行完命令后才记录日志的)
- RDB:把内存数据以快照的形式保存到磁盘上。RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作
Redis面对大量访问时的处理办法
Redis是单线程服务,所有指令都是顺序执行,当某一指令耗时很长时,就会阻塞后续的指令执行。当被积压的指令越来越多时,Redis服务占用CPU将不断升高,最终导致Redis实例崩溃甚至服务器宕机。
处理办法:
- 使用Redis连接池
- 批量操作,使用Redis管道机制
- 使用合适的数据结构和命令
- 使用Reids集群
Redis面对大量数据存储
- 数据分片,将数据存储到多个Redis节点上
- 使用合适的数据结构
- 合理设置过期时间
- 使用持久化机制
Redis键的设计
- 遵循基本格式:[业务名称]:[数据名]:[id]
长度不超过44字节 - 拒绝BigKey
- 恰当的数据格式
对象格式的数据可以采用json存储,但是更好的是采用hash格式存储 - 将集合类型中数据量大的进行拆分
Redis中各类型的底层结构
String:简单动态字符串
List:双向链表或压缩链表(ziplist)
- 双向链表:列表长度较长或包含较多元素
- 压缩链表:在一定程度上减少内存使用,存储在连续的内存区域中
Set:哈希表(Hash Table)和跳跃表(Skip List)
- 哈希表:集合元素较多或元素大。将集合的元素作为哈希表的键,值被设为固定的空值
- 跳跃表:有序的数据结构,支持快速查找、插入和删除(因此也被用于ZSet)
ZSet:使用跳跃表存储元素,使用哈希表存储 元素:分值
Hash:哈希表和压缩链表
- 哈希表:hash类型的字段数量较多,或字段大小较大时
- 压缩链表:字段的顺序是按照插入的先后顺序进行存储的
Elasticsearch
es的数据格式怎么规定的
通过mapping进行定义,可以查看我的相关文档 ElasticSearch 其中的mapping映射属性
为什么使用es
- 分布式实时文件存储,可将每一个字段存入索引,使其可以被检索到
- 实时分析的分布式搜索引擎
- 索引分拆成多个分片,每个分片可以有多个副本存储在不同的节点上,负载均衡等
- 可以扩展到上百台服务器
- 支持插件机制,分词插件、同步插件、Hadoop插件、可视化插件等
Docker
Docker镜像
Docker参考文章
Docker 容器的运行是基于宿主机的内核,通过linux的namespaces来实现隔离,相对于虚拟机而言降低了硬件资源的性能损耗,且具备一定程度上的应用隔离效果。
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
Java基础
Hash冲突的解决方式
- 链表法(HashMap)+ 红黑树(默认链表长度超过8)
- 再哈希法
- 开放定址法
- 建立公共溢出区
HashMap和CurrentHashMap的对比
HashMap线程不同步,底层使用链表和红黑树的方式处理冲突
CurrentHashMap:
- JDK 1.7 :使用segment数组,每个segment中存储一定量的HashEntry,HashEntry用链表处理冲突;线程安全通过锁被操作的segment
- JDK 1.8 :直接使用Node结点,使用Synchronized和CAS的方式实现线程安全
红黑树的特性,以及保持平衡的方式
- 每个结点不是红色就是黑色
- 根节点是黑色的
- 如果一个节点是红色的,则它的子结点必须是黑色的(没有连续的红色节点)
- 对于每个结点,从该结点到其所有可到达的叶结点的路径中,均包含相同数目的黑色结点
- 每个 NIL 叶子结点都是黑色的(此处的叶子结点指的是空结点)
保持平衡:
- 插入:
- 插入新节点涂红色
- 如果父节点为黑色不用操作
- 如果父节点为红色
- 父节点无兄弟节点或父节点的兄弟节点为黑色,直接旋转操作
- 父节点有兄弟结点,且兄弟结点也为黑色,直接上溢:将父节点和叔都涂为黑色,将祖父节点涂为红色,然后在上溢部分继续判断是否需要处理
- 删除:
- 删除结点都在B树的最后一层,可以理解为都在红黑树的最下面2层
- 删除最后一层的红色结点没有影响
- 删除最后一层的黑色节点:
- 如果黑色节点有2个子节点,不允许删除
- 如果黑色结点只有一个子节点,删除黑色结点,并用子节点取代该位置,同时染成黑色
- 如果黑色结点为叶子节点:
- 该节点没有兄弟节点(只能是根节点),直接删除
- 该节点的兄弟结点为黑色,旋转兄弟结点
- 该节点的兄弟结点为红色,旋转兄弟和父节点
线程
自定义线程池有哪些参数,分别是什么
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)
| 参数 | 参数意义 | 参数名称 | 参数要求 |
|---|---|---|---|
| 参数一 | 指定线程池的线程数量(核心线程) | corePoolSize | 不能小于0 |
| 参数二 | 指定线程池可支持的最大线程数 | maximumPoolSize | 最大数量 >= 核心线程数量 |
| 参数三 | 指定临时线程的最大存活时间 | keepAliveTime | 不能小于0 |
| 参数四 | 指定存活时间的单位(秒、分、时、天) | unit | 时间单位 |
| 参数五 | 指定任务队列 | workQueue | 不能为null |
| 参数六 | 指定用哪个线程工厂创建线程 | threadFactory | 不能为null |
| 参数七 | 指定线程忙,任务满的时候,新任务来了怎么办 | handler | 不能为null |
volitail关键字
保证了不同线程之间对共享变量操作的可见性
- 每个线程都能从主内存中获取volitail修饰的属性,并缓存在本地工作内存中
- 一旦有线程修改了该值,会自动刷新到主内存中,同时其他内存中的该值失效,再次访问需要重新到主内存中获取
禁止对指令进行重排序操作。
- 保证该指令前的所有指令都执行,该指令后的所有指令都未执行
锁
AQS
AQS ( Abstract Queued Synchronizer )是一个抽象的队列同步器,通过维护一个共享资源状态( Volatile Int State )和一个先进先出( FIFO )的线程等待队列来实现一个多线程访问共享资源的同步框架。
原理:
AQS 为每个共享资源都设置一个共享资源锁,线程在需要访问共享资源时首先需要获取共享资源锁,如果获取到了共享资源锁,便可以在当前线程中使用该共享资源,如果获取不到,则将该线程放入线程等待队列(先进先出),等待下一次资源调度
使用:
在使用AQS创建自定义锁时,AQS一般是被内部类去继承实现的。需要去重写几个方法:tryAcquire(int),tryRelease(int),tryAcquireShared(int),tryReleaseShared(int),isHeldExclusively()(最后一个方法一般在需要使用condition时才需要重写,即当某线程需要放到条件队列中,遇到某条件才唤醒时使用)
在使用时可以在tryAcquire(int)和tryRelease(int)中使用getState(),setState(int),compareAndSetState(int,int)去获取和改变AQS的状态码,AQS的状态码默认情况下是:0代表锁可用,1代表锁被占有;使用setExclusiveOwnerThread()设置独占资源的线程;因此可以在tryAcquire(int)获取状态码,为0的情况下置为1,并返回true,在tryRelease(int)将状态码置为0,完成锁的释放。在继承AQS类并重写完这些方法后,就可以调用其本身的acquire和release方法获取和释放锁了。
CAS如何实现
CAS:CompareAndSwep,其中包括几个参数:①对象本身②值的内存偏移地址③期望更新的值(旧值)④更新的值(新值),只有当目前的值和期望更新的值相同时,才会去完成更新操作,否则会自旋或者不操作。
但作为乐观锁,可能会遇到ABA问题,可用版本号和时间戳来解决
共享锁
mysql的行锁中的读锁即是共享锁。即:多个线程如果都对某一行数据发起读请求,就会尝试获取该行数据的共享锁,可由多个线程或事务获取到该共享锁,即读操作可同时发生。
与此相对的就是排他锁/互斥锁,一旦获取了一行数据的排他锁/互斥锁,其他事务或线程就不能获取该数据的任何锁;并且如某行数据被获取了共享锁,也不能再被获取排他锁/互斥锁。
读可共享-读写不共享-写写不共享
分布式锁
分布式锁用于解决分布式系统中控制共享资源的访问
Redis的分布式锁:
- 使用setnx添加锁(setnx保证原子性,且只有在key不存在时才能成功,即多个系统并发获取锁,也只有一个系统能成功获取到锁)
set <lock.key> <lock.value> nx ex <expireTime>同时用ex能设置过期时间 - 可使用del主动释放锁,即直接删除该键值对
- 可重入锁的实现方式:hash类型设置可重入锁,
HSETNX,然后通过获取其中的字段判断是否可重入,并且能够设置重入的次数。 - 使用Redission的看门狗机制或者自定义守护线程维护获取锁的业务的锁过期时间
ReentrantLock和Synchronized
| ReentrantLock | Synchronized | |
|---|---|---|
| 锁实现机制 | 依赖AQS | 监视器模式 |
| 灵活性 | 支持响应中断、超时、尝试获取锁 | 不灵活 |
| 释放形式 | 必须显式调用unlock() | 自动释放监视器 |
| 锁类型 | 公平锁&非公平锁 | 非公平锁 |
| 条件队列 | 可关联多个条件队列 | 关联一个条件队列 |
| 可重入性 | 可重入 | 可重入 |
JVM
JVM有哪些垃圾回收器
| 垃圾回收器 | 版本 | 适用范围 | 特点 | 算法 |
|---|---|---|---|---|
| Serial(串行收集器) | jdk1.1 | 新生代 | 只会使用一个CPU或者一条GC线程进行垃圾回收 并且在垃圾回收过程中暂停其他工作线程 | 标记-复制-清除 |
| ParNew | jdk1.3 | 新生代 | Serial的多线程版本 | 标记-复制-清除 |
| Parallel Scavenge | jdk1.4 | 新生代 | 追求CPU吞吐量的优化 能在较短的时间内完成指定的任务 | 标记-复制-清除 |
| Serial Old | jdk1.3 | 老年代 | 单线程 暂停应用程序执行 | 标记-整理 |
| Parallel Old | jdk1.5 | 老年代 | 多线程 和用户线程并发 | 标记-整理 |
| CMS(concurrent mark sweep) | jdk1.4 | 老年代 | 初始标记(停) 并发标记(运) 重新标记(运) 并发清除 | 标记-清除 |
| G1 | jdk1.7引入 jdk1.9默认 | 老年代 | 重新标记阶段停止业务线程 软实时 内存划分变为Region并评估每个region价值 首先清除垃圾最多的区域 | 标记-整理 |
类加载机制
java源码经过javac编译后形成class字节码文件,jvm将字节码文件加载进内存,经过字节码验证器验证,为类变量进行内存分配和初始化零值,字节码解释器解释执行字节码指令转换为底层机器代码并执行。
双亲委派
如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委派父类加载器去完成。每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个请求时,子加载器才会尝试自己去加载。
当发现在某一步该类已经被加载过时,会直接返回已加载的类,避免重复加载
反射
反射通过类加载器加载class字节码文件实现,可通过一个类的字节码获取该类的所有信息,包括属性、方法等
获取类对象:
Class<?> clazz = MyClass.class;通过类字面常量获取类对象Class<?> clazz = Class.forName("com.example.MyClass");通过Class.forName()方法获取MyClass object = new MyClass(); Class<?> clazz = obj.getClass();通过对象的getClass()获取Class<?> clazz = getClass().getClassLoader().loadClass("com.example.MyClass");
根据类对象生成对象实例:Object object = (Object)clazz.newInstance();
根据类对象获取属性和方法:
getFields():获取所有public的属性getDeclaredFields():获取所有(不限修饰符的)属性getType:以Class形式返回类型getName:返回属性名setAccessible(true):使用
getMethods():获取所有pubic的方法getDeclaredMethods():获取所有(不限修饰符的)方法getReturnType:以Class形式获取返回类型getName:返回方法名getParameterTypes:以Class[]返回参数类型数组invoke(obj, param1, ...):调用方法
getConstructors():获取所有public的构造方法getDeclaredConstructors():获取所有(不限修饰符的)构造方法getModifiers:以int形式返回修饰符.getName:返回构造器名(全类名).getParameterTypes:以Class[]返回参数类型数组
异常
异常的分类,以及有什么区别
Error(错误):是程序无法处理的错误,表示代码运行时JVM出现的问题。例如:OutOfMemoryError、NullPointerException
Exception(异常):是程序本身可以处理的异常。
- RuntimeException:运行时异常,不受检查异常,表示JVM常用操作引发的错误,编译时能通过,但会在后期代码的执行过程中暴露出来
- 其他异常:受检查异常,在编译时不能被忽略,程序必须对它有相应的处理
计算机网络
Https为什么安全
- 浏览器发起 HTTPS 请求
- 服务端返回 HTTPS 证书
- 客户端验证证书是否合法,如果不合法则提示告警
- 当证书验证合法后,在本地生成随机数
- 通过公钥加密随机数,并把加密后的随机数传输到服务端
- 服务端通过私钥对随机数进行解密
- 服务端通过客户端传入的随机数构造对称加密算法,对返回结果内容进行加密后传输
数据传输是用对称加密:非对称加密的加解密效率非常低
- https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
TCP拥塞控制
- 慢启动
- 最初拥塞控制窗口cwnd的初始值为一个小值,推荐为2个MSS(MSS通常为536字节或1460字节)
- MSS:Maximum Segment Size ,最大报文段长度,TCP提交给IP层最大分段大小
- 当收到一个ACK后,
cwnd = cwnd*2
- 最初拥塞控制窗口cwnd的初始值为一个小值,推荐为2个MSS(MSS通常为536字节或1460字节)
- 拥塞避免
- 拥塞窗口cwnd值等于慢开始门限值后,
cwnd = cwnd+1
- 拥塞窗口cwnd值等于慢开始门限值后,
- 快速恢复
- 拥塞时,将慢开始门限修改为cwnd/2,并且将
cwnd = cwnd/2
- 拥塞时,将慢开始门限修改为cwnd/2,并且将
- 快速重传
- 连续收到3条对某报文段的重传确认,就需要快速重传该报文段
地址框输入url后经历了什么
- DNS解析
- 在自己的DNS高速缓存中查找
- 权限域名服务器->顶级域名服务器->根域名服务器
- TCP连接
- TCP三次握手
- 发送HTTP请求
- 服务端处理请求:根据路径查找对应的资源(服务),然后返回数据报
- 浏览器收到返回的数据,进行渲染,形成页面
- TCP断开
- 四次挥手
场景问题
流量大对服务的影响
数据有效期为半年
30分钟延迟任务
秒杀系统
熔断 服务降级
在线笔试
lc33.旋转数组
题目:搜索一个 升序的 后经旋转后 的数组中 目标数的下标
思路:二分查找
示例代码:
class Solution {public int search(int[] nums, int target) {int n = nums.length;if (n == 0) {return -1;}if (n == 1) {return nums[0] == target ? 0 : -1;}int l = 0, r = n - 1;while (l <= r) {int mid = (l + r) / 2;if (nums[mid] == target) {return mid;}if (nums[0] <= nums[mid]) {if (nums[0] <= target && target < nums[mid]) {r = mid - 1;} else {l = mid + 1;}} else {if (nums[mid] < target && target <= nums[n - 1]) {l = mid + 1;} else {r = mid - 1;}}}return -1;}
}作者:力扣官方题解
链接:https://leetcode.cn/problems/search-in-rotated-sorted-array/solutions/220083/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/
来源:力扣(LeetCode)
回文子串
回文子串:一个字符串的子串,如果它是回文的,则这是一个回文子串
思路:可使用动态规划算法,找出回文子串的个数或者最长回文子串
lc854.最长山脉数组
题目:山脉数组指一个数组中存在一个中间位置的元素a[i],0--i单增,i~len-1单减;给一个数组arr,从中找到最长山脉子数组
思路:遍历枚举就行
示例代码:
class Solution {public int longestMountain(int[] arr) {int n = arr.length;int ans = 0;int left = 0;while (left + 2 < n) {int right = left + 1;if (arr[left] < arr[left + 1]) {while (right + 1 < n && arr[right] < arr[right + 1]) {++right;}if (right < n - 1 && arr[right] > arr[right + 1]) {while (right + 1 < n && arr[right] > arr[right + 1]) {++right;}ans = Math.max(ans, right - left + 1);} else {++right;}}left = right;}return ans;}
}作者:力扣官方题解
链接:https://leetcode.cn/problems/longest-mountain-in-array/solutions/459406/shu-zu-zhong-de-zui-chang-shan-mai-by-leetcode-sol/
来源:力扣(LeetCode)
lc54.螺旋矩阵
题目:按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例代码:
class Solution {public List<Integer> spiralOrder(int[][] matrix) {//使用四个值去记录边界int left = -1;int right = matrix[0].length - 1;int up = 0;int down = matrix.length;//使用两个值去记录方向int x = 0;int y = 1;//使用一个值去判断下次转向的条件int flag = 1;//使用两个值去记录位置int i = 0, j = 0;//计数停止int count = 0;int sum = (right + 1) * down;List<Integer> list = new LinkedList<>();while (count < sum) {list.add(matrix[i][j]);count++;switch(flag){case 0:{if(i==up&&j==left){x=0;y=1;flag=1;right--;}break;}case 1:{if(i==up&&j==right){x=1;y=0;flag=2;down--;}break;}case 2:{if(i==down&&j==right){x=0;y=-1;flag=3;left++;}break;}case 3:{if(i==down&&j==left){x=-1;y=0;flag=0;up++;}break;}default:{break;}}i+=x;j+=y;}return list;}
}
lc23.合并k个升序链表
相关文章:
秋招面经——结合各方面试经验
Mysql mysql事务 共享锁与排他锁 共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。(读都允许读,但我在读不允许你去改) 排他锁:允许一个事务去读一行,阻止其他事务获得相同…...
Python random模块用法整理
随机数在计算机科学领域扮演着重要的角色,用于模拟真实世界的随机性、数据生成、密码学等多个领域。Python 中的 random 模块提供了丰富的随机数生成功能,本文整理了 random 模块的使用。 文章目录 Python random 模块注意事项Python random 模块的内置…...
【Redis从头学-5】Redis中的List数据类型实战场景之天猫热销榜单
🧑💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:Re…...
基于Python的HTTP代理爬虫开发初探
前言 随着互联网的发展,爬虫技术已经成为了信息采集、数据分析的重要手段。然而在进行爬虫开发的过程中,由于个人或机构的目的不同,也会面临一些访问限制或者防护措施。这时候,使用HTTP代理爬虫可以有效地解决这些问题࿰…...
时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测
时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测预测效果基本介绍模型描述程序设计学习总结参考资料 预测效果 基本介绍 时序预测 | MATLAB实现WOA-…...
每日一题之二进制中1的个数
二进制中1的个数 问题描述: 输入一个整数 n ,输出该数 32 位二进制表示中 1 的个数。其中负数用补码表示。 科普一下有符号数的三种表示:原码、反码和补码,可能有时候遗忘了。 真值:带有符号位的机器数(一…...
8.17校招 内推 面经
绿泡泡: neituijunsir 交流裙,内推/实习/校招汇总表格 1、校招 | 腾讯2024校园招聘全面启动(内推) 校招 | 腾讯2024校园招聘全面启动(内推) 2、校招 | 大华股份2024届全球校园招聘正式启动(内推) 校招 | 大华股份2024届全球校园招聘正式启动(内推) …...
VScode搭建Opencv(C++开发环境)
VScode配置Opencv 一、 软件版本二 、下载软件2.1 MinGw下载2.2 Cmake下载2.3 Opencv下载 三、编译3.1 cmake-gui3.2 make3.3 install 四、 VScode配置4.1 launch.json4.2 c_cpp_properties.json4.3 tasks.json 五、测试 一、 软件版本 cmake :cmake-3.27.2-windows-x86_64 Mi…...
Redis高可用:哨兵机制(Redis Sentinel)详解
目录 1.什么是哨兵机制(Redis Sentinel) 2.哨兵机制基本流程 3.哨兵获取主从服务器信息 4.多个哨兵进行通信 5.主观下线和客观下线 6.哨兵集群的选举 7.新主库的选出 8.故障的转移 9.基于pub/sub机制的客户端事件通知 1.什么是哨兵机制…...
Hadoop小结(上)
最近在学大模型的分布式训练和存储,自己的分布式相关基础比较薄弱,基于深度学习的一切架构皆来源于传统,我总结了之前大数据的分布式解决方案即Hadoop: Why Hadoop Hadoop 的作用非常简单,就是在多计算机集群环境中营…...
ORA-600 ksuloget2 恢复----惜分飞
客户在win 32位的操作系统上调至sga超过2G,数据库运行过程中报ORA-600 ksuloget2错误 Thread 1 cannot allocate new log, sequence 43586 Checkpoint not complete Current log# 1 seq# 43585 mem# 0: D:\ORACLE\ORADATA\ORCL\REDO01.LOG Fri Aug 04 14:57:02 2023 Errors i…...
NLP的tokenization
GPT3.5的tokenization流程如上图所示,以下是chatGPT对BPE算法的解释: BPE(Byte Pair Encoding)编码算法是一种基于统计的无监督分词方法,用于将文本分解为子词单元。它的原理如下: 1. 初始化:将…...
【宝藏系列】一文讲透C语言数组与指针的关系
【宝藏系列】嵌入式 C 语言代码优化技巧【超详细版】 文章目录 【宝藏系列】嵌入式 C 语言代码优化技巧【超详细版】👨🏫前言1️⃣指针1️⃣1️⃣指针的操作1️⃣2️⃣关于指针定义的争议1️⃣3️⃣对教材错误写法的小看法 2️⃣指针和数组的区别2️⃣…...
Jenkins+Jmeter集成自动化接口测试并通过邮件发送测试报告
一、Jenkins的配置 1、新增一个自由风格的项目 2、构建->选择Excute Windows batch command(因为我是在本地尝试的,因此选择的windows) 3、输入步骤: 1. 由于不能拥有相同的jtl文件,因此在每次构建前都需要删除jtl…...
clickhouse入门
clickhouse 1 课程介绍 和hadoop无关,俄罗斯,速度快3 介绍&特点 1 列式存储 在线分析处理。 使用sql进行查询。列式存储更适合查询分析的场景。新增时候有一个寻址的过程。更容易进行压缩行式存储。增删改查都需要的时候。2 DBMS功能 包括ddl,d…...
中间件: ElasticSearch的安装与部署
文档地址: https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html 单机部署 创建用户: useradd es chown -R es /opt/soft/ mkdir -p /var/log/elastic chown -R es /var/log/elastic mkdir -p /tmp/elastic chown -R es /tmp…...
LabVIEW模拟化学反应器的工作
LabVIEW模拟化学反应器的工作 近年来,化学反应器在化学和工业过程领域有许多应用。高价值产品是通过混合产品,化学反应,蒸馏和结晶等多种工业过程转换原材料制成的。化学反应器通常用于大型加工行业,例如酿酒厂公司饮料产品的发酵…...
Python基础语法入门(第二十三天)——正则表达式
正则表达式是一种文本模式,用于匹配字符串,它是由字符和特殊字符组成的模式。正则表达式可以用于验证、搜索、替换和提取字符串。其能够应用于各种编程语言和文本处理工具中,如Python、Java、JavaScript等。 正则表达式在线测试工具…...
山西电力市场日前价格预测【2023-08-20】
日前价格预测 预测明日(2023-08-20)山西电力市场全天平均日前电价为341.71元/MWh。其中,最高日前电价为367.66元/MWh,预计出现在20: 30。最低日前电价为318.47元/MWh,预计出现在04: 15。 价差方向预测 1: 实…...
C++中function,bind,lambda
c11之前,STL中提供了bind1st以及bind2nd绑定器 首先来看一下他们如何使用: 如果我们要对vector中的元素排序,首先会想到sort,比如: void output(const vector<int> &vec) {for (auto v : vec) {cout <&l…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
