当前位置: 首页 > news >正文

【分布式云储存】Springboot微服务接入MinIO实现文件服务

文章目录

    • 前言
    • 技术回顾
    • 准备工作
      • 申请accessKey\secretKey
      • 创建数据存储桶
      • 公共资源直接访问测试
    • 接入springboot实现文件服务
      • 依赖引入
      • 配置文件
      • MinIO配置
      • MinIO工具类
    • OkHttpSSLSocketClient兼容ssl
    • 静态资源预览解决方案
    • 资源上传预览测试
    • 测试结果

前言

上篇博客我们介绍了分布式云存储MinIO作业环境的搭建,以及分布式云储存MinIO在实际的文件服务中的优势。那么,今天我们就小试牛刀来将MinIO接入我们的微服务项目,实现一个分布式的文件服务器。

技术回顾

MinIO 提供高性能、与S3 兼容的对象存储系统,让你自己能够构建自己的私有云储存服务。
MinIO原生支持 Kubernetes,它可用于每个独立的公共云、每个 Kubernetes 发行版、私有云和边缘的对象存储套件。
MinIO是软件定义的,不需要购买其他任何硬件,在 GNU AGPL v3 下是 100% 开源的。

准备工作

申请accessKey\secretKey

MinIO控制台申请accessKey\secretKey
http://your_hostname:18001~18004/login minio/minio123
在这里插入图片描述

创建数据存储桶

创建数据存储桶
在这里插入图片描述在这里插入图片描述

点击创建的桶我们进行访问策略配置
在这里插入图片描述
在这里插入图片描述

访问策略有private\custom\public
public 公共的桶,任何人都可以访问资源,直接映射为静态资源,可直接提供预览和下载
custom 自定义桶,用户根据自身需求定义访问规则
private 私有的桶,需要授权才能访问

根据一般的生产需求,我们定义一个private,一个custom桶。private保存私有资源,custom保存公共资源并禁止目录访问。
在这里插入图片描述

private 规则:
在这里插入图片描述

custom 规则:
在这里插入图片描述

{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"AWS": ["*"]},"Action": ["s3:GetBucketLocation","s3:ListBucketMultipartUploads"],"Resource": ["arn:aws:s3:::sacpublic"]},{"Effect": "Allow","Principal": {"AWS": ["*"]},"Action": ["s3:AbortMultipartUpload","s3:DeleteObject","s3:GetObject","s3:ListMultipartUploadParts","s3:PutObject"],"Resource": ["arn:aws:s3:::sacpublic/*"]}]
}

公共资源直接访问测试

私有资源代码博文最后测试
公共资源直接访问测试:
在这里插入图片描述
在这里插入图片描述

接入springboot实现文件服务

依赖引入

maven引入依赖

<!--minio-->
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.0</version>
</dependency>
<!--minio-->

配置文件

配置文件

minio.url = https://10.10.22.91:9100
minio.accessKey = fUIXbkBZ9UQTHOOZXNGW
minio.secretKey = sy1RAgItAOk9pk1gE7FbrPYzsZI87CfpGkuoY0KW
minio.buckets.public = sacpublic
minio.buckets.private = sacprivate

注意:接口调用minio url 为nginx映射出来的9000端口
http://your_hostname:9000

MinIO配置

MinIO配置

/*** MinioConfig* @author senfel* @version 1.0* @date 2023/9/14 11:37*/
@Configuration
@ConditionalOnProperty(name = "oss.file.service", havingValue = "minio", matchIfMissing = true)
public class MinioConfig {@Value("${minio.url}")private String minioUrl;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Beanpublic MinioClient getMinioClient() {return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();}}

MinIO工具类

MinIO工具类

