懂车帝二面复盘
时间:2023年04月10日 17:00
场景
数据推送到内存中,如何做到不产生并发问题。
请看以下示例:
1 | public class Main { |
运行启动类,查看控制台:
1 | 打印之前:[19, 16, 5, 13] |
发现这样替换数据会产生并发问题,也就是在打印过程中,数据源直接被替换,那么打印的数据也就被替换了。其实解决方案很简单,就是使用一个局部变量接收共享变量的值,使用局部变量进行遍历,这个局部变量只有两种状态,要么是旧数据要么是新数据,不会被改变。
修改printData()
方法:
1 |
|
运行启动类,查看控制台:
1 | 打印之前:[10, 14, 15, 6, 15, 4, 16, 18, 7, 2, 14, 0, 5, 9, 14, 18, 18] |
我们发现原始数据已经被更新多次,但打印的数据还是旧数据,状态一致,保证了并发的安全性,同时无锁也保证了并发度。
算法
数组nums中给定可以使用的1~9的数,返回由数组nums中的元素组成的小于n的最大数。
此题leetcode上也有讨论贴:小于n的最大数
示例 1:
1 | 输入:nums = {1, 2, 9, 4},n = 2533 |
示例 2:
1 | 输入:nums = {1, 2, 5, 4},n = 2543 |
示例 3:
1 | 输入:nums = {1, 2, 5, 4},n = 2541 |
示例 4:
1 | 输入:nums = {1, 2, 9, 4},n = 2111 |
示例 5:
1 | 输入:nums = {5, 9},n = 5555 |
示例 6:
1 | 输入:nums = {5, 9},n = 3 |
思路
- 对每一位先尝试使用相同数字
- 如果没有相同数字,判断是否存在比当前数字更小的数字,如果有,则选择更小数字中的最大数,剩余的数字用最大数字
- 如果没有,向前查找前一个数字有没有更小的数字
- 直到回溯到第一个数字,就用位数更少但全部都是最大的数
代码
在实际代码编写中我们添加一个标志末尾字符,当遍历到此字符时必定会向前查找,统一因缺少数字与所有数字都包含的情况,例如:
- 缺少数字
1 | 输入:nums = {1, 2, 9, 4},n = 2533 |
2533遍历到第一个3时,因为nums数组中不存在3,因此需要向前一位查找更小的数字
- 所有数字都包含
1 | 输入:nums = {1, 2, 9, 4},n = 2111 |
2111遍历完毕,所有的数字都包含,最后结果为2111,因此需要再向前一位查找更小的数字
添加一个标志末尾字符的目的就是统一以上两种情况,避免重复编码,值得注意的是添加的标志字符的ASCII码值应小于’0’,必须使set.lower(num)返回为null。
1 | class Solution { |
测试
添加测试用例:
1 | class Test { |
运行启动类,查看控制台:
1 | true------>2542 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 狼族少年、血狼!