iOS 直播特殊礼物特效实现方案(Swift实现,超详细!)
特殊礼物特效是提升直播互动体验的关键功能,下面我将详细介绍如何在iOS应用中实现各种高级礼物特效。
- 基础特效类型
1.1 全屏动画特效
class FullScreenAnimationView: UIView {static func show(with gift: GiftModel, in view: UIView) {let effectView = FullScreenAnimationView(gift: gift)effectView.frame = view.boundsview.addSubview(effectView)effectView.startAnimation()}private let gift: GiftModel private var imageView: UIImageView!private var animationFrames: [UIImage] = []init(gift: GiftModel) {self.gift = giftsuper.init(frame: .zero)setupUI()loadAnimationFrames()}private func setupUI() {backgroundColor = UIColor.black.withAlphaComponent(0.7)imageView = UIImageView()imageView.contentMode = .scaleAspectFit imageView.frame = boundsaddSubview(imageView)}private func loadAnimationFrames() {// 从本地或网络加载动画帧for i in 1...30 { // 假设有30帧动画 if let image = UIImage(named: "\(gift.id)_frame_\(i)") {animationFrames.append(image)}}}func startAnimation() {imageView.animationImages = animationFramesimageView.animationDuration = 3.0 imageView.animationRepeatCount = 1 imageView.startAnimating()DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {self.removeFromSuperview()}}
}
1.2 粒子特效
class ParticleEffectView: UIView {static func show(with gift: GiftModel, in view: UIView) {let effectView = ParticleEffectView(gift: gift)effectView.frame = view.bounds view.addSubview(effectView)effectView.startEmitter()}private let gift: GiftModelprivate var emitterLayer: CAEmitterLayer!init(gift: GiftModel) {self.gift = gift super.init(frame: .zero)setupEmitter()}private func setupEmitter() {emitterLayer = CAEmitterLayer()emitterLayer.emitterPosition = CGPoint(x: bounds.midX, y: bounds.midY)emitterLayer.emitterSize = CGSize(width: bounds.width, height: 1)emitterLayer.emitterShape = .sphere emitterLayer.renderMode = .additive emitterLayer.beginTime = CACurrentMediaTime()let cell = CAEmitterCell()cell.contents = UIImage(named: "particle_\(gift.id)")?.cgImagecell.birthRate = 50 cell.lifetime = 5 cell.lifetimeRange = 1 cell.velocity = 100cell.velocityRange = 50 cell.emissionRange = .pi * 2 cell.spin = 1 cell.spinRange = 2cell.scale = 0.5cell.scaleRange = 0.3cell.scaleSpeed = -0.05 cell.alphaSpeed = -0.2 emitterLayer.emitterCells = [cell]layer.addSublayer(emitterLayer)}func startEmitter() {DispatchQueue.main.asyncAfter(deadline: .now() + 2) {self.emitterLayer.birthRate = 0DispatchQueue.main.asyncAfter(deadline: .now() + 3) {self.removeFromSuperview()}}}
}
- 高级特效实现
2.1 3D模型特效 (使用SceneKit)
import SceneKit class Model3DEffectView: UIView {static func show(with gift: GiftModel, in view: UIView) {let effectView = Model3DEffectView(gift: gift)effectView.frame = view.bounds view.addSubview(effectView)effectView.startAnimation()}private let sceneView = SCNView()private let gift: GiftModelinit(gift: GiftModel) {self.gift = giftsuper.init(frame: .zero)setupScene()}private func setupScene() {sceneView.frame = boundssceneView.backgroundColor = .clearaddSubview(sceneView)let scene = SCNScene()sceneView.scene = scene// 加载3D模型if let modelNode = loadModelNode() {scene.rootNode.addChildNode(modelNode)// 添加相机let cameraNode = SCNNode()cameraNode.camera = SCNCamera()cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)scene.rootNode.addChildNode(cameraNode)// 添加光源 let lightNode = SCNNode()lightNode.light = SCNLight()lightNode.light?.type = .omnilightNode.position = SCNVector3(x: 0, y: 10, z: 10)scene.rootNode.addChildNode(lightNode)}}private func loadModelNode() -> SCNNode? {guard let sceneURL = Bundle.main.url(forResource: gift.id, withExtension: "scn"),let sceneSource = SCNSceneSource(url: sceneURL, options: nil) else {return nil}return sceneSource.entryWithIdentifier("MDL_OBJ_ROOT", withClass: SCNNode.self)}func startAnimation() {// 旋转动画 let rotateAction = SCNAction.rotateBy(x: 0, y: .pi * 2, z: 0, duration: 5)sceneView.scene?.rootNode.childNodes.first?.runAction(rotateAction)// 缩放动画let scaleUp = SCNAction.scale(to: 1.5, duration: 1)let scaleDown = SCNAction.scale(to: 0.5, duration: 1)let scaleSequence = SCNAction.sequence([scaleUp, scaleDown])let repeatScale = SCNAction.repeat(scaleSequence, count: 2)sceneView.scene?.rootNode.childNodes.first?.runAction(repeatScale)DispatchQueue.main.asyncAfter(deadline: .now() + 5) {self.removeFromSuperview()}}
}
2.2 视频特效 (使用AVPlayer)
class VideoEffectView: UIView {static func show(with gift: GiftModel, in view: UIView) {let effectView = VideoEffectView(gift: gift)effectView.frame = view.bounds view.addSubview(effectView)effectView.playVideo()}private let playerLayer = AVPlayerLayer()private let gift: GiftModel init(gift: GiftModel) {self.gift = gift super.init(frame: .zero)setupPlayer()}private func setupPlayer() {guard let videoURL = URL(string: gift.effectVideoURL) else { return }let player = AVPlayer(url: videoURL)playerLayer.player = player playerLayer.frame = bounds playerLayer.videoGravity = .resizeAspectFilllayer.addSublayer(playerLayer)NotificationCenter.default.addObserver(self,selector: #selector(playerDidFinishPlaying),name: .AVPlayerItemDidPlayToEndTime,object: player.currentItem)}func playVideo() {playerLayer.player?.play()}@objc private func playerDidFinishPlaying() {removeFromSuperview()}deinit {NotificationCenter.default.removeObserver(self)}
}
- 复合特效组合
3.1 组合多个特效
class CompositeEffectCoordinator {static func playEffect(for gift: GiftModel, in view: UIView) {// 根据礼物类型播放不同组合特效switch gift.effectLevel {case .basic:FullScreenAnimationView.show(with: gift, in: view)case .advanced:FullScreenAnimationView.show(with: gift, in: view)DispatchQueue.main.asyncAfter(deadline: .now() + 1) {ParticleEffectView.show(with: gift, in: view)}case .premium:FullScreenAnimationView.show(with: gift, in: view)DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {Model3DEffectView.show(with: gift, in: view)}DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {VideoEffectView.show(with: gift, in: view)}}}
}
3.2 特效序列管理器
class EffectSequenceManager {private var effectQueue: [() -> Void] = []private var isPlaying = false func addEffect(_ effect: @escaping () -> Void) {effectQueue.append(effect)playNextIfNeeded()}private func playNextIfNeeded() {guard !isPlaying, !effectQueue.isEmpty else { return }isPlaying = truelet effect = effectQueue.removeFirst()effect()DispatchQueue.main.asyncAfter(deadline: .now() + 3) {self.isPlaying = false self.playNextIfNeeded()}}
}// 使用示例
let effectManager = EffectSequenceManager()
effectManager.addEffect {FullScreenAnimationView.show(with: gift1, in: view)
}
effectManager.addEffect {ParticleEffectView.show(with: gift2, in: view)
}
- 高级交互特效
4.1 用户交互式特效
class InteractiveEffectView: UIView {private var touchPoints: [CGPoint] = []private var displayLink: CADisplayLink?private var particleLayers: [CALayer] = []override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {super.touchesBegan(touches, with: event)guard let touch = touches.first else { return }let point = touch.location(in: self)createParticleEmitter(at: point)}override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {super.touchesMoved(touches, with: event)guard let touch = touches.first else { return }let point = touch.location(in: self)touchPoints.append(point)if touchPoints.count > 5 {touchPoints.removeFirst()}if touchPoints.count % 2 == 0 {createParticleEmitter(at: point)}}private func createParticleEmitter(at position: CGPoint) {let emitterLayer = CAEmitterLayer()emitterLayer.emitterPosition = position emitterLayer.emitterSize = CGSize(width: 20, height: 20)emitterLayer.emitterShape = .circleemitterLayer.renderMode = .additivelet cell = CAEmitterCell()cell.contents = UIImage(named: "sparkle")?.cgImage cell.birthRate = 20 cell.lifetime = 2 cell.velocity = 50 cell.velocityRange = 30 cell.emissionRange = .pi * 2 cell.scale = 0.2 cell.scaleRange = 0.1cell.alphaSpeed = -0.5emitterLayer.emitterCells = [cell]layer.addSublayer(emitterLayer)particleLayers.append(emitterLayer)DispatchQueue.main.asyncAfter(deadline: .now() + 2) {emitterLayer.birthRate = 0DispatchQueue.main.asyncAfter(deadline: .now() + 1) {emitterLayer.removeFromSuperlayer()if let index = self.particleLayers.firstIndex(of: emitterLayer) {self.particleLayers.remove(at: index)}}}}
}
4.2 手势控制特效
class GestureControlledEffectView: UIView {private var panRecognizer: UIPanGestureRecognizer!private var pinchRecognizer: UIPinchGestureRecognizer!private var rotationRecognizer: UIRotationGestureRecognizer!private var effectNode: SKSpriteNode!override init(frame: CGRect) {super.init(frame: frame)setupScene()setupGestures()}private func setupScene() {let skView = SKView(frame: bounds)skView.backgroundColor = .clearaddSubview(skView)let scene = SKScene(size: bounds.size)scene.backgroundColor = .clearskView.presentScene(scene)effectNode = SKSpriteNode(imageNamed: "magic_effect")effectNode.position = CGPoint(x: scene.size.width/2, y: scene.size.height/2)effectNode.setScale(0.5)scene.addChild(effectNode)}private func setupGestures() {panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))addGestureRecognizer(panRecognizer)pinchRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(_:)))addGestureRecognizer(pinchRecognizer)rotationRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(handleRotation(_:)))addGestureRecognizer(rotationRecognizer)// 允许多个手势同时识别panRecognizer.delegate = self pinchRecognizer.delegate = selfrotationRecognizer.delegate = self }@objc private func handlePan(_ recognizer: UIPanGestureRecognizer) {let translation = recognizer.translation(in: self)effectNode.position.x += translation.x effectNode.position.y -= translation.yrecognizer.setTranslation(.zero, in: self)}@objc private func handlePinch(_ recognizer: UIPinchGestureRecognizer) {effectNode.setScale(effectNode.xScale * recognizer.scale)recognizer.scale = 1.0 }@objc private func handleRotation(_ recognizer: UIRotationGestureRecognizer) {effectNode.zRotation += recognizer.rotation recognizer.rotation = 0.0}
}extension GestureControlledEffectView: UIGestureRecognizerDelegate {func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {return true}
}
- 性能优化方案
5.1 对象池模式
class EffectPool {static let shared = EffectPool()private var fullScreenEffects: [FullScreenAnimationView] = []private var particleEffects: [ParticleEffectView] = []func dequeueFullScreenEffect(for gift: GiftModel) -> FullScreenAnimationView {if let effect = fullScreenEffects.first(where: { $0.isHidden }) {effect.gift = gifteffect.isHidden = false return effect } else {let effect = FullScreenAnimationView(gift: gift)fullScreenEffects.append(effect)return effect}}func dequeueParticleEffect(for gift: GiftModel) -> ParticleEffectView {if let effect = particleEffects.first(where: { $0.isHidden }) {effect.gift = gifteffect.isHidden = false return effect } else {let effect = ParticleEffectView(gift: gift)particleEffects.append(effect)return effect}}func recycle(effect: UIView) {effect.isHidden = true effect.layer.removeAllAnimations()}
}
5.2 特效资源预加载
class EffectPreloader {static func preloadEffects(for gifts: [GiftModel]) {DispatchQueue.global(qos: .userInitiated).async {for gift in gifts {switch gift.effectType {case .animation:_ = UIImage(contentsOfFile: Bundle.main.path(forResource: "\(gift.id)_frame_1", ofType: "png") ?? "")case .particle:_ = UIImage(contentsOfFile: Bundle.main.path(forResource: "particle_\(gift.id)", ofType: "png") ?? "")case .video:let _ = AVAsset(url: URL(string: gift.effectVideoURL)!)case .model3D:_ = SCNScene(named: "\(gift.id).scn")}}}}
}
- 特效配置文件
{"effects": [{"id": "rocket","name": "超级火箭","type": "composite","components": [{"type": "animation","duration": 2.0,"frames": 30,"framePrefix": "rocket_anim_"},{"type": "particle","particleImage": "rocket_particle","birthRate": 200,"lifetime": 3.0,"velocity": 150},{"type": "sound","file": "rocket_launch.mp3","volume": 1.0 }],"trigger": "immediate","zOrder": 1000 },{"id": "fireworks","name": "豪华烟花","type": "sequence","components": [{"type": "animation","duration": 1.5,"frames": 45,"framePrefix": "fireworks_launch_"},{"type": "particle","particleImage": "sparkle","birthRate": 500,"lifetime": 2.5,"velocity": 80,"delay": 1.5 }],"trigger": "delayed","zOrder": 900}]
}
实现建议
-
分层架构设计:
- 表现层:处理特效的视觉展示
- 控制层:管理特效的播放顺序和组合
- 数据层:加载和解析特效配置
-
性能监控:
func monitorPerformance() {DispatchQueue.main.async {let fps = CADisplayLink(target: self, selector: #selector(checkFPS))fps.add(to: .current, forMode: .common)} }@objc private func checkFPS(displayLink: CADisplayLink) {if displayLink.timestamp - lastTimestamp >= 1 {let fps = Double(frameCount) / (displayLink.timestamp - lastTimestamp)print("Current FPS: \(fps)")if fps < 50 {// 降低特效质量或数量EffectQualityManager.shared.reduceQuality()}lastTimestamp = displayLink.timestamp frameCount = 0}frameCount += 1 }
-
动态调整:
- 根据设备性能自动调整特效质量
- 在低电量模式下减少粒子数量
- 后台时暂停复杂特效
通过以上方案,可以实现从简单到复杂的各种特殊礼物特效,并根据实际需求灵活扩展。记得在实现过程中充分考虑性能优化和内存管理,确保特效的流畅运行。
相关文章:
iOS 直播特殊礼物特效实现方案(Swift实现,超详细!)
特殊礼物特效是提升直播互动体验的关键功能,下面我将详细介绍如何在iOS应用中实现各种高级礼物特效。 基础特效类型 1.1 全屏动画特效 class FullScreenAnimationView: UIView {static func show(with gift: GiftModel, in view: UIView) {let effectView FullS…...

9. 现代循环神经网络
文章目录 9.1. 门控循环单元(GRU)9.1.1. 门控隐状态9.1.1.1. 重置门和更新门9.1.1.2. 候选隐状态9.1.1.3. 隐状态 9.1.2. 从零开始实现9.1.2.1. 初始化模型参数9.1.2.2. 定义模型 9.1.3. 简洁实现9.1.4. 小结 9.2. 长短期记忆网络(LSTM&#…...

视频太大?用魔影工厂压缩并转MP4,画质不打折!
在日常生活中,我们常常需要将视频文件转换成不同的格式以适应各种设备或平台的播放需求。魔影工厂作为一款功能强大且操作简单的视频转换工具,深受用户喜爱。本文中简鹿办公将手把手教你如何使用魔影工厂将视频转换为MP4格式,并进行个性化设置…...
Python中tqdm进度条工具和enumerate函数的使用详解
tqdm进度条工具 tqdm 是 Python 中一个非常流行的 进度条显示工具库,常用于迭代操作的可视化,比如训练神经网络、批量数据处理等任务。 一、tqdm 是什么? tqdm 全称是 taqaddum(阿拉伯语,意为“进展”)&a…...

最宽温度范围文本格式PT1000分度表-200~850度及PT1000铂电阻温度传感器计算公式
常用PT铂电阻温度传感器 该图片来自网络,在此对图片作者表示感谢。 白色陶瓷面为测温面。 近距离图片。 常用的有PT100、PT500、PT1000,不常用的还有 PT50、PT200、PT10000等,PT代表铂电阻,后面的数字是零摄氏度时电阻值&#…...
基于Netty架构的充电桩系统设计:服务器运维如何更好保障稳定性?
Netty是一个异步事件驱动的网络应用框架,用于快速开发高性能、高可靠性的网络服务器和客户端。它本质上是NIO的封装和增强,主要针对TCP/IP协议下高性能网络通信场景。 本设计通过Netty的高性能网络通信能力,结合充电桩行业特性,实…...
操作系统学习笔记第1章 操作系统概述(灰灰题库
1.单选题 用户发起系统服务请求时,处理器处于______。 A. 用户态 B. 核心态 C. 阻塞态 D. 挂起态 第 1 题 答案:A 解析:用户态下,用户程序只能执行非特权指令 。当用户发起系统服务请求(通常通过系统调用)时…...
后端开发实习生-抖音生活服务
职位描述 ByteIntern:面向2026届毕业生(2025年9月-2026年8月期间毕业),为符合岗位要求的同学提供转正机会。 团队介绍:生活服务业务依托于抖音、抖音极速版等平台,致力于促进用户与本地服务的连接。过去一…...

机器学习算法-sklearn源起
scikit-learn(简称 sklearn)是 Python 中最流行的开源机器学习库之一,基于 NumPy、SciPy 和 Matplotlib 构建。它提供了丰富的机器学习算法和工具,适用于数据挖掘和数据分析任务。以下是其核心特点的简介: 1、sklearn主…...
Keepalived 在不同场景下的高可用方案设计与最佳实践
一、Keepalived 典型应用场景深度解析 1. Web 服务器集群:统一入口与故障容错 1.1 场景需求 核心目标:为多台 Web 服务器提供统一 VIP 入口,隐藏后端节点细节,实现故障透明切换。 挑战: 确保用户请求在主节点故障时…...

注册并创建一个微信小程序
目录 (一)前往微信公众平台,并注册一个微信小程序账号 (二)配置微信小程序 (三)创建微信小程序项目 1.流程 1.1获取小程序ID 1.2下载微信开发者工具 1.3安装微信开发者工具 2.创建项目…...
CentOS 10:启动telnet服务
参考, 鳥哥私房菜 - 第七章、網路安全與主機基本防護:限制埠口, 網路升級與 SELinux 7.3.3 埠口与服务的启动/关闭及开机时状态设定 我们知道系统的 Telnet 服务通常是以 super daemon 来控管的,请您启动您系统的 telnet 试看看。 1 要启动 …...

计算机网络——每一层的用到的设备及其作用
计算机网络基础 OSI参考模型TCP/IP协议族集线器(Hub)交换机(Switch)路由器(Router)功能特点无线路由器(家庭宽带)光猫功能 网关(Gateway)功能应用场景特点 IP…...
OpenLayers 加载鹰眼控件
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图控件是一些用来与地图进行简单交互的工具,地图库预先封装好,可以供开发者直接使用。OpenLayers具有大部分常用的控件&#x…...
Eigen与OpenCV矩阵操作全面对比:最大值、最小值、平均值
功能对比总表 功能Eigen 方法OpenCV 方法主要区别最大值mat.maxCoeff(&row, &col)cv::minMaxLoc(mat, NULL, &maxVal, NULL, &maxLoc)Eigen需要分开调用,OpenCV一次获取最小值mat.minCoeff(&row, &col)cv::minMaxLoc(mat, &minVal, NU…...
安全基础与协议分析
5.1 Web安全基础 5.1.1 Web安全基础概览(一、二) Web安全的核心目标是保护Web应用及其数据免受攻击,涵盖以下关键领域: 攻击面: 前端漏洞(XSS、CSRF)。 后端漏洞(SQL注入、RCE&a…...

【Web前端】JavaScript入门与基础(一)
JavaScript简介 JavaScript 是一种轻量级的脚本语言。所谓“脚本语言”,指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序的“脚本”。 JavaScript 是一种嵌入式(embedded)语言。它本身提供的核心语法不算…...
第一课:医学影像研究的科学思维与问题提出
课程目标: 理解科学思维在医学影像研究中的核心地位。掌握从临床实践、文献回顾及技术进展中发现医学影像研究问题的方法。学习如何凝练、评估并清晰表述一个具有研究价值的医学影像科学问题。熟悉医学影像研究问题提出的伦理考量。课程大纲与核心内容: 引言 医学影像研究的…...

前端大文件上传性能优化实战:分片上传分析与实战
前端文件分片是大文件上传场景中的重要优化手段,其必要性和优势主要体现在以下几个方面: 一、必要性分析 1. 突破浏览器/服务器限制 浏览器限制:部分浏览器对单次上传文件大小有限制(如早期IE限制4GB) 服务器限制&a…...
数据的获取与读取篇---常见的数据格式JSON
文件格式 假如你有一份想分析的数据文件,获得文件后下一步就是用代码读取它。不同的文件格式有不同的读取方法。所以读取前了解文件格式也很重要。你可能见过非常多的文件格式,例如TXT、MP3、PDF、JPEG等等。 一般可以通过文件的后缀来分辨文件的格式,例如TXT格式,一般保存…...
【python代码】一些小实验
目录 1. 测试Resnet50 ONNX模型的推理速度 1. 测试Resnet50 ONNX模型的推理速度 ############################### # 导出resnet50 模型 # 测试onnx模型推理 cpu 和 GPU 的对比 ###############################import time import numpy as np import onnxruntime as ort im…...

Linux服务器配置深度学习环境(Pytorch+Anaconda极简版)
前言: 最近做横向需要使用实验室服务器跑模型,之前用师兄的账号登录服务器跑yolo,3张3090一轮14秒,我本地一张4080laptop要40秒,效率还是快很多,(这么算一张4080桌面版居然算力能比肩3090&#…...
Vue-创建应用/挂载应用/根组件模版-.vue单文件/应用配置
目录 应用实例 根组件 挂载应用 容器元素自己将不会被视为应用的一部分 那为什么还要在被挂载标签里面写东西呢? .mount( ) 方法应该始终在整个应用配置和资源注册完成后被调用 什么是资源注册? 什么是应用实例? 什么是根实例&#…...

超低延迟音视频直播技术的未来发展与创新
引言 音视频直播技术正在深刻改变着我们的生活和工作方式,尤其是在教育、医疗、安防、娱乐等行业。无论是全球性的体育赛事、远程医疗、在线教育,还是智慧安防、智能家居等应用场景,都离不开音视频技术的支持。为了应对越来越高的需求&#x…...
虚拟文件(VFS)
核心知识点:虚拟文件系统(VFS) 1. 通俗易懂的解释 想象一下你家里的冰箱。你把食物放进去,不用管它是放在塑料盒里、玻璃罐里还是直接用保鲜膜包着,你只需要知道它在冰箱的哪个位置(比如“蔬菜抽屉里”&a…...

Java 内存模型(JMM)深度解析:理解多线程内存可见性问题
Java 内存模型(JMM)深度解析:理解多线程内存可见性问题 在 Java 编程中,多线程的运用能够显著提升程序的执行效率,但与此同时,多线程环境下的一些问题也逐渐凸显。其中,内存可见性问题是一个关…...

转移dp简单数学数论
1.转移dp问题 昨天的练习赛上有一个很好玩的起终点问题,第一时间给出bfs的写法。 但是写到后面发现不行,还得是的dp转移的写法才能完美的解决这道题目。 每个格子可以经过可以不经过,因此它的状态空间是2^(n*m)&…...
【大模型面试每日一题】Day 27:自注意力机制中Q/K/V矩阵的作用与缩放因子原理
【大模型面试每日一题】Day 27:自注意力机制中Q/K/V矩阵的作用与缩放因子原理 📌 题目重现 🌟🌟 面试官:请解释Transformer自注意力机制中Query、Key、Value矩阵的核心作用,并分析为何在计算注意力分数时…...
Ubuntu24.04 LTS安装java8、mysql8.0
在 Ubuntu 24.04 上安装 OpenJDK OpenJDK 包在 Ubuntu 24.04 的默认存储库中随时可用。 打开终端并运行以下 apt 命令: sudo apt update查看是否已经安装java java --version如果未安装会有提示,直接复制命令安装即可,默认版本: sudo apt in…...

动静态库--
目录 一 静态库 1. 创建静态库 2. 使用静态库 2.1 第一种 2.2 第二种 二 动态库 1. 创建动态库 2. 使用动态库 三 静态库 VS 动态库 四 动态库加载 1. 可执行文件加载 2. 动态库加载 一 静态库 Linux静态库:.a结尾 Windows静态库:.lib结尾…...