1、Kafka 是什么?主要应用场景有哪些?

Kafka 是一个分布式流式处理平台。这到底是什么意思呢?

流平台具有三个关键功能:

◆ 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。

◆ 容错的持久方式存储记录消息流: Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险。

◆ 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。

Kafka 主要有两大应用场景:

◆ 消息队列 :建立实时流数据管道,以可靠地在系统或应用程序之间获取数据。

◆ 数据处理: 构建实时的流数据处理程序来转换或处理数据流。

2、kafka 为什么有 topic 还要用 patition?

◆ Kafka 可以将主题划分为多个分区(Partition),会根据分区规则选择把消息存储到哪个分区中,只要分区规则设置的合理,那么所有的消息将会被均匀的分布到不同的分区中,这样就实现了负载均衡和水平扩展。另外,多个订阅者可以从一个或者多个分区中同时消费数据,以支撑海量数据处理能力。

◆ producer 只需要关心消息发往哪个 topic,而 consumer 只关心自己订阅哪个 topic, 并不关心每条消息存于整个集群的哪个 broker。 为了性能考虑,如果 topic 内的消息只存于一个 broker,那这个 broker 会成为瓶颈,无法做到水平扩展。所以把 topic 内的数据分布到整个集群就是一个自然而然的设计方式。

◆ Partition 的引入就是解决水平扩展问题的一个方案。

3、客户端和服务器之间最多能建立多少个连接 ?

服务器的 ip ,端口号 ,客户端的 ip 都是确定的。 能变的只有客户端的端口号。加网卡 ,保证四元组唯一,理论上能是客户端和服务器之间建立 10 万以上的连接 。

4、HashMap 结构,线程不安全举个例子?

◆ 多个线程同时操作一个 hashmap 就可能出现不安全的情况。

◆ 如果两个线程同时遇到 HashMap 的大小达到 12 的倍数时,就很有可能会出现在将oldTable 转移到 newTable 的过程中遇到问题,从而导致最终的 HashMap 的值存储异常。

◆ 构造 entry<K,V>单链表时,也会出现不安全的情况。

5、MySQL 索引分类?

单列索引

◆ 普通索引:MySQL 中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值

和空值,纯粹为了查询数据更快一点。

◆ 唯一索引:索引列中的值必须是唯一的,但是允许为空值,

◆ 主键索引:是一种特殊的唯一索引,不允许有空值。

组合索引:

多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合。

全文索引:

只有在 MyISAM 引擎上才能使用,只能在 CHAR,VARCHAR,TEXT 类型字段上使用全文索引,介绍了要求,说说什么是全文索引,就是在一堆文字中,通过其中的某个关键字等,就能找到该字段所属的记录行,比如有"你是个靓仔,靓女 ..." 通过靓仔,可能就可以找到该条记录

空间索引:

空间索引是对空间数据类型的字段建立的索引,MySQL 中的空间数据类型有四种,GEOMETRY、POINT、LINESTRING、POLYGON。在创建空间索引时,使用 SPATIAL 关键字。要求,引擎为 MyISAM,创建空间索引的列,必须将其声明为 NOT NULL。

6、了解线程 & 进程的区别吗?

操作系统中可以拥有多个进程,一个进程里可以拥有多个线程,线程在进程内执行,进程和线程的区别

◆ 容易创建新线程。创建新进程需要重复父进程

◆ 线程可以控制同一进程的其他线程。进程无法控制兄弟进程,只能控制其子进程

◆ 进程拥有自己的内存空间。线程使用进程的内存空间,且要和该进程的其他线程共享这个空间;而不是在进程中给每个线程单独划分一点空间。

◆(同一进程中的)线程在共享内存空间中运行,而进程在不同的内存空间中运行

◆线程可以使用 wait(),notify(),notifyAll(),volatile 等方法直接与其他线程(同一进程)通信;而进程需要使用“进程间通信”(IPC)来与操作系统中的其他进程通信。

7、Java 进程间的几种通信方式?

◆ 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

◆ 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

◆ 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

