iOS 直播弹幕功能的实现
实现iOS直播弹幕功能需要考虑多个方面,包括弹幕的显示、管理、动画效果以及与直播流的同步。
核心实现方案
1. 弹幕显示视图
class BarrageView: UIView {// 弹道(轨道)数组private var tracks: [CALayer] = []// 正在显示的弹幕数组 private var displayingBarrages: [BarrageLabel] = []// 等待显示的弹幕队列 private var waitingBarrages: [BarrageModel] = []override init(frame: CGRect) {super.init(frame: frame)setupTracks()}// 初始化弹道private func setupTracks() {let trackCount = 5 // 根据需求调整弹道数量let trackHeight: CGFloat = 30 // 每条弹道高度for i in 0..<trackCount {let track = CALayer()track.frame = CGRect(x: 0, y: CGFloat(i) * trackHeight, width: bounds.width, height: trackHeight)tracks.append(track)}}// 添加新弹幕 func addBarrage(_ barrage: BarrageModel) {waitingBarrages.append(barrage)tryDisplayNextBarrage()}// 尝试显示下一条弹幕 private func tryDisplayNextBarrage() {guard !waitingBarrages.isEmpty else { return }// 找到空闲的弹道 if let freeTrackIndex = findFreeTrack() {let barrage = waitingBarrages.removeFirst()displayBarrage(barrage, on: freeTrackIndex)}}// 在指定弹道上显示弹幕private func displayBarrage(_ barrage: BarrageModel, on trackIndex: Int) {let track = tracks[trackIndex]let barrageLabel = BarrageLabel(barrage: barrage)// 设置初始位置(右侧屏幕外)barrageLabel.frame = CGRect(x: bounds.width, y: track.frame.origin.y, width: barrageLabel.intrinsicContentSize.width, height: track.frame.height)addSubview(barrageLabel)displayingBarrages.append(barrageLabel)// 动画UIView.animate(withDuration: 8.0, // 根据弹幕长度调整时间 delay: 0,options: [.curveLinear],animations: {barrageLabel.frame.origin.x = -barrageLabel.bounds.width }, completion: { _ in barrageLabel.removeFromSuperview()if let index = self.displayingBarrages.firstIndex(of: barrageLabel) {self.displayingBarrages.remove(at: index)}self.tryDisplayNextBarrage()})}// 查找空闲弹道private func findFreeTrack() -> Int? {for (index, track) in tracks.enumerated() {var isOccupied = false for barrage in displayingBarrages {if barrage.frame.origin.y == track.frame.origin.y {isOccupied = truebreak }}if !isOccupied {return index}}return nil}
}
2. 弹幕数据模型
struct BarrageModel {let text: String let color: UIColor let fontSize: CGFloat let timestamp: TimeInterval // 相对于直播开始的时间戳 let type: BarrageType // 滚动、顶部、底部等类型 enum BarrageType {case scroll case top case bottom }
}class BarrageLabel: UILabel {init(barrage: BarrageModel) {super.init(frame: .zero)text = barrage.texttextColor = barrage.color font = UIFont.systemFont(ofSize: barrage.fontSize)backgroundColor = UIColor.black.withAlphaComponent(0.3)layer.cornerRadius = 4clipsToBounds = true }
}
3. 弹幕管理器
class BarrageManager {private let barrageView: BarrageViewprivate var timer: Timer?private var currentPlayTime: TimeInterval = 0init(barrageView: BarrageView) {self.barrageView = barrageView }// 开始弹幕播放 func start(with barrages: [BarrageModel]) {stop()currentPlayTime = 0timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateBarrages), userInfo: nil, repeats: true)}// 停止弹幕播放func stop() {timer?.invalidate()timer = nil}// 更新当前播放时间 func updatePlayTime(_ time: TimeInterval) {currentPlayTime = time}@objc private func updateBarrages() {// 在实际应用中,这里应该从服务器获取当前时间点的弹幕 // 这里简化为随机生成一些弹幕 if Int.random(in: 0...10) > 7 { // 30%概率生成新弹幕 let randomTexts = ["666", "主播好帅", "哈哈哈", "这是什么?", "太精彩了!", "爱了爱了"]let randomColors: [UIColor] = [.white, .red, .yellow, .green, .cyan]let barrage = BarrageModel(text: randomTexts.randomElement()!,color: randomColors.randomElement()!,fontSize: CGFloat.random(in: 14...18),timestamp: currentPlayTime,type: .scroll)DispatchQueue.main.async {self.barrageView.addBarrage(barrage)}}}
}
高级优化方案
1. 弹幕渲染性能优化
// 使用CoreText自定义绘制
class BarrageLabel: UIView {private var attributedText: NSAttributedString!init(barrage: BarrageModel) {super.init(frame: .zero)let attributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: barrage.fontSize),.foregroundColor: barrage.color,.strokeWidth: -2,.strokeColor: UIColor.black]attributedText = NSAttributedString(string: barrage.text, attributes: attributes)backgroundColor = UIColor.black.withAlphaComponent(0.3)layer.cornerRadius = 4clipsToBounds = true }override func draw(_ rect: CGRect) {super.draw(rect)guard let context = UIGraphicsGetCurrentContext() else { return }context.textMatrix = .identity context.translateBy(x: 0, y: bounds.size.height)context.scaleBy(x: 1.0, y: -1.0)let path = CGMutablePath()path.addRect(bounds)let framesetter = CTFramesetterCreateWithAttributedString(attributedText)let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributedText.length), path, nil)CTFrameDraw(frame, context)}
}
2. 弹幕与直播同步
// 在播放器回调中更新弹幕时间
func playerTimeUpdate(_ time: TimeInterval) {barrageManager.updatePlayTime(time)
}// 弹幕预加载
func preloadBarrages(for timeRange: ClosedRange<TimeInterval>) {// 从服务器获取指定时间范围内的弹幕 APIManager.fetchBarrages(from: timeRange.lowerBound, to: timeRange.upperBound) { [weak self] barrages in self?.barrageCache.addBarrages(barrages)}
}
3. 弹幕交互功能
// 点击弹幕处理
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {guard let touch = touches.first else { return }let point = touch.location(in: self)for barrage in displayingBarrages.reversed() {if barrage.frame.contains(point) {handleBarrageTap(barrage)break}}
}private func handleBarrageTap(_ barrage: BarrageLabel) {// 显示弹幕操作菜单let alert = UIAlertController(title: "弹幕操作", message: nil, preferredStyle: .actionSheet)alert.addAction(UIAlertAction(title: "回复", style: .default) { _ in// 回复弹幕 })alert.addAction(UIAlertAction(title: "举报", style: .destructive) { _ in // 举报弹幕})alert.addAction(UIAlertAction(title: "取消", style: .cancel))// 显示alert // 需要获取当前视图控制器
}
服务器端实现要点
1. 弹幕存储结构:
struct ServerBarrage {let id: String let content: String let color: String // "#FFFFFF"let size: Int // 字体大小let timestamp: TimeInterval // 相对于直播开始的时间 let userId: String let type: Int // 0:滚动 1:顶部 2:底部
}
2. 弹幕分发:
- 使用WebSocket实时推送新弹幕
- 提供按时间范围查询历史弹幕的API
完整集成示例
class LiveViewController: UIViewController {private let barrageView = BarrageView()private let barrageManager = BarrageManager(barrageView: barrageView)private var player: AVPlayer!override func viewDidLoad() {super.viewDidLoad()setupPlayer()setupBarrageView()loadInitialBarrages()}private func setupPlayer() {// 设置播放器 player = AVPlayer(url: liveURL)let playerLayer = AVPlayerLayer(player: player)playerLayer.frame = view.boundsview.layer.addSublayer(playerLayer)player.play()// 添加时间观察者player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 0.1, preferredTimescale: CMTimeScale(NSEC_PER_SEC)), queue: .main) { [weak self] time in self?.barrageManager.updatePlayTime(time.seconds)}}private func setupBarrageView() {barrageView.frame = view.boundsview.addSubview(barrageView)view.bringSubviewToFront(barrageView)}private func loadInitialBarrages() {// 加载初始弹幕APIManager.fetchInitialBarrages { [weak self] barrages inself?.barrageManager.start(with: barrages)}}@IBAction func sendBarrage(_ sender: Any) {let alert = UIAlertController(title: "发送弹幕", message: nil, preferredStyle: .alert)alert.addTextField { textField in textField.placeholder = "输入弹幕内容"}alert.addAction(UIAlertAction(title: "发送", style: .default) { [weak self] _ inguard let text = alert.textFields?.first?.text, !text.isEmpty else { return }let newBarrage = BarrageModel(text: text,color: .white,fontSize: 16,timestamp: self?.player.currentTime().seconds ?? 0,type: .scroll)// 发送到服务器APIManager.sendBarrage(newBarrage) { success inif success {DispatchQueue.main.async {self?.barrageView.addBarrage(newBarrage)}}}})present(alert, animated: true)}
}
注意事项
-
性能优化:
- 使用异步绘制(CoreText)
- 限制同时显示的弹幕数量
- 使用对象池复用弹幕视图
-
内存管理:
- 及时移除不可见的弹幕
- 避免强引用循环
-
用户体验:
- 提供弹幕透明度调节
- 支持弹幕显示区域设置
- 实现弹幕屏蔽功能
-
弹幕防挡:
- 重要内容区域(如主播面部)自动避开弹幕
- 提供手动设置防挡区域功能
通过以上方案,你可以实现一个高性能、功能丰富的iOS直播弹幕系统。根据实际需求,你可以进一步扩展功能,如弹幕礼物、高级弹幕效果等。
相关文章:
iOS 直播弹幕功能的实现
实现iOS直播弹幕功能需要考虑多个方面,包括弹幕的显示、管理、动画效果以及与直播流的同步。 核心实现方案 1. 弹幕显示视图 class BarrageView: UIView {// 弹道(轨道)数组private var tracks: [CALayer] []// 正在显示的弹幕数组 private var displayingBarra…...
借助Azure AI Foundry 如何打造语音交互新体验
在刚刚落幕的微软创想未来峰会上,Contoso 智能家居的现场演示引发了热议。许多观众在会后留言询问如何回看这场精彩演示。今天,微软为您揭秘 Contoso 如何借助微软最新技术实现智能家居的飞跃式创新。 当语音遇上智能体:用户体验焕然一新 如…...
Spring开发系统时如何实现上传和下载文件
代码如下 值得注意的是上传时候不需要参数servletRequest而下载时候却需要servletResponse,这是为什么呢? 这是因为文件上传时,客户端通过 HTTP POST 请求将文件数据放在 请求体(Body) 中。Spring MVC 对上传过程进行…...
CyberSecAsia专访CertiK首席安全官:区块链行业亟需“安全优先”开发范式
近日,权威网络安全媒体CyberSecAsia发布了对CertiK首席安全官Wang Tielei博士的专访,双方围绕企业在进军区块链领域时所面临的关键安全风险与防御策略展开深入探讨。 Wang博士在采访中指出,跨链桥攻击、智能合约漏洞以及私钥管理不当&#x…...
Android 直播播放器FFmpeg静态库编译实战指南(NDK r21b)
一、环境准备与验证 1.1 必要组件安装 # Ubuntu环境依赖 sudo apt update sudo apt install -y git make automake autoconf libtool pkg-config curl unzip# NDK r21b下载 mkdir -p ~/android && cd ~/android wget https://dl.google.com/android/repository/andro…...
Linux中 I/O 多路复用机制的边缘触发与水平触发
边缘触发(Edge Triggered, ET)与水平触发(Level Triggered, LT) Linux中I/O复用机制epoll -CSDN博客 Linux中的 I/O 复用机制 select-CSDN博客 在 epoll 或其他 I/O 多路复用机制中,触发模式是指如何触发文件描述符…...
01-jenkins学习之旅-window-下载-安装
1 jenkins简介 百度百科介绍:Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。 [1] Jenkins官网地址 翻译&…...
实战:Dify智能体+Java=自动化运营工具!
我们在运营某个圈子的时候,可能每天都要将这个圈子的“热门新闻”发送到朋友圈或聊天群里,但依靠传统的实现手段非常耗时耗力,我们通常要先收集热门新闻,再组装要新闻内容,再根据内容设计海报等。 那怎么才能简化并高…...
LInux—shell编程
一、Shell 编程核心特性 解释型语言 无需编译,直接由 bash、sh 等解释器逐行执行。 类似 PHP 的解释执行,不同于 C 的编译型。 系统命令集成 可直接调用 Linux 命令(如 ls、grep、awk),实现系统管理自动化。 与 C/…...
C++028(变量的作用域)
变量的作用域 作用域就是程序中变量的作用范围。局部变量的作用域是局部的,如函数体内;全局变量的作用域则是整个程序。 我们前面接触过的变量基本都是局部变量,这些变量在函数体内声明,无法被其他函数所使用。函数的形参也属于…...
计算机三级数据库免费题库
1.免费题库链接 链接: https://pan.baidu.com/s/1oNpgWmkFePUrCS6G7tfpUQ?pwdb1hg 提取码: b1hg 2.安装教程...
Unity Shader入门(更新中)
参考书籍:UnityShader入门精要(冯乐乐著) 参考视频:Bilibili《Unity Shader 入门精要》 写在前面:前置知识需要一些计算机组成原理、线性代数、Unity的基础 这篇记录一些学历过程中的理解和笔记(更新中&…...
NSSCTF-[陇剑杯 2021]webshell(问6)
下载得到pcap文件 放到Wireshark进行分析 先过滤http contains "1.php"&&http.request.method"POST" 追踪HTTP流 将后面的进行解码 得到flag NSSCTF{192.168.239.123}...
vscode git push 记录
1.先在git上建一个仓库 2.在vscode上登录同一账号 配置好ssh 直接使用 git remote add origin gitgithub.com:18053923230/aiRecipe.git (base) PS D:\gitee\cookbook> git push -u origin master Enter passphrase for key /c/Users/Administrator/.ssh/id_ed25519: …...
前端性能优化方案
一、HTML优化策略 1、减少DOM层级 <!-- 避免 --><div><div><div><p>内容</p></div></div></div><!-- 推荐 --><div class"content">内容</div> 原因:嵌套过深会增加渲染…...
前端vscode学习
1.安装python 打开Python官网:Welcome to Python.org 一定要点PATH,要不然要自己设 点击install now,就自动安装了 键盘winR 输入cmd 点击确定 输入python,回车 显示这样就是安装成功了 2.安装vscode 2.1下载软件 2.2安装中文 2.2.1当安…...
python实现web请求与回复
一、作为客户端发送请求(使用requests库) import requests # 发送GET请求 response requests.get("https://api.example.com/data") print("GET响应状态码:", response.status_code) print("GET响应内容:", response.…...
Python实现Web请求与响应
目录 一、Web 请求与响应基础 (一)Web 请求与响应的定义与组成 (二)HTTP 协议概述 (三)常见的 HTTP 状态码 二、Python 的 requests 库 (一)安装 requests 库 (二…...
AI与.NET技术实操系列(六):实现图像分类模型的部署与调用
引言 人工智能(AI)技术的迅猛发展推动了各行各业的数字化转型。图像分类,作为计算机视觉领域的核心技术之一,能够让机器自动识别图像中的物体、场景或特征,已广泛应用于医疗诊断、安防监控、自动驾驶和电子商务等领域…...
PP-YOLOE-SOD学习笔记1
项目:基于PP-YOLOE-SOD的无人机航拍图像检测案例全流程实操 - 飞桨AI Studio星河社区 一、安装环境 先准备新环境py>3.9 1.先cd到源代码的根目录下 2.pip install -r requirements.txt 3.python setup.py install 这一步需要看自己的GPU情况,去飞浆…...
Axure系统原型设计列表版方案
列表页面是众多系统的核心组成部分,承担着数据呈现与基础交互的重要任务。一个优秀的列表版设计,能够极大提升用户获取信息的效率,优化操作体验。下面,我们将结合一系列精心设计的列表版方案图片,深入探讨如何打造出实…...
腾讯音乐二面
ReentrantLock 的源码及实现 ReentrantLock 是 Java 中的一种可重入的互斥锁。它通过 AQS(AbstractQueuedSynchronizer)框架来实现。AQS 使用一个 FIFO 队列来管理获取锁的线程。ReentrantLock 有公平锁和非公平锁两种模式。非公平锁:当线程尝…...
服务器操作系统调优内核参数(方便查询)
fs.aio-max-nr1048576 #此参数限制并发未完成的异步请求数目,应该设置避免I/O子系统故障 fs.file-max1048575 #该参数决定了系统中所允许的文件句柄最大数目,文件句柄设置代表linux系统中可以打开的文件的数量 fs.inotify.max_user_watches8192000 #表…...
MySQL5.7导入MySQL8.0的文件不成功
文章目录 问题检查原因及解决方法原因解决办法 问题 检查 检查自己的mysql版本自己检查,搜索“0900_ai_ci”,如果能搜索到,说明这个sql文件是从8的版本导出的 原因及解决方法 原因 MySQL 8.0默认使用utf8mb4字符集和utf8mb4_0900_ai_ci排…...
vscode连接WSL卡住
原因:打开防火墙 解决: 使用sudo ufw disable关闭防火墙...
springAI调用deepseek模型使用硅基流动api的配置信息
查看springai的官方文档,调用deepseek的格式如下: spring.ai.deepseek.api-key${your-api-key} spring.ai.deepseek.chat.options.modeldeepseek-chat spring.ai.deepseek.chat.options.temperature0.8 但是硅基流动的格式不是这样,这个伞兵…...
symbol【ES6】
你一闭眼世界就黑了,你不是主角是什么? 目录 什么是Symbol?Symbol特点:创建方法:注意点:不能进行运算:显示调用toString() --没有意义隐式转换boolean 如果属性名冲突了怎么办?o…...
如何用数据可视化提升你的决策力?
在数字化浪潮席卷全球的当下,数据已然成为企业和组织发展的核心资产。然而,单纯的数据堆积犹如未经雕琢的璞玉,难以直接为决策提供清晰有力的支持。数据可视化作为一种强大的工具,能够将海量、复杂的数据转化为直观、易懂的图形、…...
【C++】vector容器实现
目录 一、vector的成员变量 二、vector手动实现 (1)构造 (2)析构 (3)尾插 (4)扩容 (5)[ ]运算符重载 5.1 迭代器的实现: (6&…...
C语言求1到n的和(附带源码和解析)
在C语言中,使用 for 循环求 1 到 n 的和是一个常见的编程任务。这个任务不仅可以帮助初学者理解循环的基本概念,还能培养他们的逻辑思维能力。 要计算 1 到 n 的和,我们需要创建一个循环,从 1 开始,一直累加到 n。for…...
springboot3+vue3融合项目实战-大事件文章管理系统-文章分类也表查询(条件分页)
在pojo实体类中增加pagebean实体类 Data NoArgsConstructor AllArgsConstructor public class PageBean <T>{private Long total;//总条数private List<T> items;//当前页数据集合 }articlecontroller增加代码 GetMappingpublic Result<PageBean<Article&g…...
java中定时任务的实现及使用场景
在 Java 需要中,定时任务的实现方式有单线程模型的 Timer 类、线程池定时任务的 ScheduleExecutorService、spring 框架提供的注解Schedule 定时任务,第三个框架定时任务比如 XX-Job,Quartz 等。 Java 任务调度组件对比与使用指南 一、核心功能对比 特…...
使用 OpenCV 实现哈哈镜效果
在计算机视觉和图像处理领域,OpenCV 提供了非常强大的图像几何变换能力,不仅可以用于纠正图像,还能制造各种“有趣”的视觉效果。今天,我们就来实现一个经典的“哈哈镜”效果,让图像像在游乐园里一样被拉伸、压缩、扭曲…...
【Java高阶面经:微服务篇】9.微服务高可用全攻略:从架构设计到自动容灾
一、架构层:构建抗故障的分布式基石 1.1 多维度冗余设计 1.1.1 跨可用区部署策略 # Kubernetes跨可用区反亲和性配置 apiVersion: apps/v1 kind: Deployment metadata:name: product-service spec:replicas: 3template:spec:affinity:podAntiAffinity:requiredDuringSchedu…...
读一本书第一遍是快读还是细读?
在时间充足且计划对重要书籍进行多遍阅读的前提下,第一遍阅读的策略可以结合**「快读搭建框架」与「标记重点」**,为后续细读奠定基础。以下是具体建议及操作逻辑: 一、第一遍:快读为主,目标是「建立全局认知」 1. 快…...
COMPUTEX 2025 | 广和通5G AI MiFi解决方案助力移动宽带终端迈向AI新未来
随着5G与AI不断融合,稳定高速、智能的移动网络已成为商务、旅行、户外作业等场景的刚需。广和通5G AI MiFi方案凭借领先技术与创新设计,重新定义5G移动网络体验。 广和通5G AI MiFi 方案搭载高通 4nm制程QCM4490平台,融合手机级超低功耗技术…...
JAVA批量发送邮件(含excel内容)
EmailSenderHtmlV1 是读取配置文件《批量发送邮件.xlsx》,配置sheet获取 发件人邮箱 邮箱账号 口令,发送excel数据sheet获取收件人邮箱 抄送人邮箱 邮件标题 第N行开始(N>1,N0默认表头) 第M行结束(M>1,M0默认表头) 附件文件夹…...
MyBatis 关联映射深度解析:_association_ 与 _collection_ 实战教程
一、核心概念与适用场景 在 MyBatis 中,<association> 和 <collection> 用于处理对象间的关联关系,简化复杂查询到对象结构的映射。 标签用途对应关系示例场景<association>映射 单个嵌套对象(“有一个”关系)一对一、多对一员工 (Emp) 属于一个部门 (D…...
NSSCTF [watevrCTF 2019]Wat-sql
90.[watevrCTF 2019]Wat-sql(逻辑漏洞) [watevrCTF 2019]Wat-sql (1) 1.准备 motalymotaly-VMware-Virtual-Platform:~$ file sql sql: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linu…...
C++ 前缀和数组
一. 一维数组前缀和 1.1. 定义 前缀和算法通过预处理数组,计算从起始位置到每个位置的和,生成一个新的数组(前缀和数组)。利用该数组,可以快速计算任意区间的和,快速求出数组中某一段连续区间的和。 1.2. …...
免费使用GPU的探索笔记
多种有免费时长的平台 https://www.cnblogs.com/java-note/p/18760386 Kaggle免费使用GPU的探索 https://www.kaggle.com/ 注册Kaggle账号 访问Kaggle官网,使用邮箱注册账号。 发现gpu都是灰色的 返回home,右上角的头像点开 验证手机号 再次code-you…...
【css】 flex布局基本知识
Flexible Box 模型,是一种一维的布局模型。一个 flexbox 一次只能处理一个维度上的元素布局,一行或者一列。 轴线 flex 属性与主轴和交叉轴有关,通过flex-direction定义 主轴由 flex-direction 定义,可以取 4 个值:…...
3D Gaussian Splatting for Real-Time Radiance Field Rendering——文章方法精解
SfM → Point-NeRF → 3D Gaussian Splatting 🟦SfM Structure-from-Motion(运动恢复结构,简称 SfM)是一种计算机视觉技术,可以: 利用多张从不同角度拍摄的图像,恢复出场景的三维结构和相机的…...
RestTemplate 发送的字段第二个大写字母变成小写的问题探究
在使用RestTemplate 发送http 请求的时候,发现nDecisonVar 转换成了ndecisonVar ,但是打印日志用fastjson 打印的没有问题,换成jackson 打印就有问题。因为RestTemplate 默认使用的jackson 作为json 序列化方式,导致的问题,但是为…...
第二次中医知识问答微调
由于昨天微调效果并不理想,因此更换数据集和参数进行重新进行了微调 本次微调参数如下: llamafactory-cli train \ --stage sft \ --do_train True \ --model_name_or_path /home/qhyz/zxy/LLaMA-Factory/model \ --preprocessing_num_workers 16 \ --…...
Linux查 ssh端口号和服务状态
一、检查SSH服务运行状态 通过进程查看命令验证服务是否启动: ps -ef | grep ssh当输出包含sshd进程时,表示SSH服务正在运行。示例输出: root 1234 1 0 10:00 ? 00:00:00 /usr/sbin/sshd二、查看服务监听端口 使用网络…...
C++ 11(1):
C11的发展史: C11中的{}: 看这个图片,我们的C11是所有的对象都可以使用{}来进行初始化,之前我们的int类型的数据要使用赋值符号来进行初始化,现在的话我们可以直接使用花括号来进行,并且连赋值符号都可以去…...
数据结构(4)线性表-链表-双链表
一、链表的分类 迟来的分类,主要如果在学习单链表前去讲分类,可能就云里雾里的,所以放在讲完单链表后讲。 划分链表的标准如下: 有没有头结点、指针的方向、循环与否 头结点就是一个占位结点,也被叫做哨兵位&#x…...
Spring Framework 的 spring-core 和 Spring Security 兼容版本
Spring Framework 的 spring-core 和 Spring Security 兼容版本 Spring Framework 的 spring-core 和 Spring Security 的版本需要保持兼容性,尤其是在旧版本(如 Spring 4.x)中。以下是它们的版本对应关系: Spring 4.x (spring-c…...
《国家职业教育平台:点亮职业教育新灯塔》
职教新航标:平台诞生记 国家职业教育智慧教育平台 在科技飞速发展的今天,数字化浪潮席卷全球,深刻地改变着我们生活的方方面面,教育领域也不例外。随着信息技术的不断进步,教育数字化已成为当今世界教育发展的重要趋势…...