文件分片上传
1前端
<inputtype="file"accept=".mp4"ref="videoInput"@change="handleVideoChange"style="display: none;">
2生成hash
// 根据整个文件的文件名和大小组合的字符串生成hash值,大概率确定文件的唯一性fhash(file) {// console.log("哈希字段: ", file.name+file.size.toString());return new Promise(resolve => {const spark = new SparkMD5();spark.append(file.name+file.size.toString());resolve(spark.end());})},
3生成切片
// 生成切片createChunks(file) {const result = [];for (let i = 0; i < file.size; i += this.chunkSize) {result.push(file.slice(i, i + this.chunkSize));}return result;},
4查询未上传切片的hash,断点续传
// 获取当前还没上传的序号 断点续传async askCurrentChunk(hash) {return await this.$get("/video/ask-chunk", {params: { hash: hash },headers: { Authorization: "Bearer " + localStorage.getItem("teri_token") }});},
5上传分片
// 上传分片async uploadChunk(formData) {return await this.$post("/video/upload-chunk", formData, {headers: {'Content-Type': 'multipart/form-data',Authorization: "Bearer " + localStorage.getItem("teri_token"),}})},
6上传文件
async upload() {const chunks = this.createChunks(this.selectedVideo);// 向服务器查询还没上传的下一个分片序号const result = await this.askCurrentChunk(this.hash);this.current = result.data.data;// 逐个上传分片for (this.current; this.current < chunks.length; this.current++) {const chunk = chunks[this.current];const formData = new FormData();formData.append('chunk', chunk); // 将当前分片作为单独的文件上传formData.append('hash', this.hash);formData.append('index', this.current); // 传递分片索引// 发送分片到服务器try {const res = await this.uploadChunk(formData);if (res.data.code !== 200) {// ElMessage.error("分片上传失败");this.isFailed = true;this.isPause = true;}} catch {// ElMessage.error("分片上传失败");this.isFailed = true;this.isPause = true;return;}// 暂停上传if (this.isPause) {// 取消上传彻底删除已上传分片if (this.isCancel) {await this.cancelUpload(this.hash);this.isCancel = false;}return;}this.progress = Math.round(((this.current + 1) / chunks.length) * 100); // 实时改进度条}this.progress = 100; // 上传完成再次确认为100%},
后端
1查询hash
/*** 获取视频下一个还没上传的分片序号* @param hash 视频的hash值* @return CustomResponse对象*/public CustomResponse askCurrentChunk(String hash) {CustomResponse customResponse = new CustomResponse();// 查询本地// 获取分片文件的存储目录File chunkDir = new File(CHUNK_DIRECTORY);// 获取存储在目录中的所有分片文件File[] chunkFiles = chunkDir.listFiles((dir, name) -> name.startsWith(hash + "-"));// 返回还没上传的分片序号if (chunkFiles == null) {customResponse.setData(0);} else {customResponse.setData(chunkFiles.length);}// 查询OSS当前存在的分片数量,即前端要上传的分片序号,建议分布式系统才使用OSS存储分片,单体系统本地存储分片效率更高
// int counts = ossUploadUtil.countFiles("chunk/", hash + "-");
// customResponse.setData(counts);return customResponse;}
2上传分片
/*** 上传单个视频分片,当前上传到阿里云对象存储* @param chunk 分片文件* @param hash 视频的hash值* @param index 当前分片的序号* @return CustomResponse对象* @throws IOException*/@Overridepublic CustomResponse uploadChunk(MultipartFile chunk, String hash, Integer index) throws IOException {CustomResponse customResponse = new CustomResponse();// 构建分片文件名String chunkFileName = hash + "-" + index;// 存储到本地// 构建分片文件的完整路径String chunkFilePath = Paths.get(CHUNK_DIRECTORY, chunkFileName).toString();// 检查是否已经存在相同的分片文件File chunkFile = new File(chunkFilePath);if (chunkFile.exists()) {log.warn("分片 " + chunkFilePath + " 已存在");customResponse.setCode(500);customResponse.setMessage("已存在分片文件");return customResponse;}// 保存分片文件到指定目录chunk.transferTo(chunkFile);// 存储到OSS,建议分布式系统才使用OSS存储分片,单体系统本地存储分片效率更高
// try {
// boolean flag = ossUploadUtil.uploadChunk(chunk, chunkFileName);
// if (!flag) {
// log.warn("分片 " + chunkFileName + " 已存在");
// customResponse.setCode(500);
// customResponse.setMessage("已存在分片文件");
// }
// } catch (IOException ioe) {
// log.error("读取分片文件数据流时出错了");
// }// 返回成功响应return customResponse;}
3合并
/*** 合并分片并将投稿信息写入数据库* @param vui 存放投稿信息的 VideoUploadInfo 对象*/@Transactionalpublic void mergeChunks(VideoUploadInfoDTO vui) throws IOException {String url; // 视频最终的URL// 合并到本地
// // 获取分片文件的存储目录
// File chunkDir = new File(CHUNK_DIRECTORY);
// // 获取当前时间戳
// long timestamp = System.currentTimeMillis();
// // 构建最终文件名,将时间戳加到文件名开头
// String finalFileName = timestamp + vui.getHash() + ".mp4";
// // 构建最终文件的完整路径
// String finalFilePath = Paths.get(VIDEO_DIRECTORY, finalFileName).toString();
// // 创建最终文件
// File finalFile = new File(finalFilePath);
// // 获取所有对应分片文件
// File[] chunkFiles = chunkDir.listFiles((dir, name) -> name.startsWith(vui.getHash() + "-"));
// if (chunkFiles != null && chunkFiles.length > 0) {
// // 使用流操作对文件名进行排序,防止出现先合并 10 再合并 2
// List<File> sortedChunkFiles = Arrays.stream(chunkFiles)
// .sorted(Comparator.comparingInt(file -> Integer.parseInt(file.getName().split("-")[1])))
// .collect(Collectors.toList());
// try {
System.out.println("正在合并视频");
// // 合并分片文件
// for (File chunkFile : sortedChunkFiles) {
// byte[] chunkBytes = FileUtils.readFileToByteArray(chunkFile);
// FileUtils.writeByteArrayToFile(finalFile, chunkBytes, true);
// chunkFile.delete(); // 删除已合并的分片文件
// }
System.out.println("合并完成!");
// // 获取绝对路径,仅限本地服务器
// url = finalFile.getAbsolutePath();
System.out.println(url);
// } catch (IOException e) {
// // 处理合并失败的情况 重新入队等
// log.error("合并视频失败");
// throw e;
// }
// } else {
// // 没有找到分片文件 发通知用户投稿失败
// log.error("未找到分片文件 " + vui.getHash());
// return;
// }// 合并到OSS,并返回URL地址url = ossUtil.appendUploadVideo(vui.getHash());if (url == null) {return;}// 存入数据库Date now = new Date();Video video = new Video(null,vui.getUid(),vui.getTitle(),vui.getType(),vui.getAuth(),vui.getDuration(),vui.getMcId(),vui.getScId(),vui.getTags(),vui.getDescr(),vui.getCoverUrl(),url,0,now,null);videoMapper.insert(video);VideoStats videoStats = new VideoStats(video.getVid(),0,0,0,0,0,0,0,0);videoStatsMapper.insert(videoStats);esUtil.addVideo(video);CompletableFuture.runAsync(() -> redisUtil.setExObjectValue("video:" + video.getVid(), video), taskExecutor);CompletableFuture.runAsync(() -> redisUtil.addMember("video_status:0", video.getVid()), taskExecutor);CompletableFuture.runAsync(() -> redisUtil.setExObjectValue("videoStats:" + video.getVid(), videoStats), taskExecutor);// 其他逻辑 (发送消息通知写库成功)}
4oss追加上传
/*** 将本地的视频分片文件追加合并上传到OSS* @param hash 视频的hash值,用于检索对应分片* @return 视频在OSS的URL地址* @throws IOException*/public String appendUploadVideo(@NonNull String hash) throws IOException {// 生成文件名String uuid = System.currentTimeMillis() + UUID.randomUUID().toString().replace("-", "");String fileName = uuid + ".mp4";// 完整路径名String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date()).replace("-", "");String filePathName = date + "/video/" + fileName;ObjectMetadata meta = new ObjectMetadata();// 设置内容类型为MP4视频meta.setContentType("video/mp4");int chunkIndex = 0;long position = 0; // 追加位置while (true) {File chunkFile = new File(CHUNK_DIRECTORY + hash + "-" + chunkIndex);if (!chunkFile.exists()) {if (chunkIndex == 0) {log.error("没找到任何相关分片文件");return null;}break;}// 读取分片数据FileInputStream fis = new FileInputStream(chunkFile);byte[] buffer = new byte[(int) chunkFile.length()];fis.read(buffer);fis.close();// 追加上传分片数据try {AppendObjectRequest appendObjectRequest = new AppendObjectRequest(OSS_BUCKET, filePathName, new ByteArrayInputStream(buffer), meta);appendObjectRequest.setPosition(position);AppendObjectResult appendObjectResult = ossClient.appendObject(appendObjectRequest);position = appendObjectResult.getNextPosition();} catch (OSSException oe) {log.error("OSS出错了:" + oe.getErrorMessage());throw oe;} catch (ClientException ce) {log.error("OSS连接出错了:" + ce.getMessage());throw ce;}chunkFile.delete(); // 上传完后删除分片chunkIndex++;}return OSS_BUCKET_URL + filePathName;}
相关文章:
文件分片上传
1前端 <inputtype"file"accept".mp4"ref"videoInput"change"handleVideoChange"style"display: none;">2生成hash // 根据整个文件的文件名和大小组合的字符串生成hash值,大概率确定文件的唯一性fhash(f…...
C#Lambda表达式与委托关系
1. 核心关系图示 A[委托] --> B[提供方法容器] B --> C[Lambda表达式] C --> D[委托实例的语法糖] A --> E[类型安全约束] C --> F[编译器自动生成委托实例] 2. 本质联系 2.1 类型关系 Lambda表达式是编译器生成的委托实例表达式自动匹配符合签名的…...
机器翻译和文本生成评估指标:BLEU 计算公式
📌 BLEU 计算公式 BLEU 主要由**n-gram精确匹配率(Precision)和长度惩罚(Brevity Penalty, BP)**组成。 1️⃣ n-gram 精确匹配率 计算不同长度的 n-gram(1-gram, 2-gram, ..., n-gram)在生成…...
24 python 类
在办公室里,类就像一个部门(如销售部、财务部),定义了该部门员工的共同属性(姓名、职位)和行为(处理客户、提交报表)。 一、面向对象技术简介 作为一个要入门码农的牛马࿰…...
pycharm与python版本
python 3.6-3.9 pycharm 2021版本搭配最好 python 3.8 pycharm 2019版本搭配最好 pycharm各版本下载...
23种设计模式-结构型模式-外观
文章目录 简介问题解决方案示例代码总结 简介 也称:门面模式、Facade。外观是一种结构型设计模式,能为程序库、框架或其他复杂类提供一个简单的接口。 问题 假设你必须在代码中使用某个复杂的库或框架中的众多对象。正常情况下,你需要负责…...
open3d教程 (三)点云的显示
官方文档位置: Visualization - Open3D 0.19.0 documentationhttps://www.open3d.org/docs/release/tutorial/visualization/visualization.html核心方法: o3d.visualization.draw_geometries([几何对象列表]) import open3d as o3dprint("Load …...
node.js、npm相关知识
Node.js 是一个基于 Chrome V8 JavaScript 引擎 构建的开源、跨平台的 JavaScript 运行时环境,主要用于服务器端编程。它允许开发者使用 JavaScript 编写高性能的后端服务,突破了 JavaScript 仅在浏览器中运行的限制。 npm(Node Package Man…...
大象如何学会太空漫步?美的:科技领先、To B和全球化
中国企业正处在转型的十字路口。一边是全新的技术、全新的市场机遇;一边是转型要面临的沉重负累和巨大投入,无数中国制造、中国品牌仍在寻路,而有的人已经走至半途。 近日,美的集团交出了一份十分亮眼的2024年财报。数据显示&…...
Go红队开发— 收官工具
文章目录 免责声明个人武器开发美观输出Whois查询反查ip目录扫描子域名爆破被动扫描主动扫描(字典爆破)CDN检测 免责声明 💡 本博客绝不涉及任何非法用途。 💡 使用者风险自担,违规后果自负。 💡 守法为先,技术向善。 …...
Android 应用程序包的 adb 命令
查看所有已安装应用的包名 命令:adb shell pm list packages说明:该命令会列出设备上所有已安装应用的包名。可以通过管道符|结合grep命令来过滤特定的包名,例如adb shell pm list packages | grep com.pm,这将只显示包名中包含co…...
北京南文观点:后糖酒会营销,以战略传播重构品牌信心坐标
第112届全国糖酒会落下帷幕,参展品牌面临一个关键命题。如何在流量洪流中沉淀品牌价值?北京南文(全称:南文乐园科技文化(北京)有限公司)认为,糖酒会的结束恰是算法时代品牌认知战的真…...
Qt - findChild
findChild 1. 函数原型2. 功能描述3. 使用场景4. 示例代码5. 注意事项6. 总结 在 Qt 中,每个 QObject 都可以拥有子对象,而 QObject 提供的模板函数 findChild 就是用来在对象树中查找满足特定条件的子对象的工具。下面我们详细介绍一下它的使用和注意事…...
2025年3月个人工作生活总结
本文为 2025年3月工作生活总结。 研发编码 一个curl下载失败问题的记录 问题: 某程序,指定IP和账户密码配置,再使用curl库连接sftp服务器,下载文件。在CentOS系统正常,但在某国产操作系统中失败,需要用命…...
Spring Boot 七种事务传播行为只有 REQUIRES_NEW 和 NESTED 支持部分回滚的分析
Spring Boot 七种事务传播行为支持部分回滚的分析 支持部分回滚的传播行为 REQUIRES_NEW:始终开启新事务,独立于外部事务,失败时仅自身回滚。NESTED:在当前事务中创建保存点(Savepoint),可局部…...
NVIDIA工业设施数字孪生中的机器人模拟
工业设施数字孪生中的机器人模拟 文章目录 工业设施数字孪生中的机器人模拟数字孪生技术的价值NVIDIA Omniverse平台工业机器人仿真的核心组件示例一:使用Isaac Sim创建基本机器人场景示例二:机器人运动规划和轨迹执行示例三:传感器集成与感知…...
docker安装jenkins
docker安装jenkins 1.安装javaJDK 服务器安装javaJDK ,因为我的服务器是直接集成了宝塔面板,我就直接从宝塔面板去安装JDK 最好安装17的JDK,因为后面会安装jenkins,需要17的版本 1.2查看安装是否完成 java --version 安装成功如下&#x…...
量子计算与人工智能融合的未来趋势
最近研学过程中发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。 在当今科技飞速发展…...
人工智能在生物医药-新版ChatGPT-4o辅助一键生成机制图
新版ChatGPT-4o辅助一键生成机制图 作为一位生物医学教授专家,我将基于PubMed最新研究和科研大数据信息,遵循您的要求,一步一步进行思考和预测。 核心问题:乳酸化修饰促进肾透明细胞癌(ccRCC)恶性进展的机…...
支持 MCP 协议的开源 AI Agent 项目
关键要点 研究表明,目前有多个开源 AI Agent 项目支持 MCP 协议,包括 ChatMCP、HyperChat、5ire 和 Cherry Studio 等。这些项目主要用于聊天或桌面助手,允许通过 MCP 协议连接外部数据和工具。MCP 协议是 2024 年 11 月由 Anthropic 开源的…...
JavaRedis和数据库相关面试题
JavaRedis面试题 1. Redis是什么以及Redis为什么快? Redis(Remote Dictionary Server)是一个开源的内存键值数据库,支持多种数据结构(如字符串、哈希、列表、集合等),并提供持久化、复制、…...
Android开发RxJava3延迟操作
Android开发RxJava3延迟操作 直接上代码: /*** param timeMillis 毫秒单位* desc : 延迟多少毫秒操作,* 注:它和Activity生命周期绑定,界面关闭了不会再执行delayTodoListener.delayTodo()* author : congge on 2021-03-25 15:31**/p…...
android 设置状态栏背景
一 让activity ui界面和手机状态栏一样的背景 要让 Activity 的 UI 界面和手机状态栏具有相同的背景颜色,并且能够随着深色模式和非深色模式的切换而改变颜色,你可以按照以下步骤操作: 1. 让 Activity 和 状态栏背景颜色一致 使用 window.s…...
vue 常见优化手段
文章目录 vue常见的优化手段前言使用key(避免明明相同的dom,每次更新都要重新生成)使用冻结的对象(避免无意义的响应式数据)使用函数式组件(减少vue组件实例的生成)vue3vue2使用计算属性(减少数据计算的次数)非实时绑定的表单项(避免表单过多触发监听事件)保持对象的…...
vue生命周期、钩子以及跨域问题简介
Vue 的生命周期是指 Vue 实例从创建到销毁的整个过程。在这个过程中,Vue 提供了一系列的生命周期钩子(Lifecycle Hooks),允许开发者在特定的时间点执行代码。以下是 Vue 的生命周期和钩子的简单说明: Vue 的生命周期阶…...
主相机绑定小地图
资源初始化:在类中通过 property 装饰器定义主相机、小地图相机、小地图精灵等资源属性,便于在编辑器中赋值。在 start 方法里,当确认这些资源存在后,创建渲染纹理并设置其大小,将渲染纹理与小地图相机关联,…...
关于音频采样率,比特,时间轴的理解
是的,你的理解完全正确!-ar、-af aresampleasync1000 和 -b:a 64k 分别用于控制音频的采样率、时间戳调整和比特率。它们各自有不同的作用,但共同确保音频的质量和同步性。下面我将详细解释每个参数的作用和它们之间的关系。 1. -ar 参数 作用…...
三、FFmpeg学习笔记
FFmpeg是一个开源、跨平台的多媒体处理框架,能够实现音视频的录制、转换、剪辑、编码、解码、流媒体传输、过滤与后期处理等几乎所有常见的多媒体操作。其强大之处在于几乎支持所有的音视频格式、编解码器和封装格式,是业界公认的“瑞士军刀”。 FFmp…...
什么是 Java 泛型
一、什么是 Java 泛型? 泛型(Generics) 是 Java 中一种强大的编程机制,允许在定义类、接口和方法时使用类型参数。通过泛型,可以将数据类型作为参数传递,从而实现代码的通用性和类型安全。 简单来说&…...
从 WPF 到 MAUI:跨平台 UI 开发的进化之路
一、引言 在软件开发领域,用户界面(UI)开发一直是至关重要的环节。随着技术的不断发展,开发者对于创建跨平台、高性能且美观的 UI 需求日益增长。Windows Presentation Foundation(WPF)和 .NET Multi - pl…...
Docker学习之dockerfile篇(day8)
文章目录 前言一、问题描述二、具体内容1. Docker 镜像原理2. Docker 镜像制作3. Dockerfile 概念Dockerfile 的基本结构: 4. Dockerfile 关键字5. Docker 实战案例5.1 基于 Nginx 构建 Web 服务器 6. 验证与总结6.1 验证 Dockerfile6.2 总结 前言 Docker 是一种轻…...
Kotlin 作用域函数:apply、let、run、with、also
在 Kotlin 开发中,作用域函数(Scope Functions)是一组能让代码更简洁、更函数式的高阶函数。它们通过不同的作用域规则和返回值设计,解决了对象配置、空安全处理、链式操作等常见场景问题。本文将结合核心特性、代码示例和对比表格…...
Java 线程池与 Kotlin 协程 高阶学习
以下是Java 线程池与 Kotlin 协程 高阶学习的对比指南,结合具体代码示例,展示两者在异步任务处理中的差异和 Kotlin 的简化优势: 分析: 首先,我们需要回忆Java中线程池的常见用法,比如通过ExecutorService创…...
C++学习笔记(三十三)——forward_list
一、std::forward_list (1) forward_list与其适用场景 std::forward_list 是 C的STL中的单向链表(Singly Linked List),它相比 std::list(双向链表)更轻量,适用于仅需要单向遍历的场景。 主要特点&#…...
ROS订阅相机图像识别颜色并发布识别信息
一、前言 区别于之前的直接驱动相机,这里改为读取图像话题进行处理,原因是如果opencv驱动相机后只能单一使用,就限制了其他识别功能(除非将原始图像发布出来),所以这里改成可以读取任意相机图像话题的方法…...
Redis-15.在Java中操作Redis-Spring Data Redis使用方式-操作集合类型的数据
一.操作集合类型的数据 package com.sky.test;import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.*;import j…...
第十一届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
1.字串排序 不会做,感觉挺难的,有兴趣的可以看下面题解 #include <iostream> #include <string.h> using namespace std; int V; int len;//符合交换次数V,字符串长度最小值 int now; //当前已经构造好的那一部分字符串逆序对个数…...
CentOS 安装 zip
安装软件 sudo yum install zip unzip # CentOS 7 sudo dnf install zip unzip # CentOS 8/9压缩文件 # 压缩单个文件 zip 压缩包名.zip 文件1# 压缩多个文件 zip 压缩包名.zip 文件1 文件2 文件3# 压缩目录(包含子目录) zip -r 压缩包名.zip 目…...
FastPillars:一种易于部署的基于支柱的 3D 探测器
FastPillars:一种易于部署的基于支柱的 3D 探测器Report issue for preceding element Sifan Zhou 1 , Zhi Tian 2 , Xiangxiang Chu 2 , Xinyu Zhang 2 , Bo Zhang 2 , Xiaobo Lu11{}^{1}start_FLOATSUPERSCRIPT 1 end_FLOATSUPERSCRIPT11footnotemark: 1 Chengji…...
LVS高可用负载均衡
一、项目图 二、主机规划 主机系统安装应用网络IPclientredhat 9.5无NAT192.168.72.115/24lvs-masterredhat 9.5ipvsadm,keepalivedNAT192.168.72.116/24 VIP 192.168.72.100/32lvs-backupredhat 9.5ipvsadm,keepalivedNAT192.168.72.117/24 VIP 192.168…...
Kafka延迟队列实现分级重试
技术方案 方案背景 Kafka队列消息消费处理过程中,发生处理异常,需要实现重试机制,并基于重试次数实现不同延迟时间重试方案。 方案介绍 通过实现Kafka延迟队列来实现消息重试机制。 目标: 支持所有业务场景的延迟重试支持多…...
谷粒微服务高级篇学习笔记整理---异步线程池
多线程回顾 多线程实现的4种方式 1. 继承 Thread 类 通过继承 Thread 类并重写 run() 方法实现多线程。 public class MyThread extends Thread {Overridepublic void run() {System.out.println("线程运行: " Thread.currentThread().getName());} }// 使用 pub…...
3.第二阶段x64游戏实战-分析人物移动实现人物加速
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:2.第二阶段x64游戏实战-x64dbg的使用 想找人物的速度,就需要使用Ch…...
MQTT 服务器(emqx)搭建及使用(一)
一. EMQX 服务器搭建 1.下载EMQX 下载链接:Windows | EMQX 文档 官方手册 2.下载内容解压至盘符根目录 3.进入bin文件夹,在地址栏输入cmd 4.依次输入下面命令安装服务 .\emqx.cmd install .\emqx.cmd console 5.设置自启动 创建批处理文件&#x…...
什么是SSE和websocket
以下是 SSE(Server-Sent Events) 和 WebSocket 在大模型(如 ChatGPT)流式输出中的实际例子对比,包含代码实现和场景分析: —### 1. SSE(Server-Sent Events)#### 场景 大模型生成文本…...
蓝桥杯专项复习——二分查找、二分答案
目录 二分查找、二分答案基础知识 二分查找模版 【模版题】数的范围 借教室 二分查找、二分答案基础知识 二分模版 二分查找 【模版题】数的范围 输入样例 6 3 1 2 2 3 3 4 3 4 5输出样例 3 4 5 5 -1 -1 思路: 对应两个模版,起始位置是对应第一…...
Android学习总结之Kotlin 协程
一、引言 在 Android 开发中,异步任务处理是绕不开的话题。传统的线程、Handler、AsyncTask 等方案要么过于繁琐,要么存在生命周期管理问题。Kotlin 协程的出现,以优雅的语法和强大的结构化并发能力,成为解决异步编程难题的理想方…...
docker的与使用
1 docker初体验 1.1 docker简介 问题:为什么会有docker出现? 一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对…...
解决ubuntu18.04无法进入系统桌面
解决ubuntu18.04无法进入系统桌面 解决ubuntu18.04无法进入系统桌面前言1、原因2、解决现象总结 前言 Vmware虚拟机运行跑Linux项目,没有关掉运行的进程就关机,导致系统无法进入系统桌面,一直卡在系统的初始化界面,按下快捷键发…...
Docker学习之容器虚拟化与虚拟机的区别(day11)
文章目录 前言一、问题描述二、具体内容1. 虚拟机(VM)2. 容器虚拟化(Docker)容器虚拟化的核心技术 三、总结1. 资源占用对比2. 适用场景3. 结论 前言 在现代软件开发和部署过程中,Docker 和虚拟机(VM&…...