◆ 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

◆ 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

◆ 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

◆ 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

8、多台服务器同时对一个数据定时任务,怎么处理 ?

对于一个定时任务,如果当前任务已经被某一个服务器处理后,另外一个服务器就不需要执行这个任务了

◆ 在定时任务里加锁机制,等某台服务器获取权限,其他服务器将不再执行此次定时任务。

◆ 在数据库的创建定时任务控制表 job_controller,创建 updated_by 字段,用来存放执行代码的服务器生成的序列号。创建 updateTime 字段,用于记录标记更新 update_by的时间戳,也可以理解为上一次任务执行的时间戳。

◆ 在代码层面,在执行任务的时候,首先生成一个序列号,然后将序列号存储在当前任务的记录上。然后再从数据库里查询当前记录的序列号,在做标记前,首先检查当前任务的上一次执行时间离当前时间超过阈值(自己定义),如果超过则表明还没有其他节点执行该任务,然后为 task 保存标签和当前运行时间。当然如果上一次运行时间为空的情况下,也是允许标记的,如果数据库中的序列号与当前节点生成序列号相匹配,则执行任务的具体逻辑,反之,则什么都不做处理。

9、常见分布式锁的几种实现方式?

◆ 基于数据库实现分布式锁

◆ 基于缓存实现分布式锁

◆ 基于 Zookeeper 实现分布式锁

10、Redis 分布式锁实现原理?

◆ set px nx

◆ 守护线程,进行 renew

◆ Redis 分布式锁实现: 先拿 setnx 来争抢锁,抢到之后,再用 expire(过期)给锁加一个过期时间防止锁忘记了释放。

◆ 如果在 setnx 之后执行 expire 之前进程意外 crash 或者要重启维护了,那会怎么样:

set 指令有非常复杂的参数,这个应该是可以同时把 setnx 和 expire 合成一条指令来用的!

11、Redis 的数据类型及它们的使用场景?

string

◆ key/value; 二进制安全的。意思是 redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象 。一个键最大能存储 512MB。

hash

◆ 存储对象数据

list : 简单的字符串列表

关注列表

◆ 队列

set: string 类型的无序集合

共同关注列表

◆ 统计独立 IP

zset : (sorted set:有序集合),每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

排行

◆ 带权重的消息队列

12、信号量与信号的区别?

◆ 信号:(signal)是一种处理异步事件的方式。信号是比较复杂的通信方式,用于通知接

受进程有某种事件发生,除了用于进程外,还可以发送信号给进程本身。

◆ 信号量:(Semaphore)进程间通信处理同步互斥的机制。是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

简单地说,信号就是一种异步通信,通知进程某种事件的发生;信号量是进程/线程同步与互斥的一种机制,保证进程/线程间之间的有序执行或对公共资源的有序访问。

13、select 和 epoll 的底层结构是什么原理

select:支持阻塞操作的设备驱动通常会实现一组自身的等待队列如读/写等待队列用于支持

上层(用户层)所需的 BLOCK 或 NONBLOCK 操作。当应用程序通过设备驱动访问该设备时

(默认为 BLOCK 操作),若该设备当前没有数据可读或写,则将该用户进程插入到该设备驱动对应的读/写等待队列让其睡眠一段时间,等到有数据可读/写时再将该进程唤醒。

select 就是巧妙的利用等待队列机制让用户进程适当在没有资源可读/写时睡眠,有资源可读/写时唤醒。

epoll:epoll 由三个系统调用组成,分别是 epoll_create,epoll_ctl 和 epoll_wait。

epoll_create 用于创建和初始化一些内部使用的数据结构;epoll_ctl 用于添加,删除或者修改指定的 fd 及其期待的事件,epoll_wait 就是用于等待任何先前指定的 fd 事件。

14、场景题:1 亿个数据取出最大前 100 个有什么方法?

◆ 最容易想到的方法是将数据全部排序,然后在排序后的集合中进行查找,最快的排序算法的时间复杂度一般为 O(nlogn),如快速排序。