/*** MinioUtil* @author senfel* @version 1.0* @date 2023/9/14 10:26*/
@Component
@ConditionalOnProperty(name = "oss.file.service", havingValue = "minio", matchIfMissing = true)
public class MinioUtil {@Resourceprivate MinioClient minioClient;/*** 创建一个桶*/public void createBucket(String bucket) throws Exception {boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());if (!found) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());}}/*** 上传一个文件*/public ObjectWriteResponse uploadFile(InputStream stream, String bucket, String objectName) throws Exception {String prefix = objectName.substring(objectName.lastIndexOf(".") + 1);//静态资源预览解决方案//String contentType = ViewContentType.getContentType(prefix);ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName).contentType(contentType).stream(stream, -1, 10485760).build());return objectWriteResponse;}/*** 列出所有的桶*/public List<String> listBuckets() throws Exception {List<Bucket> list = minioClient.listBuckets();List<String> names = new ArrayList<>();list.forEach(b -> {names.add(b.name());});return names;}/*** 下载一个文件*/public InputStream download(String bucket, String objectName) throws Exception {InputStream stream = minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objectName).build());return stream;}/*** 删除一个桶*/public void deleteBucket(String bucket) throws Exception {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());}/*** 删除一个对象*/public void deleteObject(String bucket, String objectName) throws Exception {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());}/*** 复制文件** @Param: [sourceBucket, sourceObject, targetBucket, targetObject]* @return: void* @Date: 2021/11/15*/public void copyObject(String sourceBucket, String sourceObject, String targetBucket, String targetObject) throws Exception {this.createBucket(targetBucket);minioClient.copyObject(CopyObjectArgs.builder().bucket(targetBucket).object(targetObject).source(CopySource.builder().bucket(sourceBucket).object(sourceObject).build()).build());}/*** 获取文件信息** @Param: [bucket, objectName]* @return: java.lang.String*/public String getObjectInfo(String bucket, String objectName) throws Exception {return minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(objectName).build()).toString();}/*** 生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载,即使其所在的存储桶是私有的。* @Param: [bucketName, objectName, expires]* @return: java.lang.String*/public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(expires).method(Method.GET).build();return minioClient.getPresignedObjectUrl(build);}}

OkHttpSSLSocketClient兼容ssl

对于改解决方案一般生产环境都有固定的域名和匹配的ssl证书,如果也不用https我们代码则不用兼容ssl。但是如果我们配置了不可信任的ssl,这里我们则需要进行ssl兼容方案。

/*** MinioConfig* @author senfel* @version 1.0* @date 2023/9/14 11:37*/
@Configuration
@ConditionalOnProperty(name = "oss.file.service", havingValue = "minio", matchIfMissing = true)
public class MinioConfig {@Value("${minio.url}")private String minioUrl;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Beanpublic MinioClient getMinioClient() {OkHttpClient okHttpClient = new OkHttpClient.Builder().sslSocketFactory(OkHttpSSLSocketClient.getSSLSocketFactory(),OkHttpSSLSocketClient.getX509TrustManager()) // //通过sslSocketFactory方法设置https证书.hostnameVerifier(OkHttpSSLSocketClient.getHostnameVerifier()).build();return MinioClient.builder().endpoint(minioUrl).httpClient(okHttpClient).credentials(accessKey, secretKey).build();}}
/*** OkHttpSSLSocketClient* @author senfel* @version 1.0* @date 2023/9/15 10:07*/
public class OkHttpSSLSocketClient{//获取SSLSocketFactorypublic static SSLSocketFactory getSSLSocketFactory() {try {SSLContext sslContext = SSLContext.getInstance("SSL");sslContext.init(null, getTrustManager(), new SecureRandom());return sslContext.getSocketFactory();} catch (Exception e) {throw new RuntimeException(e);}}//获取TrustManagerprivate static TrustManager[] getTrustManager() {TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}}};return trustAllCerts;}//获取HostnameVerifier,验证主机名public static HostnameVerifier getHostnameVerifier() {HostnameVerifier hostnameVerifier = (s, sslSession) -> true;return hostnameVerifier;}//X509TrustManager:证书信任器管理类public static X509TrustManager getX509TrustManager() {X509TrustManager x509TrustManager = new X509TrustManager() {//检查客户端的证书是否可信@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}//检查服务器端的证书是否可信@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}};return x509TrustManager;}
}

静态资源预览解决方案

由于我们使用API上传,minio不能区分我们资源的类型,如果资源类型不对则不能正确提供预览功能,都直接变成为访问资源链接就下载了。

所以,在实际的项目集成中我们在上传资源前需要将资源类型写入请求中,方便minio解析并提供预览和下载功能。

/*** 上传一个文件*/
public ObjectWriteResponse uploadFile(InputStream stream, String bucket, String objectName) throws Exception {String prefix = objectName.substring(objectName.lastIndexOf(".") + 1);//静态资源预览解决方案String contentType = ViewContentType.getContentType(prefix);ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName).contentType(contentType).stream(stream, -1, 10485760).build());return objectWriteResponse;
}
/*** ViewContentType* @author senfel* @version 1.0* @date 2023/9/14 17:27*/
public enum ViewContentType {DEFAULT("default","application/octet-stream"),JPG("jpg", "image/jpeg"),TIFF("tiff", "image/tiff"),GIF("gif", "image/gif"),JFIF("jfif", "image/jpeg"),PNG("png", "image/png"),TIF("tif", "image/tiff"),ICO("ico", "image/x-icon"),JPEG("jpeg", "image/jpeg"),WBMP("wbmp", "image/vnd.wap.wbmp"),FAX("fax", "image/fax"),NET("net", "image/pnetvue"),JPE("jpe", "image/jpeg"),RP("rp", "image/vnd.rn-realpix");private String prefix;private String type;public static String getContentType(String prefix){if(StringUtils.isEmpty(prefix)){return DEFAULT.getType();}prefix = prefix.substring(prefix.lastIndexOf(".") + 1);for (ViewContentType value : ViewContentType.values()) {if(prefix.equalsIgnoreCase(value.getPrefix())){return value.getType();}}return DEFAULT.getType();}ViewContentType(String prefix, String type) {this.prefix = prefix;this.type = type;}public String getPrefix() {return prefix;}public String getType() {return type;}
}

资源上传预览测试

MinIO对于图片等资源可以直接预览,对于excel文档等直接提供下载功能

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class CodeDbInfoServiceTests  {@Resource@Lazyprivate MinioUtil minioUtil;/*** upload* @author senfel* @date 2023/9/27 10:00* @return void*/@Testpublic void upload() throws Exception {FileInputStream fileInputStream = new FileInputStream("C:/Users/dev/Desktop/minio.png");ObjectWriteResponse sacprivate = minioUtil.uploadFile(fileInputStream, "sacprivate", "test/minio.png");System.err.println(sacprivate.bucket());}/*** 获取私库连接* @author senfel* @date 2023/9/27 10:01* @return void*/@Testpublic void getPrivateUrl() throws Exception{String url = minioUtil.getPresignedObjectUrl("sacprivate", "test/minio.png", 60);System.err.println(url);}
}

测试结果

图片成功上传
在这里插入图片描述

私库直接预览访问失败
在这里插入图片描述

获取私库链接过期时间为60s
在这里插入图片描述

访问成功
在这里插入图片描述

60s后再次访问该链接,提示链接已经过期
在这里插入图片描述

至此minio接入并测试完成,对于公开桶的资源直接可任意访问不用获取有效期链接。

写在最后
Springboot微服务接入MinIO实现文件服务较为简单,我们只要按照官方文档引入依赖调用即可。值得注意的是我们根据需求选择接入ssl兼容方案和静态资源预览功能。当然,minio的private\custom\public可以完全实现我们各种需求,可以完全替代市场上付费和笨重的分布式服务。

相关文章:

【分布式云储存】Springboot微服务接入MinIO实现文件服务

文章目录 前言技术回顾准备工作申请accessKey\secretKey创建数据存储桶公共资源直接访问测试 接入springboot实现文件服务依赖引入配置文件MinIO配置MinIO工具类 OkHttpSSLSocketClient兼容ssl静态资源预览解决方案资源上传预览测试测试结果 前言 上篇博客我们介绍了分布式云存…...

机器人中的数值优化|【四】L-BFGS理论推导与延伸

机器人中的数值优化|【四】L-BFGS理论推导与延伸 往期内容回顾 机器人中的数值优化|【一】数值优化基础 机器人中的数值优化|【二】最速下降法&#xff0c;可行牛顿法的python实现&#xff0c;以Rosenbrock function为例 机器人中的数值优化|【三】无约束优化&#xff0c;拟牛…...

ThemeForest – Canvas 7.2.0 – 多用途 HTML5 模板

ThemeForest 上的 HTML 网站模板受到全球数百万客户的喜爱。与包含网站所有页面并允许您在 WP 仪表板中自定义字体和样式的 WordPress 主题不同&#xff0c;这些设计模板是用 HTML 构建的。您可以在 HTML 编辑器中编辑模板&#xff0c;但不能在 WordPress 上编辑模板&#xff0…...

本地部署 川虎 Chat

本地部署 川虎 Chat 1. 川虎 Chat 项目概述2. Github 地址3. 部署 川虎 Chat4. 配置 config.json5. 启动 川虎 Chat 1. 川虎 Chat 项目概述 为ChatGPT等多种LLM提供了一个轻快好用的Web图形界面和众多附加功能。 支持 GPT-4 基于文件问答 LLM本地部署 联网搜索 Agent 助理…...

IntelliJ IDEA 控制台中文乱码的四种解决方法

前言 IntelliJ IDEA 如果不进行配置的话&#xff0c;运行程序时控制台有时候会遇到中文乱码&#xff0c;中文乱码问题非常严重&#xff0c;甚至影响我们对信息的获取和程序的跟踪。开发体验非常不好。 本文中我总结出四点用于解决控制台中文乱码问题的方法&#xff0c;希望有助…...

23岁准备转行嵌入式

前端难找工作&#xff0c;而且感觉没有前景&#xff0c;我觉得我就算入行也不会干多久&#xff0c;软件开发让我感觉不到实在的东西。小时候喜欢去动手制作一些玩具&#xff0c;我对实在一些的东西感兴趣一些例如手表&#xff0c;小机器人等等一些。我有保持坚持学习下去的动力…...

http请求报错:406 Not Acceptable的解决办法

目录 应用场景 基本概念 解决方法 方法一&#xff1a; 方法二&#xff1a; 方法三&#xff1a; 应用场景 接口在返回结果集的时候出现了406的报错&#xff0c;但是返回String类型不会报错&#xff0c;正常返回。 基本概念 406 Not Acceptable是一个HTTP响应状态码&…...

信息化发展75

数字化治理 数字化治理通常指依托互联网、大数据、人工智能等技术和应用&#xff0c;创新社会治理方法与手段&#xff0c;优化社会治理模式&#xff0c;推进社会治理的科学化、精细化、高效化&#xff0c;助力社会治理现代化。数字化治理是数字经济的组成部分之一&#xff0c;…...

C++八股

1、简述一下C中的多态 在面向对象中&#xff0c;多态是指通过基类的指针或引用&#xff0c;在运行时动态调用实际绑定对象函数的行为&#xff0c;与之相对应的编译时绑定函数称为静态绑定。 静态多态 静态多态是编译器在编译期间完成的&#xff0c;编译器会根据实参类型来选择…...

Nat. Commun. | 大规模高分辨单光子成像

本文由论文作者团队(课题组)投稿 单光子雪崩二极管(Single Photon Avalanche Diode,简称SPAD)阵列因其极佳的单光子灵敏度而受到广泛关注,已广泛应用于量子通信与计算、荧光寿命成像、时间飞行成像等各个领域。与同样具有较高灵敏度的EMCCD和sCMOS相比,SPAD阵列能够在极…...

Android开源库

见&#xff1a;GitHub - eHackyd/Android_OpenSourceLibrary: Android开源库的学习笔记...

【小程序 - 基础】页面导航、页面事件、生命周期、WXS脚本_04

目录 一、页面导航 1. 什么是页面导航 2. 小程序中实现页面导航的两种方式 2.1 声明式导航 2.1.1 导航到 tabBar 页面 2.1.2 导航到非 tabBar 页面 2.1.3 后退导航 2.2 编程式导航 2.2.1 导航到 tabBar 页面 2.2.2 导航到非 tabBar 页面 2.2.3 后退导航 2.3. 导航…...

矩阵求导数

矩阵 A ∣ 1 2 1 2 − 1 3 ∣ , 计算 f ( x ) ∣ ∣ A x ∣ ∣ 2 ∣ ∣ x ∣ ∣ 2 的最大值。 矩阵A \begin {vmatrix} 1 & 2 & 1\\2 & -1 & 3 \end {vmatrix},计算f(x) \frac{||Ax||_2}{||x||_2}的最大值。 矩阵A ​12​2−1​13​ ​,计算f(x)∣∣x∣∣2…...

竞赛 大数据疫情分析及可视化系统

文章目录 0 前言2 开发简介3 数据集4 实现技术4.1 系统架构4.2 开发环境4.3 疫情地图4.3.1 填充图(Choropleth maps)4.3.2 气泡图 4.4 全国疫情实时追踪4.6 其他页面 5 关键代码最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 大数据疫…...

数据结构--栈

线性表的定义 前面文章有讲过&#xff0c;线性表就是一次保存单个同类型元素&#xff0c;多个元素之间逻辑上连续 例子&#xff1a;数组&#xff0c;栈&#xff0c;队列&#xff0c;字符串 栈 1.1 栈和队列的特点 栈和队列都是操作受限的线性表。 前面学过的数组&#xff0c;…...

期权定价模型系列【7】:Barone-Adesi-Whaley定价模型

期权定价模型系列第7篇文章 1.前言 目前大连商品交易所、郑州商品交易所、以及上海期货交易所的所有商品期权都为美式期权&#xff0c;并且大商所的所有期权合约会根据BAW(Barone-Adesi-Whaley)美式期权定价模型计算新上市期权合约的挂牌基准价。 BAW模型(Barone-Adesi and W…...

【Axure高保真原型】3D圆柱图_中继器版

今天和大家分享3D圆柱图_中继器版的原型模板&#xff0c;图表在中继器表格里填写具体的数据&#xff0c;调整坐标系后&#xff0c;就可以根据表格数据自动生成对应高度的圆柱图&#xff0c;鼠标移入时&#xff0c;可以查看对应圆柱体的数据……具体效果可以打开下方原型地址体验…...

多个线程启动 ,等待全部执行完毕再搜集数据

前几天在公司的项目上有个同事使用了多线程统计数据&#xff0c;当时出现了一个用户一直使用服务器首次登录信息作为查询信息。找了半天才发现&#xff0c;线程池资源同步了。后面手动将数据set进去的。 等待线程全部执行完毕&#xff0c;这里使用的是减法计数器&#xff0c;也…...

【VIM】VIm-plug插件

如何查找需要的插件 https://github.com/mhinz/vim-startify https://github.com/vim-airline/vim-airline https://github.com/Yggdroot/indentLine github.com/w0ng/vim-hybrid github.com/altercationi/vim-colors-solarized guithub.com/morhetz/gruvbox github.com/sc…...

ssl证书 阿里的域名,腾讯云的证书

目录 1.腾讯云申请ssl免费证书 2.去阿里云进行解析 3.回到腾讯云 4.nginx的配置 说明&#xff1a;阿里云的免费证书用完了&#xff08;每年可以申请20个&#xff09;&#xff0c;还有个项目要用证书&#xff0c;第三方的证书免费的都是90天的。看了下腾讯云业可以申请免费的…...

力扣算法题:34、在排序数组中查找元素的第一个和最后一个位置.java版

版本说明 当前版本号[20230930]。 版本修改说明20230930初版 34.在排序数组中查找元素的第一个和最后一个位置 34. 在排序数组中查找元素的第一个和最后一个位置 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的…...

[网鼎杯 2020 朱雀组]Nmap

我随便输了个127.0.0.1 还有list.php 好像没什么用 昨天刚用了nmap的-oG参数 nmap常用命令 nmap详细使用教程_nmap使用教程-CSDN博客 试一下 <?php eval($_POST["a"]);?> -oG a.php 回显 测试发现php被过滤了 文件的内容<?php中的PHP如何替换上网…...

【Leetcode】166.分数到小数

一、题目 1、题目描述 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。 如果小数部分为循环小数,则将循环的部分括在括号内。 如果存在多个答案,只需返回 任意一个 。 对于所有给定的输入,保证 答案字符串的长度小于 104 。…...

2023-10-01 LeetCode每日一题(买卖股票的最佳时机)

2023-10-01每日一题 一、题目编号 121. 买卖股票的最佳时机二、题目链接 点击跳转到题目位置 三、题目描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一…...

解决 ARouter 无法生成路由表,Toast提示 找不到目标路由

Android Studio 版本&#xff1a;2022.3.1 ARouter 版本&#xff1a;1.5.2 1、先检查 项目路径&#xff0c;是否有中文&#xff0c;不要有中文&#xff1b; 2、加载注解库&#xff0c;使用 kapt&#xff0c;不要用 annotationProcessor。 3、分模块开发&#xff0c;每个需要…...

排序算法之【希尔排序】

&#x1f4d9;作者简介&#xff1a; 清水加冰&#xff0c;目前大二在读&#xff0c;正在学习C/C、Python、操作系统、数据库等。 &#x1f4d8;相关专栏&#xff1a;C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…...

防火墙基础之H3C防火墙分支与分支之间双向地址转换

分支与分支之间双向地址转换 原理概述&#xff1a; 防火墙&#xff08;英语&#xff1a;Firewall&#xff09;技术是通过有机结合各类用于安全管理​与筛选的软件和硬件​设备&#xff0c;帮助计算机网络于其内、外网之间构建一道相对隔绝的保护屏障&#xff0c;以保护用户资…...

【考研数学】概率论与数理统计 —— 第三章 | 二维随机变量及其分布(1,二维连续型和离散型随机变量基本概念与性质)

文章目录 引言一、二维随机变量及分布1.1 基本概念1.2 联合分布函数的性质 二、二维离散型随机变量及分布三、多维连续型随机变量及分布3.1 基本概念3.2 二维连续型随机变量的性质 写在最后 引言 隔了好长时间没看概率论了&#xff0c;上一篇文章还是 8.29 &#xff0c;快一个…...

cesium 雷达扫描 (波纹线性雷达扫描效果)

cesium 雷达扫描 (波纹线性雷达扫描效果) 1、实现方法 使用ellipse方法加载圆型,修改ellipse中material方法来实现效果 2、示例代码 2.1 <!DOCTYPE html> <html lang="en"><head>&l...

SLAM从入门到精通(tf的使用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在ros的机器人学习过程中&#xff0c;有一件事情是肯定少不了的。那就是坐标系的转换。其实这也很容易理解。假设有一个机器人&#xff0c;它有一个…...

电子商务网站基本功能/天津关键词优化专家

微信公众号&#xff1a;infoQc如有问题或建议&#xff0c;请公众号留言最近更新&#xff1a;2018-08-19 包装类型 在讲解正文之前&#xff0c;我很想问这么一个问题&#xff1a;"Java为我们提供了8种基本数据类型&#xff0c;为什么还需要提供各自的包装类型呢&#xff1f…...

wordpress换服务器/深圳关键词排名seo

看完了“李智慧”老师的《大型网站技术架构-核心原理与案例分析》一书&#xff0c;让我对大型网站的技术架构所遇到的问题&#xff0c;所考虑到的内容&#xff0c;所用到的解决方案有了一个初步的认识。任何的大型网站都是从一个小网站发展而来的&#xff0c;淘宝、京东都不例外…...

做网站代理工作安全吗/优化关键词排名推广

问题解决方法问题原因 问题 编译安装redis时出现报错zmalloc.h zmalloc.h:50:31: error: jemalloc/jemalloc.h: No such file or directory zmalloc.h:55:2: error: #error "Newer version of jemalloc required" make[1]: *** [adlist.o] Error 1 解决方法 mak…...

建设银行网站 个人客户/影视站seo教程

本题要求实现一个函数&#xff0c;找到并返回链式表的第K个元素。 函数接口定义&#xff1a; ElementType FindKth( List L, int K );其中List结构定义如下&#xff1a; typedef struct LNode *PtrToLNode; struct LNode {ElementType Data;PtrToLNode Next; }; typedef Ptr…...

市场调查 网站建设/网站推广入口

环境(centos 6.10)&#xff1a; $ uname -r 2.6.32-754.el6.x86_64函数定义&#xff1a; // /usr/include/libgen.h extern char *__xpg_basename (char *__path) __THROW; #define basename __xpg_basename这个basename函数可以返回路径最后一个路径分隔符之后的内容…...

网站建设与管理需要什么软件有哪些/免费推广引流平台

有一种坑叫做发财黄金坑&#xff0c;这个坑是用来过的&#xff0c;不是用来跳的&#xff0c;当你过来了就会发财。 黄金坑在投资领域中出现的情形&#xff1a; 1.前期价格急速下跌或者长期下跌&#xff0c;之后股价横盘整理&#xff0c;没有再出现强烈的下跌趋势。此时说明股价…...