【面经】2024春招滴滴后端研发岗

一 redis过期策略

        Redis的过期策略是指当Redis中的缓存数据(即key)达到其设定的过期时间后,Redis如何对这些数据进行处理的一系列规则和方法。Redis提供了多种过期策略,主要包括以下几种方式:

1. 定时删除

  • 做法:为每个设置了过期时间的key创建一个定时器,当过期时间到达时,定时器触发,Redis立即删除该key。
  • 优点:可以立即释放内存,对内存使用友好。
  • 缺点:占用大量CPU资源,因为每个key都需要一个独立的定时器,这在key数量很多时会导致CPU负载过高,从而影响Redis的性能。因此,Redis并不推荐这种方式作为主要的过期策略。

2. 惰性删除

  • 做法:Redis不主动删除过期的key,而是在每次访问key时,检查该key是否过期。如果已过期,则删除该key。
  • 优点:可以节省CPU资源,因为只有在实际需要访问key时才会进行检查。
  • 缺点:可能导致大量过期的key仍然占用内存,特别是如果这些key在过期后很长时间内都没有被访问。

3. 定期删除

  • 做法:Redis将设置了过期时间的key放入一个特定的字典中,并周期性地(默认是100ms)从这个字典中随机选取一定数量的key进行检查,删除其中的过期key。如果删除的key数量超过一定比例(如1/4),则重复这个过程,直到删除的key数量少于这个比例。
  • 优点:是定时删除和惰性删除的折中方案,可以在不过度消耗CPU资源的情况下,有效地释放内存。
  • 缺点:可能存在一些过期的key在一段时间内仍然被使用,特别是在key过期时间集中分布时。此外,如果过期key数量非常多,可能导致扫描和删除操作频繁,从而影响Redis的性能。

4. 内存淘汰策略

        当Redis的内存达到限制时,除了上述过期策略外,Redis还提供了多种内存淘汰策略来选择删除哪些键以腾出空间。这些策略包括:

  • noeviction:当内存超出限制时,不保存新的数据,返回错误。
  • allkeys-lru:根据最近最少使用(LRU)算法,删除最久未使用的键。
  • allkeys-lfu:根据最不经常使用(LFU)算法,删除使用频率最低的键。
  • volatile-lru:在设置了过期时间的键集合中,使用LRU算法删除最久未使用的键。
  • volatile-lfu:在设置了过期时间的键集合中,使用LFU算法删除使用频率最低的键。
  • allkeys-random:随机删除任意键。
  • volatile-random:随机删除设置了过期时间的任意键。
  • volatile-ttl:删除设置了过期时间且剩余生存时间最短的键。

二 TCP和UDP区别

1. 连接性

  • TCP:TCP是一种面向连接的协议。在数据传输之前,TCP要求发送方和接收方之间先建立一个可靠的连接。这个连接过程通常包括三次握手,确保双方都已准备好接收数据。
  • UDP:UDP则是一种无连接的协议。发送方在发送数据之前不需要与接收方建立连接,可以直接将数据发送出去。这种无连接特性使得UDP的通信过程更加简单和高效。

2. 可靠性

  • TCP:TCP对数据的可靠性要求非常严格。它采用了一系列机制来确保数据的完整性和正确性,包括确认机制、重传机制和流量控制机制等。如果接收方没有收到数据或数据有误,TCP会要求发送方重新发送,直到数据正确接收为止。
  • UDP:UDP对数据的可靠性要求较低,它不提供确认、重传和流量控制等机制。因此,如果发送的数据丢失或损坏,UDP不会进行任何处理,而是直接由接收方承担可能的数据错误或丢失的风险。

3. 速度和效率

  • TCP:由于TCP需要建立连接和进行确认重传等操作,因此其速度和效率相对较低。特别是在网络拥堵的情况下,TCP的拥塞控制机制会进一步降低其传输速度。
  • UDP:UDP不受连接建立和确认重传等开销的影响,因此其传输速度通常比TCP更快。同时,UDP也不受拥塞控制算法的限制,可以在网络拥堵时继续发送数据。

4. 数据包大小

  • TCP:TCP将数据划分为较小的数据包(称为TCP段)进行传输,并根据网络状况进行调整。TCP没有固定的数据报大小限制,可以根据需要动态调整数据包的大小。
  • UDP:UDP允许将多个数据包打包成一个较大的数据报(称为UDP数据报)进行传输。UDP数据报的大小通常由应用层决定,但受到网络MTU(最大传输单元)的限制。