◆ 局部淘汰法,该方法与排序方法类似,用一个容器保存前 10000 个数,然后将剩余的所有数字——与容器内的最小数字相比,如果所有后续的元素都比容器内的 10000 个数还小,那么容器内这个 10000 个数就是最大 10000 个数。如果某一后续元素比容器内最小数字大,则删掉容器内最小元素,并将该元素插入容器,最后遍历完这 1 亿个数,得到的结果容器中保存的数即为最终结果了。此时的时间复杂度为 O(n+m^2),其中 m为容器的大小,即 10000。

◆ 分治法,将 1 亿个数据分成 100 份,每份 100 万个数据,找到每份数据中最大的10000 个,最后在剩下的 10010000 个数据里面找出最大的 10000 个。如果 100万数据选择足够理想,那么可以过滤掉 1 亿数据里面 99%的数据。100 万个数据里面查找最大的 10000 个数据的方法如下:用快速排序的方法,将数据分为 2 堆,如果大的那堆个数 N 大于 10000 个,继续对大堆快速排序一次分成 2 堆,如果大的那堆个数 N 大于 10000 个,继续对大堆快速排序一次分成 2 堆,如果大堆个数 N 小于10000 个,就在小的那堆里面快速排序一次,找第 10000-n 大的数字;递归以上过程,就可以找到第 1w 大的数。参考上面的找出第 1w 大数字,就可以类似的方法找到前10000 大数字了。此种方法需要每次的内存空间为 10^64=4MB,一共需要 101 次这样的比较。

◆ Hash 法,如果这 1 亿个数里面有很多重复的数,先通过 Hash 法,把这 1 亿个数字去重复,这样如果重复率很高的话,会减少很大的内存用量,从而缩小运算空间,然后通过分治法或最小堆法查找最大的 10000 个数。

◆ 采用最小堆法,首先读入前 10000 个数来创建大小为 10000 的最小堆,建堆的时间复杂度为 O(mlogm)(m 为数组的大小即为 10000),然后遍历后续的数字,并于堆顶(最小)数字进行比较。如果比最小的数小,则继续读取后续数字;如果比堆顶数字大,则替换堆顶元素并重新调整堆为最小堆。整个过程直至 1 亿个数全部遍历完为止。然后按照中序遍历的方式输出当前堆中的所有 10000 个数字。该算法的时间复杂度为 O(nmlogm),空间复杂度是 10000(常数)。

15、kafka 如何保证消息可靠?

生产者丢失消息的情况

生产者(Producer) 调用 send 方法发送消息之后,消息可能因为网络问题并没有发送过去。

为了确定消息是发送成功,我们要判断消息发送的结果,Kafka 生产者(Producer) 使用send 方法发送消息实际上是异步的操作,我们可以通过 get()方法获取调用结果,但是这样也让它变为了同步操作,可以采用为其添加回调函数的形式,示例代码如下:

ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, o);

future.addCallback(result -> logger.info("生产者成功发送消息到 topic:{} partition:{}的消息",

result.getRecordMetadata().topic(), result.getRecordMetadata().partition()),

ex -> logger.error("生产者发送消失败,原因:{}", ex.getMessage()));

Producer 的 retries(重试次数)设置一个比较合理的值,一般是 3 ,但是为了保证消息不丢失的话一般会设置比较大一点。设置完成之后,当出现网络问题之后能够自动重试消息发送,避免消息丢失。另外,建议还要设置重试间隔,因为间隔太小的话重试的效果就不明显了,网络波动一次你 3 次一下子就重试完了消费者丢失消息的情况 ,消费者拉取到了分区的某个消息之后,消费者会自动提交了 offset。自动提交的话会有一个问题,试想一下,当消费者刚拿到这个消息准备进行真正消费的时候,突然挂掉了,消息实际上并没有被消费,但是 offset 却被自动提交了。

解决办法也比较粗暴,我们手动关闭自动提交 offset,每次在真正消费完消息之后再自己手动提交 offset 。 但是,细心的朋友一定会发现,这样会带来消息被重新消费的问题。比如你刚刚消费完消息之后,还没提交 offset,结果自己挂掉了,那么这个消息理论上就会被消费两次。

