/秋招突击——7/21——复习{堆——数组中的第K大元素}——新作{回溯——全排列、子集、电话号码的字母组合、组合总和、括号生成}
文章目录
- 引言
- 复习
- 数组中的第K大的最大元素
- 复习实现
- 参考实现
- 新作
- 回溯模板
- 46 全排列
- 个人实现
- 参考实现
- 子集
- 个人实现
- 参考实现
- 电话号码的字母组合
- 复习实现
- 组合总和
- 个人实现
- 参考实现
- 括号生成
- 复习实现
- 总结
引言
- 昨天的科大讯飞笔试做的稀烂,今天回来好好练习一下,主要是针对下述两种题型,分别是对顶堆还有回溯,对顶堆的题目并不多,主要是回溯。下次再遇到这种题目,直接背模板,然后开始做!
复习
数组中的第K大的最大元素
-
题目链接
-
第一次做
-
第二次做
-
不知不觉已经是第三次做了,感觉还是有点懵,O(N)的时间复杂度,说明可以遍历多次,但是不能嵌套遍历!想想看哈
复习实现
- 我还是会使用堆实现,并且发现了如果第一次不会做,那么后续会一直不会做,记不住!这里还是要总结.
- 这里还是使用了堆排序时间,虽然时间复杂度不满足要求,但是单纯为了练习一下!
class Solution {public int findKthLargest(int[] nums, int k) {//define m is lenght ,and pq to sort the numint m = nums.length;Queue<Integer> pq = new PriorityQueue<>();// traverse the numsfor(int i = 0;i < m;i ++){if(pq.size() < k) pq.add(nums[i]);else{if(nums[i] > pq.peek()){pq.poll();pq.add(nums[i]);}}}return pq.peek();}
}

参考实现
- 这里正确的做法是使用快排进行修改,这里先回顾一下快排的模板
void quickSort(nums q,int l ,int r){if(l >= r) return;int i = l - 1,j = r + 1,x = q[(l + r)>>1];while(i< j){do i ++ ;while(q[i] < x);do j ++ ;while(q[j] > x);if(i < j) swap(q[i],q[j]);}quickSort(q,l,j),quickSort(q,j + 1,r);
}
- 这样背!虽然很蹩脚,但是能记住就行了,记住了就好些了!
- 左右相交就返回
- 左左右右是 ij
- i加小 j减大
- i小j大做交换
- j做划分两边排
这里是要求第K大的数字,所以得改变一下i和j交换的方向,最后的序列应该是从大到小,然后再是找第k大的元素,这道题是记住了!修改的话,就从最后的终止条件开始!
具体实现
class Solution {public int quickSort(int[] nums,int l ,int r,int k){if(l == r) return nums[k];int i = l - 1,j = r + 1,x = nums[(l + r) >> 1];while(i < j){do i ++;while(nums[i] > x);do j --;while(nums[j] < x);if(i < j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}}if(j >= k) return quickSort(nums,l,j,k);else return quickSort(nums,j + 1,r,k);}public int findKthLargest(int[] nums, int k) {//define m is lenght ,and pq to sort the numint m = nums.length;// traverse the numsint x = quickSort(nums,0,m - 1,k - 1 );return x;}
}

新作
回溯模板
void dfs(int[] nums,int idx){// 终止条件if(idx == termination){// 目标操作return;}//迭代内容for(){dfs(nums,idx + 1);// 恢复现场}
}
-
这里要确定两个东西,一个是总的迭代对象,还有一个是单次迭代的修改内容,下面把下面几个题按照这个模板都分析一下!
-
全排列
- n个对象排在n个位置,每一个位置都要迭代一次,然后每一次都要从剩下没有排的对象中选出来的,所以
- 总的迭代次数:n个位置,终止条件就是迭代n次
- 单次迭代内容:在可选的选项中随机选择一个。
- n个对象排在n个位置,每一个位置都要迭代一次,然后每一次都要从剩下没有排的对象中选出来的,所以
-
子集
- n个对象,其中选择任意一个有几种选择方法,遍历每一个元素,然后根据每一个元素决定是否选中,所以
- 总的迭代次数:n个对象,终止条件所有元素都决策过了。
- 单次迭代内容:当前元素是否选中两种情况,选中当前元素,不选中当前元素,
- n个对象,其中选择任意一个有几种选择方法,遍历每一个元素,然后根据每一个元素决定是否选中,所以
-
组合总和
- n个对象,选择其中若干个若干次,形成目标值,所以
- 总的迭代次数:n个元素,每一个元素都要遍历
- 单次迭代内容:当前元素选择零次,或者若干次
- n个对象,选择其中若干个若干次,形成目标值,所以
其实如果能够从树的角度分析,效果会更好,树的深度就是总的迭代次数,单个节点的子节点数也就是树的宽度,就是单次迭代需要考虑的内容
46 全排列
- 题目链接

注意 - 所有整数互不相同,不用处理特殊情况。
- 数组的长度会出现的一的情况,边界情况,需要特殊处理!
个人实现
- 标准回溯,确定一个模板直接开始写。
- 终止条件:idx = 0,并将结果加入到res中
- 迭代条件:遍历剩余的元素,随机加入到临时列表中
class Solution {public List<List<Integer>> res = new ArrayList<>();void dfs(int[] nums,int idx,List<Integer> list,Set<Integer> set){if(idx == 0){res.add(new ArrayList(list));return;}// iterator conditionfor(int i = 0;i < nums.length;i ++){int x = nums[i];if(!set.contains(x)){list.add(x);set.add(x);dfs(nums,idx - 1,list,set);list.remove(list.size() - 1);set.remove(x);}}}public List<List<Integer>> permute(int[] nums) {List<Integer> list = new ArrayList<>();Set<Integer> set = new HashSet<>();dfs(nums,nums.length,list,set);return res;}
}
觉得写的有点繁琐,看看参考的教程是怎么写的
- 注意,在Java中res.add方法是引用传递,需要创建一个同元素变量的副本才行,不然会越界!
参考实现
-
明确需要记录的状态
- 每一个位置具体的位置保存的数字,也就是list
- 每一个数字的使用情况,使用set
- 递归到了第几步
-
他是使用全局变量来声明,没有使用形参传递对应
这里就不写了,基本上都是一致的
子集
- 题目链接

注意 - 存在数组为1的特殊情况,可能需要特殊处理
- 各个元素互不相同
- 元素有负数的情况
个人实现
- 刚才那道题目是所有的排列情况,这道题目是所有的组合情况,应该也可以使用回溯实现。这个和刚才相同,不过是在每一次的改变环境的时候,就将结果进行保存!
class Solution {List<Integer> list = new ArrayList<>();Set<Integer> set = new HashSet<>();Set<List<Integer>> res = new HashSet<>();void dfs(int[] nums,int idx){if(idx == nums.length){List<Integer> temp = new ArrayList<>(list);Collections.sort(temp);res.add(temp);}for(int i = 0;i < nums.length;i ++){int x = nums[i];if(!set.contains(x)){set.add(x);list.add(x);List<Integer> temp = new ArrayList<>(list);Collections.sort(temp);res.add(temp);dfs(nums,idx + 1);set.remove(x);list.remove(list.size() - 1);}}}public List<List<Integer>> subsets(int[] nums) {res.add(Arrays.asList());dfs(nums,0);List<List<Integer>> resList = new ArrayList<>();for(List<Integer> x:res){resList.add(x);}return resList;}
}

上面这样做就不对,得再想想,如果是回溯的话,得更新一下状态的改变,不能直愣愣的添加对应的元素!出来结果了,然后再添加!
- 好蠢呀,没想到,没想到,既然没想到,记下来,下次肯定能够想到!
参考实现
方法一、DFS
递归的条件
- 每一个元素只有两种情况,放或者不放,所以遍历这两种情况就行了!
class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> res = new ArrayList<>();void dfs(int[] nums,int idx){// termiante conditionif(idx == nums.length){res.add(new ArrayList(list));return ;}// traverse all the condition// get the idx numlist.add(nums[idx]);dfs(nums,idx + 1);list.remove(list.size() - 1);// do not get the idx numdfs(nums,idx + 1);}public List<List<Integer>> subsets(int[] nums) {dfs(nums,0);return res;}
}

方法二、位运算
- 将这个问题转化为对应的二进制表示,每一个物体只有放或者不放两种情况,对应就是不同的二进制数,而且全排列的最终结果数量就是 2 n 2^n 2n
具体实现如下
这里刚好练习一下Java中的二进制数是怎么操作的!
class Solution {public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> res = new ArrayList<>();int n = nums.length;// traverse all the binary numfor(int i = 0;i < (1 << n);i ++){List<Integer> temp = new ArrayList<>();for(int j = 0;j < n;j ++){// judge the j is 0 or 1if(((i >> j) & 1) == 1){temp.add(nums[j]);}}res.add(temp);}return res;}
}
电话号码的字母组合
- 题目链接
- 第一次做
复习实现
class Solution {Map<Character,List<Character>> map = new HashMap<>();StringBuilder str = new StringBuilder();List<String> res = new ArrayList<>();void dfs(String digits,int idx){if(idx == digits.length()){//System.out.println(str.toString());res.add(str.toString());return;}for(char x:map.get(digits.charAt(idx))){str.append(x);dfs(digits,idx + 1);str.deleteCharAt(str.length() - 1);}}public List<String> letterCombinations(String d) {map.put('2',Arrays.asList('a','b','c'));map.put('3',Arrays.asList('d','e','f'));map.put('4',Arrays.asList('g','h','i'));map.put('5',Arrays.asList('j','k','l'));map.put('6',Arrays.asList('m','n','o'));map.put('7',Arrays.asList('p','q','r','s'));map.put('8',Arrays.asList('t','u','v'));map.put('9',Arrays.asList('w','x','y','z')); if(d.length() == 0) return res;dfs(d,0);return res;}
}

- 没以前使用C++实现起来那么快,写起来也没有那么方便!
组合总和
- 题目链接

注意 - 所有元素互不相同
- 每一个元素可以放很多次
个人实现
- 这题可以使用两种方式实现
- 完全背包问题,不过需要记录对应的背包状态,时间复杂度比较低,但是不知道怎么记录满足条件的状态
- 随便选一个,装满为止;F-V,加上价值,这里价值为零
- 暴力回溯,时间复杂度高
- 完全背包问题,不过需要记录对应的背包状态,时间复杂度比较低,但是不知道怎么记录满足条件的状态
暴力回溯
class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> resList = new ArrayList<>();Set<List<Integer>> res = new HashSet<>();// brute dfs to solve the problemvoid dfs(int[] candi,int tar,int temp){if(temp == tar){List<Integer> tempList = new ArrayList(list);Collections.sort(tempList);res.add(tempList);return;}for(int i = 0;i < candi.length;i ++){if(temp + candi[i] <= tar){// put//System.out.println(candi[i]);list.add(candi[i]);dfs(candi,tar,temp + candi[i]);list.remove(list.size() - 1);}}}public List<List<Integer>> combinationSum(int[] candidates, int target) {dfs(candidates,target,0);for(List<Integer> x:res){resList.add(x);}return resList;}
}

我靠,这个居然能过,也是离谱了!
完全背包问题
class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> resList = new ArrayList<>();public List<List<Integer>> combinationSum(int[] candidates, int target) {int[] f = new int[target + 1];f[0] = 1;for(int i = 0;i < candidates;i ++){for(int j = candidates[i];j < target;j ++){f[j] = f[j] + f[j - candidates[i]];}}return f[target - 1];}
}
- 这里只能写成这样,因为我并不知道怎么保存中间状态!
不能用完全背包,完全背包并不能获取中间状态!!
参考实现
- 只能说我对于的回溯的理解还是不够深刻,两种存放方式
- 是否放当前的数字,要用深度u控制,防止出现死循环
- 当前物体一定要放,但是顺序不同,需要set控制是否出现
class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> resList = new ArrayList<>();void dfs(int[] candidates,int dpt,int tar){if(tar == 0){resList.add(new ArrayList(list));return;}if(dpt == candidates.length) return;for(int i = 0;i * candidates[dpt] <= tar ;i ++){dfs(candidates,dpt + 1,tar - i * candidates[dpt]);list.add(candidates[dpt]);} for(int i = 0; i * candidates[dpt] <= tar ;i ++)list.remove(list.size() - 1);}public List<List<Integer>> combinationSum(int[] candidates, int target) {dfs(candidates,0,target);return resList;}
}

实现起来确实更优!如果放或者不放,还是需要使用的深度进行控制!
无论怎么样,都需要加上的对应idx控制
括号生成
- 题目链接
- 第一次学习链接
复习实现
class Solution {// define the structure to store the resultList<String> res = new ArrayList<>();StringBuilder str = new StringBuilder();void dfs(int idx,int n,int l,int r){if(idx == 2 * n && l == r){if(l == r)res.add(str.toString());return ;}// remove the special situationif(r > l || l > n || r > n) return;str.append('(');dfs(idx + 1,n,l + 1,r);str.deleteCharAt(str.length() - 1);str.append(')');dfs(idx + 1,n,l ,r + 1);str.deleteCharAt(str.length() - 1);}public List<String> generateParenthesis(int n) {dfs(0,n,0,0);return res;}
}

上一次写的真丝滑!
vector<string> res;
void dfs(int n,int lc,int rc,string s){/** n表示括号数量,lc表示左括号数量,rc表示右括号数量,s表示字符串*/// 判定什么时候加左括号if (lc == n && rc == n) res.push_back(s); else{// 什么时候加右括号if (lc < n) dfs(n,lc + 1,rc,s + "(");if (lc > rc && rc < n) dfs(n,lc,rc + 1,s + ")");}
}vector<string> generateParenthesis(int n){dfs(n,0,0,"");return res;
}
总结
- 今天这几道题做完了,算是对于深度有了更加深刻的认识!最好能够画出对应的树形结构,树的高度就是总的迭代次数,树的宽度就是单次迭代需要迭代的内容!
- 写回溯,还是比写其他算法要轻松很多!
- 写回溯,一定要画图!写算法一定要画图,转成对应的数据结构!回溯就是可以转成对应的树形结构!
- 一定要要记得恢复现场,每一步都要恢复现场,因为你的编程习惯是共用一个StringBuilder。
相关文章:
/秋招突击——7/21——复习{堆——数组中的第K大元素}——新作{回溯——全排列、子集、电话号码的字母组合、组合总和、括号生成}
文章目录 引言复习数组中的第K大的最大元素复习实现参考实现 新作回溯模板46 全排列个人实现参考实现 子集个人实现参考实现 电话号码的字母组合复习实现 组合总和个人实现参考实现 括号生成复习实现 总结 引言 昨天的科大讯飞笔试做的稀烂,今天回来好好练习一下&a…...
matlab 异常值检测与处理——Robust Z-score法
目录 一、算法原理1、概述2、主要函数3、参考文献二、代码实现三、结果展示四、相关链接本文由CSDN点云侠翻译,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、概述 Robust Z-score法也被称为中位数绝对偏差法。它类似于Z-sc…...
Ubuntu 20安装JDK17和MySQL8.0
一.jdk 安装JDK 第一步:更新软件包:sudo apt update 第二步:安装JDK:sudo apt install openjdk-17-jdk 第三步:检测JDK: java -version 卸载JDK: 第一步:移除JDK包:apt-get purg…...
DC-1靶场打靶第一次!!!!冲冲冲!
今天打了一下DC-1这个靶场,感觉收获比大,我就来记录一下。 我的思路是下面的这个 我们先把靶机导入,然后与我们的liunx(攻击机)在同一个网段中,这也大大的减低难度。 然后我们先对自己这个网段内存活的主机进行操作,我…...
【LeetCode】填充每个节点的下一个右侧节点指针 II
目录 一、题目二、解法完整代码 一、题目 给定一个二叉树: struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NUL…...
mac无法清空废纸篓怎么办 mac废纸篓清空了如何找回 cleanmymac误删文件怎么恢复
废纸篓相当于“一颗后悔药”,用于临时存储用户删除的文件。我们从从Mac上删除的文件,一般会进入废纸篓中。如果我们后悔了,可以从废纸篓中找回来。然而,有时我们会发现mac无法清空废纸篓,这是怎么回事?本文将探讨一些…...
树上启发加点分治思想
题目链接 思路: 对于一条链可以组成回文串,意味着最多只有一个奇数字母,比起我们记录路径各个字母的个数和,我们可以发现回文串实际上不在意真正的个数,只在意个数的奇偶。又我们发现字母只有20来个,可以使…...
【iOS】类对象的结构分析
目录 对象的分类object_getClass和class方法isa流程和继承链分析isa流程实例验证类的继承链实例验证 类的结构cache_t结构bits分析实例验证属性properties方法methods协议protocolsro类方法 类结构流程图解 对象的分类 OC中的对象主要可以分为3种:实例对象…...
接口性能优化思路
前言 日常开发中设计接口,响应时间是衡量一个接口质量的重要指标。 接口响应时间这里粗糙地分为三种: 即时响应:毫秒级,小于500毫秒快速响应:秒级,大于500毫秒且小于2秒长时间操作:大于2秒&a…...
PyQt5 多线程编程详细教程
PyQt5 多线程编程详细教程 在 PyQt5 中,多线程编程是提高应用程序性能和响应性的重要手段。本教程将详细介绍如何在 PyQt5 中使用 QThread 进行多线程编程,学习如何避免界面冻结和线程安全问题,并通过丰富的案例来展示如何实现这些功能。 Q…...
uniapp小程序上传pdf文件
<template><view class"mainInnBox"><view class"formBox"><!-- 注意,如果需要兼容微信小程序,最好通过setRules方法设置rules规则 --><u-form :model"form" ref"uForm" :rules&quo…...
Python酷库之旅-第三方库Pandas(036)
目录 一、用法精讲 111、pandas.Series.item方法 111-1、语法 111-2、参数 111-3、功能 111-4、返回值 111-5、说明 111-6、用法 111-6-1、数据准备 111-6-2、代码示例 111-6-3、结果输出 112、pandas.Series.xs方法 112-1、语法 112-2、参数 112-3、功能 112-…...
Python爬虫(2) --爬取网页页面
文章目录 爬虫URL发送请求UA伪装requests 获取想要的数据打开网页 总结完整代码 爬虫 Python 爬虫是一种自动化工具,用于从互联网上抓取网页数据并提取有用的信息。Python 因其简洁的语法和丰富的库支持(如 requests、BeautifulSoup、Scrapy 等…...
【iOS】——探究isKindOfClass和isMemberOfClass底层实现
isKindOfClass 判断该对象是否为传入的类或其子类的实例 // 类方法实现,用于检查一个类是否属于另一个类或其父类链上的任何类。(BOOL)isKindOfClass:(Class)cls {// 从当前类开始,tcls将沿着元类的继承链向上遍历。for (Class tcls self->ISA(); …...
Python 热门面试题(七)
Python中如何拷贝对象?浅拷贝和深拷贝的区别是什么? 在Python中,拷贝对象是一个常见的需求,尤其是当你需要修改一个对象但又不想影响原始对象时。Python提供了几种拷贝对象的方法,其中最重要的是浅拷贝(sh…...
STM32项目分享:智能宠物喂食系统
目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片: 哔哩哔哩视频链接: https://www.bilibili.com/video/BV1zy411z7…...
数据结构——栈的实现(java实现)与相应的oj题
文章目录 一 栈栈的概念:栈的实现:栈的数组实现默认构造方法压栈获取栈元素的个数出栈获取栈顶元素判断当前栈是否为空 java提供的Stack类Stack实现的接口: LinkedList也可以当Stack使用虚拟机栈,栈帧,栈的三个概念 二 栈的一些算…...
linux修改时区为CST
目录 第一步: 第二步: 第三步: 第一步: 备份原来的时区信息 [rootlocalhost ~]# mv /etc/localtime localtime.bak 第二步: 通过软链接将亚洲/上海 的时区信息 指导时区信息 [rootlocalhost ~]# ln -s /usr/share…...
【Spring Security】初识Spring Security
今天晚上因为一个项目问题,而正式开始学习Spring Security。 这个问题是“APP端的操作员应仅可查看管理后台的项目负责人分配给自己的计划”。 一、Spring Security的核心组件: Spring Security的核心组件包括:SecurityContextHolder、Auth…...
配置单区域OSPF
目录 引言 一、搭建基础网络 1.1 配置网络拓扑图如下 1.2 IP地址表 二、测试每个网段都能单独连通 2.1 PC0 ping通Router1所有接口 2.2 PC1 ping通Router1所有接口 2.3 PC2 ping通Router2所有接口 2.4 PC3 ping通Router2所有接口 2.5 PC4 ping通Router3所有接口 2.…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