5. 适用场景

  • TCP:由于TCP提供可靠的数据传输服务,因此适用于对数据可靠性要求较高的应用场景,如文件传输、电子邮件和网页浏览等。
  • UDP:UDP由于其快速传输和较低的开销特性,适用于对数据实时性要求较高的应用场景,如音频和视频流传输、网络游戏和实时通信等。此外,UDP还支持广播和多播传输方式,适用于需要向多个主机发送相同数据的场景。

三 MySQL索引适用场景

1. 经常被查询的字段

  • 场景描述:对于经常被查询的字段,如用户ID、订单号等,建立索引可以显著提高查询效率。
  • 应用实例:在电商网站中,用户经常通过订单号查询订单信息,为订单号字段建立索引可以加快查询速度。

2. 需要进行范围查询的字段

  • 场景描述:对于需要进行范围查询的字段,如日期范围、价格范围等,建立索引可以加快查询速度。
  • 应用实例:在新闻网站中,用户经常通过日期范围查询新闻,为日期字段建立索引可以提高查询效率。

3. 外键字段

  • 场景描述:对于外键字段,建立索引可以加快关联查询的速度。
  • 应用实例:在一个订单系统中,订单表和用户表通过用户ID进行关联查询,为用户ID字段建立索引可以提高查询效率。

4. 需要进行排序操作的字段

  • 场景描述:对于需要进行排序操作的字段,建立索引可以加快排序速度。
  • 应用实例:在一个论坛系统中,用户经常通过帖子的发布时间进行排序,为发布时间字段建立索引可以提高排序效率。

5. 需要进行统计操作的字段

  • 场景描述:对于需要进行统计操作的字段,建立索引可以加快统计的速度。
  • 应用实例:在一个销售系统中,需要统计每个月的销售额,为销售日期字段建立索引可以提高统计效率。

6. 大表中的查询字段

  • 场景描述:在处理大量数据的情况下,索引的作用更加明显。对于大表中的查询字段,建立索引可以加快查询速度。
  • 应用实例:在一个电商平台中,商品表可能包含上百万条数据,为商品名称字段建立索引可以提高查询效率。

7. 唯一性索引

  • 场景描述:唯一性索引确保索引列中的所有值都是唯一的,适用于需要保证数据唯一性的场景,如用户的手机号、身份证号等。
  • 应用实例:创建表时添加唯一索引,或者在已存在的表上添加唯一索引,以确保数据的唯一性。

8. 组合索引

  • 场景描述:组合索引涉及多个列,可以通过多个列的组合来提高查询性能。
  • 应用实例:在订单表中同时对用户ID和订单状态创建复合索引,以减少数据库的扫描范围,提高查询速度。

四 两个有序数组合并

1.暴力破解法:直接合并两个数组,再对新数组进行排序

public class MergeSortedArrays {  
    public static int[] mergeArrays(int[] arr1, int[] arr2) {  
        int[] merged = new int[arr1.length + arr2.length];  
          
        // 复制数组1  
        System.arraycopy(arr1, 0, merged, 0, arr1.length);  
        // 复制数组2  
        System.arraycopy(arr2, 0, merged, arr1.length, arr2.length);  
          
        // 对合并后的数组进行排序  
        Arrays.sort(merged);  
          
        return merged;  
    }  
  
    public static void main(String[] args) {  
        int[] arr1 = {1, 3, 5, 7};  
        int[] arr2 = {2, 4, 6, 8};  
        int[] merged = mergeArrays(arr1, arr2);  
        System.out.println(Arrays.toString(merged));  
    }  
}

2.双指针法

public class MergeSortedArraysEfficient {  
    public static int[] mergeSortedArrays(int[] arr1, int[] arr2) {  
        int len1 = arr1.length, len2 = arr2.length;  
        int[] merged = new int[len1 + len2];  
        int i = 0, j = 0, k = 0;  
          
        // 使用三个指针分别指向两个输入数组和输出数组  
        while (i < len1 && j < len2) {  
            if (arr1[i] <= arr2[j]) {  
                merged[k++] = arr1[i++];  
            } else {  
                merged[k++] = arr2[j++];  
            }  
        }  
          
        // 如果第一个数组还有剩余,复制剩余部分  
        while (i < len1) {  
            merged[k++] = arr1[i++];  
        }  
          
        // 如果第二个数组还有剩余,复制剩余部分  
        while (j < len2) {  
            merged[k++] = arr2[j++];  
        }  
          
        return merged;  
    }  
  
    public static void main(String[] args) {  
        int[] arr1 = {1, 3, 5, 7};  
        int[] arr2 = {2, 4, 6, 8};  
        int[] merged = mergeSortedArrays(arr1, arr2);  
        System.out.println(Arrays.toString(merged));  
    }  
}

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值