Kafka 弄丢了消息

试想一种情况:假如 leader 副本所在的 broker 突然挂掉,那么就要从 follower 副本重新选出一个 leader ,但是 leader 的数据还有一些没有被 follower 副本的同步的话,就会造成消息丢失。

当我们配置了 unclean.leader.election.enable = false 的话,当 leader 副本发生故障时就不会从 follower 副本中和 leader 同步程度达不到要求的副本中选择出 leader ,这样降低了消息丢失的可能性。

16、消息队列的使用场景?

消息队列在实际应用中包括如下四个场景:

◆ 应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;

◆ 异步处理:多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;

◆ 限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;

◆ 消息驱动的系统:系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理;

17、乐观锁和悲观锁的理解及如何实现,有哪些实现方式?

悲观锁:

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如 Java 里面的同步原语 synchronized 关键字的实现也是悲观锁。

乐观锁:

顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于 write_condition 机制,其实都是提供的乐观锁。在 Java 中 java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的。

18、ArrayList 和 LinkedList 的区别在哪里?

◆ 数据结构实现:ArrayList :基于数组,便于按 index 访问,超过数组需要扩容,扩容成本较高。LinkedList:使用链表实现,无需扩容。

◆ 随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。

◆ 增加和删除效率:在非首尾的增删操作,LinkedList 要比 ArrayList 效率要高,因为ArrayList 增删操作要影响数组内的其他数据的下标。

◆ 内存空间占用:LinkedList 比 ArrayList 更占内存,因为 LinkedList 的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。

◆ 线程安全:ArrayList 和 LinkList 都是不同步的,不保证线程安全。

◆ 综合来说,需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在增删操作较多时,更推荐使用 LinkedList。

◆ LinkedList 的双向链表是链表的一种,它的每个数据结点中都有 2 个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便的访问它的前驱结点和后继结点。

19、谈谈你对 SQL 注入式攻击的理解?

所谓 SQL 注入式攻击,就是攻击者把 SQL 命令插入到 Web 表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的 SQL 命令

如何防范 SQL 注入式攻击?

在利用表单输入的内容构造 SQL 命令之前,把所有输入内容过滤一番就可以了。过滤输入内容可以按多种方式进行。

◆ 对于动态构造 SQL 查询的场合

a. 替换单引号,即把所有单独出现的单引号改成两个单引号,防止攻击者修改 SQL 命令的含义。

b. 删除用户输入内容中的所有连字符

c. 对于用来执行查询的数据库帐户,限制其权限用不同的用户帐户执行查询、插入、更新、删除操作。

d.采用预编译技术

◆ 限制表单或查询字符串输入的长度。

◆ 检查用户输入的合法性。

◆ 将用户登录名称、密码等数据加密保存。

◆ 检查提取数据的查询所返回的记录数量。

20、数据库事务的特性?

◆ 原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。

◆ 一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态

◆ 隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务。

◆ 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。

21、Redis 如何做内存优化?

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的 key,而是应该把这个用户的所有信息存储到一张散列表里面.

22、缓存穿透,缓存击穿,缓存雪崩都是咋回事?解决办法?

缓存穿透

◆ 问题:大量并发查询不存在的 KEY,在缓存和数据库中都不存在,同时给缓存和数据库

带来压力。

◆ 原因:一般而言,缓存穿透有 2 种可能性:业务数据被误删,导致缓存和数据库中都没

有数据。恶意进行 ddos 攻击。

◆ 分析:为什么会多次透传呢?不存在 一直为空,需要注意让缓存能够区分 KEY 不存在和查询到一个空值。

◆ 解决办法:缓存空值的 KEY,这样第一次不存在也会被加载会记录,下次拿到有这个

KEY。Bloom 过滤或 RoaingBitmap 判断 KEY 是否存在,如果布隆过滤器中没有查到

这个数据,就不去数据库中查。在处理请求前增加恶意请求检查,如果检测到是恶意攻击,

则拒绝进行服务。完全以缓存为准,使用延迟异步加载的策略(异步线程负责维护缓存的

数据,定期或根据条件触发更新),这样就不会触发更新。

缓存击穿

◆ 问题:某个 KEY 失效的时候,正好有大量并发请求访问这个 KEY。

◆ 分析:跟穿透其实很像,属于比较偶然的。

◆ 解决办法:KEY 的更新操作添加全局互斥锁。完全以缓存为准,使用延迟异步加载的策略(异步线程负责维护缓存的数据,定期或根据条件触发更新),这样就不会触发更新。

缓存雪崩

◆ 问题:当某一时刻发生大规模的缓存失效的情况,导致大量的请求无法获取数据,从而将流量压力传导到数据库上,导致数据库压力过大甚至宕机。

◆ 原因:一般而言,缓存雪崩有 2 种可能性:大量的数据同一个时间失效:比如业务关系强相关的数据要求同时失效 Redis 宕机

◆ 分析:一般来说,由于更新策略、或者数据热点、缓存服务宕机等原因,可能会导致缓存

数据同一个时间点大规模不可用,或者都更新。所以,需要我们的更新策略要在时间上合适,数据要均匀分享,缓存服务器要多台高可用。

◆ 解决办法:更新策略在时间上做到比较平均。如果数据需要同一时间失效,可以给这批数据加上一些随机值,使得这批数据不要在同一个时间过期,降低数据库的压力。使用的热数据尽量分散到不同的机器上。多台机器做主从复制或者多副本,实现高可用。做好主从的部署,当主节点挂掉后,能快速的使用从结点顶上。实现熔断限流机制,对系统进行负载能力控制。对于非核心功能的业务,拒绝其请求,只允许核心功能业务访问数据库获取数据。服务降价:提供默认返回值,或简单的提示信息。

23、数组和链表的区别?当数组内存过大时会出现什么问题?链表增删过多会出现的什么问题?

◆ 数组静态分配内存,链表动态分配内存;

◆ 数组事先定义固定的长度,不能适应数据动态的增减的情况。当数据增加时,可能超出原

先定义的元素个数;当数据减少时,造成内存浪费;

◆ 链表动态地进行存储分配,可以适应数据动态地增减的情况

◆ 数组在内存中连续,链表不连续;

◆ 数组元素在栈区,链表元素在堆区;

◆(静态)数组从栈中分配空间,对于程序员方便快速,但是自由度小;

◆ 链表从堆中分配空间,自由度大但是申请管理比较麻烦。

◆ 数组利用下标定位,时间复杂度为 O(1),链表定位元素时间复杂度 O(n);

◆ 数组插入或删除元素的时间复杂度 O(n),链表的时间复杂度 O(1)。

◆ 当数组内存过大时会出现什么问题(堆内存溢出),链表增删过多会出现的什么问题(大

量内存碎片)

24、常见排序算法和分别的复杂度?

◆ 冒泡排序,O(n2),通过重复走完数组的所有元素,通过两两比较,直到没有数可以交换的时候结束这个数,再到下个数,直到整个数组排好顺序。

◆ 插入排序,O(n2),每次从未排好序的数据堆中拿出一个数,插入到已排好序的数据队列 的正确位置。

◆ 选择排序,O(n2),每次从未排好序的数据堆中找到最小的数,插入到已排好序的数据队列的头部。

◆ 快速排序,O(N*logN),以数据堆中的一个数为标准,将数据堆分为小于等于和大于该数的两堆,对于分割后的两堆数再分别利用上述方法进行分割,以此类推,直到堆中只有一个数为止。

◆ 堆排序,O(N*logN),将数据堆中的数两两组队排序,对于排序好的这些子堆再两两组队排序,以此类推,直到只剩下一个堆。

◆ 归并排序,O(N*logN),基于堆的排序算法,分为最大堆和最小堆。排序分为两个过程堆的构造和堆的排序。

25、

jdk 1.8 的 JVM 内存划分模型 ,堆和栈的区别

◆ 方法区(method):被所有的线程共享。方法区包含所有的类信息和静态变量。(运行时常量池)

◆ 堆(heap):被所有的线程共享,存放对象实例以及数组,Java 堆是 GC 的主要区域。

◆ 栈(stack):每个线程包含一个栈区,栈中保存一些局部变量等。(本地局部变量、操作数

栈、动态链接、返回地址)

◆ 程序计数器:是当前线程执行的字节码的行指示器。

◆ 本地方法栈

26、简单描述 MySQL 中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)?

◆ 索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。

◆ 普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的访问速度。

◆ 普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相

同的值,在为这个数据列创建索引的时候就应该用关键字 UNIQUE 把它定义为一个唯一索引。也就是说,唯一索引可以保证数据记录的唯一性。

◆ 主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字 PRIMARY KEY 来创建。

◆ 索引可以覆盖多个数据列,如像 INDEX(columnA, columnB)索引,这就是联合索引。

◆ 索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执

行这些写操作时,还要操作索引文件。

27、I/O 模型有哪几种?

阻塞 I/O, 非阻塞 I/O 模型,I/O 复用模型,信号驱动 I/O 模型 ,异步 I/O 模型。

28、当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤?

域名解析–> 发起 TCP 的 3 次握手 –> 建立 TCP 连接后发起 http 请求 –> 服务器响应http 请求–>浏览器得到 html 代码 –> 浏览器解析 html 代码,并请求 html 代码中的资

源(如 js、css、图片等) –> 浏览器对页面进行渲染呈现给用户 。

29、虚拟 DOM 的优劣如何?

优点:

◆ 保证性能下限: 虚拟 DOM 可以经过 diff 找出最小差异,然后批量进行 patch,这种操作虽然比不上手动优化,但是比起粗暴的 DOM 操作性能要好很多,因此虚拟 DOM 可以保证性能下限

@无需手动操作 DOM: 虚拟 DOM 的 diff 和 patch 都是在一次更新中自动进行的,我们无需手动操作 DOM,极大提高开发效率

◆ 跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟DOM 可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等

缺点:

无法进行极致优化: 在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化,比如 VScode 采用直接手动操作 DOM 的方式进行极端的性能优化。

30、幻读是什么,用什么隔离级别可以防止幻读?

幻读是一个事务在前后两次查询同一个范围的时候、后一次查询看到了前一次查询未看到的行。

在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在“当前读”下才会出现。

SERIALIZABLE(可串行化)可以防止幻读:最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。

鹅厂java面试真题汇总相关推荐

  1. 百度统计 java 实现思路_2019社招阿里、腾讯、蚂蚁金服「四面」Java面试真题分享...

    在过去很长一段时间内,国内互联网一直处于三足鼎立状态,BAT即百度.阿里巴巴.腾讯.而在最新的互联网企业价值榜上,百度却被蚂蚁金服挤出前三的位置. 能够进一线互联网公司,是大部分程序员奋斗的目标,有很 ...

  2. 2021大厂Java面试真题(一)

    2021大厂Java面试真题(一) 大厂面试的基本流程 以下是一些大厂面试的基本流程,大家可以参考下: 字节跳动 阿里 腾讯 网易游戏 面试前需要准备: \1. **Java 八股文:**了解常考的题 ...

  3. 精选 2021 年大厂高频 Java 面试真题集锦(含答案),面试一路开挂

    本文涵盖了阿里巴巴.腾讯.字节跳动.京东.华为等大厂的 Java 面试真题,不管你是要面试大厂还是普通的互联网公司,这些面试题对你肯定是有帮助的,毕竟大厂一定是行业的发展方向标杆,很多公司的面试官同样 ...

  4. 精选2022年大厂高频Java面试真题集锦(含答案),面试一路开挂

    本文涵盖了阿里巴巴.腾讯.字节跳动.京东.华为等大厂的Java面试真题,不管你是要面试大厂还是普通的互联网公司,这些面试题对你肯定是有帮助的,毕竟大厂一定是行业的发展方向标杆,很多公司的面试官同样会研 ...

  5. 运维经典面试真题汇总系列

    运维经典面试真题汇总系列 如何判断 mysql 主从是否同步?该如何使其同步?** Slave_IO_Running Slave_SQL_Running: 略 2. mysql 的 innodb 如何 ...

  6. 2021大厂Java面试真题(二)

    2021大厂Java面试真题(二) 2021 [阿里]面试真题: 1.TCP 和 UDP 区别? TCP 基于连接,UDP 基于无连接. TCP 要求系统资源较多,UDP 较少. UDP 程序结构较简 ...

  7. 2020社招阿里、腾讯、蚂蚁金服「四面」Java面试真题分享

    在过去很长一段时间内,国内互联网一直处于三足鼎立状态,BAT即百度.阿里巴巴.腾讯.而在最新的互联网企业价值榜上,百度却被蚂蚁金服挤出前三的位置. 能够进一线互联网公司,是大部分程序员奋斗的目标,有很 ...

  8. 2019社招阿里、腾讯、蚂蚁金服Java面试真题

    在过去很长一段时间内,国内互联网一直处于三足鼎立状态,BAT即百度.阿里巴巴.腾讯.而在最新的互联网企业价值榜上,百度却被蚂蚁金服挤出前三的位置. 能够进一线互联网公司,是大部分程序员奋斗的目标,有很 ...

  9. 2021大厂Java面试真题(六)

    2021大厂Java面试真题(六) * * 2021 [华为]面试真题* * : * * 1.Java 常用集合及特点?* * List:ArrayList.LinkedList.Vector.Sta ...

  10. Java后端开发-大厂校招面试真题汇总【语雀图灵周瑜CSDN】

    BLOG内相关链接 & 积累常用对比等 Java实现快速排序算法 - yub4by - 博客园 (cnblogs.com) 三大类设计模式.Spring中用到的设计模式 - yub4by - ...

最新文章

  1. g-gdb工具使用图谱(持续更新)
  2. list存入mysql乱序_MySQL案例-并行复制乱序提交引起的同步异常
  3. 使用isql连接Sybase ASE数据库的常见错误及处理方式
  4. FuncT,TResult的使用方法(转载)
  5. RocketMQ-初体验RocketMQ(08)-IDEA拉取调测RocketMQ源码
  6. 广州技术沙龙第 4 期报名开始!
  7. CodeForces - 468B Two Sets(并查集+思维)
  8. 如何多人共同编辑_如何实现可多人协作的“在线excel”系统?
  9. Android之使用PopupWindow使用和总结
  10. Android开发和调试必备工具-SDK Tools
  11. MySQL Cookbook 学习笔记-02
  12. linux proc io,在/proc/[pid]/io 中,理解计数器_linux-kernel_开发99编程知识库
  13. 上岗乌镇大会安防的智慧警眼“云镜”,是谁家的AR眼镜?
  14. 手机安装 卸载CA证书
  15. 【5G系列】一文打尽 IMSI、TMSI、GUTI、P-TMSI、S-TMSI、LMSI、5G-TMSI、5G-GUTI、5G-S-TMSI
  16. python知识图谱实战_知识图谱实战
  17. C语言指针(函数指针数组,二级指针)
  18. ROS与优傲机器人UR机器人通讯
  19. 性能测试报告(方案)模板
  20. Hello, Weka

热门文章

  1. Could not locate executable null\bin\winutils.exe in the Hadoop binaries
  2. jQuery项目:京东商品详情页
  3. 猴子排序算法_猴子排序-有史以来最慢的排序算法?
  4. HTML CSS 学习笔记
  5. 关于Android自启动管理的相关知识点
  6. 钉钉机器人发送定时任务
  7. [英文邮件写作技巧] 表达感谢,提出问题,描述附件
  8. 超声波传感器(CHx01) 学习笔记 Ⅴ- 参数配置
  9. 修真院七种教学工具之学习日报
  10. 产品经理告诉你什么是PMF?什么是MVP?