阿里 对象存储OSS 云存储服务

1.简介

对象存储服务(Object Storage Service ,OSS) 是一种 海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。

2.如何使用。参考文档

 

看文档,说的很明白,这里就不演示了

3. SpringCloudAlibaba-OSS

spring-cloud-alibaba/README-zh.md at 2022.x · alibaba/spring-cloud-alibaba · GitHub

好像新版本没有starter了

自己封装一下原生API吧

package com.jmj.gulimall.product.config;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OssClientConfiguration {

    @Value("${spring.cloud.alicloud.access-key}")
    private String accessKey;
    @Value("${spring.cloud.alicloud.secret-key}")
    private String secretKey;
    @Value("${spring.cloud.alicloud.endpoint}")
    private String endpoint;

    @Bean
    public OSS ossClient() {
        // 创建OSSClient实例。
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKey, secretKey);
        // 创建ClientBuilderConfiguration。
        // ClientBuilderConfiguration是OSSClient的配置类,可配置代理、连接超时、最大连接数等参数。
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        // 设置Socket层传输数据的超时时间,默认为50000毫秒。
        conf.setSocketTimeout(10000);
        // 设置建立连接的超时时间,默认为50000毫秒。
        conf.setConnectionTimeout(10000);
        // 设置失败请求重试次数,默认为3次。
        conf.setMaxErrorRetry(5);
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider,conf);
        return ossClient;
    }


}
package com.jmj.gulimall.product.ossclient;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

@Component
@Slf4j
public class OssClientTemplate {

    @Autowired
    private OSS ossClient;

    public Boolean uploadFile(String bucketName, String objectName, File file) {
        // 创建PutObjectRequest对象。
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, file);
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader("x-oss-forbid-overwrite", true);
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            putObjectRequest.setMetadata(metadata);
            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            log.info("上传成功:文件名 {}", objectName);
            return true;
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message:" + oe.getErrorMessage());
            log.error("Error Code:" + oe.getErrorCode());
            log.error("Request ID:" + oe.getRequestId());
            log.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message:" + ce.getMessage());
        }
        return false;
    }

    public Boolean uploadFile(String bucketName, String objectName, String content){
        // 创建PutObjectRequest对象。
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content.getBytes());
        try {

            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, byteArrayInputStream);
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader("x-oss-forbid-overwrite", true);
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            putObjectRequest.setMetadata(metadata);
            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            log.info("上传成功:文件名 {}", objectName);
            return true;
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message:" + oe.getErrorMessage());
            log.error("Error Code:" + oe.getErrorCode());
            log.error("Request ID:" + oe.getRequestId());
            log.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message:" + ce.getMessage());
        }finally {
            if (byteArrayInputStream!=null){
                try {
                    byteArrayInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    public Boolean uploadFile(String bucketName, String objectName, InputStream inputStream){
        // 创建PutObjectRequest对象。
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader("x-oss-forbid-overwrite", true);
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            putObjectRequest.setMetadata(metadata);
            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            log.info("上传成功:文件名 {}", objectName);
            return true;
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message:" + oe.getErrorMessage());
            log.error("Error Code:" + oe.getErrorCode());
            log.error("Request ID:" + oe.getRequestId());
            log.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message:" + ce.getMessage());
        }finally {
            if (inputStream!=null){
                try {
                    //其实流已经被关闭了,我再关闭一下保险一点
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }
    public Boolean uploadFile(String objectName, InputStream inputStream){
        // 创建PutObjectRequest对象。
        return uploadFile("gulimall-jmj", objectName, inputStream);
    }
}

4.后端签名直传

package com.jmj.gulimall.third.config;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.jmj.gulimall.third.ossclient.OssClientTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties({OssConfigurationProperties.class})
@Slf4j
@RefreshScope //动态从配置中心获取配置
public class OssClientConfiguration {

    @Autowired
    private OssConfigurationProperties ossConfigurationProperties;

    @Bean
    public OSS ossClient() {
        // 创建OSSClient实例。
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(ossConfigurationProperties.getAccessKey(), ossConfigurationProperties.getSecretKey());
        // 创建ClientBuilderConfiguration。
        // ClientBuilderConfiguration是OSSClient的配置类,可配置代理、连接超时、最大连接数等参数。
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        // 设置是否支持CNAME。CNAME用于将自定义域名绑定到目标Bucket。
        conf.setSupportCname(true);
        // 设置Socket层传输数据的超时时间,默认为50000毫秒。
        conf.setSocketTimeout(10000);
        // 设置建立连接的超时时间,默认为50000毫秒。
        conf.setConnectionTimeout(10000);
        // 设置失败请求重试次数,默认为3次。
        conf.setMaxErrorRetry(5);
        OSS ossClient = new OSSClientBuilder().build(ossConfigurationProperties.getEndpoint(), credentialsProvider, conf);
        log.info("ossClient初始化完成,properties={}",ossConfigurationProperties);
        return ossClient;
    }


    @Bean
    public OssClientTemplate ossClientTemplate(OSS ossClient) {
        return new OssClientTemplate(ossClient,ossConfigurationProperties);
    }

}
package com.jmj.gulimall.third.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;

@ConfigurationProperties(prefix = "spring.cloud.alicloud")
@Data
@RefreshScope //动态从配置中心获取配置
public class OssConfigurationProperties {

    private String accessKey;

    private String secretKey;

    private String endpoint;

    private String regionEnd;

    private String bucket;



}
package com.jmj.gulimall.third.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.jmj.gulimall.third.common.R;
import com.jmj.gulimall.third.config.OssConfigurationProperties;
import com.jmj.gulimall.third.ossclient.OssClientTemplate;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/oss")
public class OssController {

    @Autowired
    private OssClientTemplate ossClientTemplate;

    @Autowired
    private OssConfigurationProperties properties;

    @GetMapping("/policy")
    public R policy(HttpServletRequest request, HttpServletResponse response) {

        // 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。
//                String callbackUrl = "https://192.168.0.0:8888";
        // 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String formatDate = simpleDateFormat.format(new Date());
        String dir = formatDate + "/";

        OSS ossClient = ossClientTemplate.getOssClient();
        String accessKeyId = properties.getAccessKey();
        String regionEnd = properties.getRegionEnd();
        String bucket = properties.getBucket();
        String host = "https://" + bucket + "." + regionEnd;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            // PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String accessId = accessKeyId;
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            // respMap.put("expire", formatISO8601Date(expiration));
            return R.ok().put("data",respMap);

        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            log.error(e.getMessage(), e);
        }
        return  R.error("上传签名异常");
    }


}
package com.jmj.gulimall.third.ossclient;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.jmj.gulimall.third.config.OssConfigurationProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
public class OssClientTemplate {

    private OSS ossClient;

    public OSS getOssClient() {
        return ossClient;
    }
    private OssConfigurationProperties properties;

    public OssClientTemplate(OSS ossClient, OssConfigurationProperties properties) {
        this.ossClient = ossClient;
        this.properties = properties;
    }

    public Boolean uploadFile(String bucketName, String objectName, File file) {
        // 创建PutObjectRequest对象。
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, file);
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader("x-oss-forbid-overwrite", true);
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            putObjectRequest.setMetadata(metadata);
            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            log.info("上传成功:文件名 {}", objectName);
            return true;
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message:" + oe.getErrorMessage());
            log.error("Error Code:" + oe.getErrorCode());
            log.error("Request ID:" + oe.getRequestId());
            log.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message:" + ce.getMessage());
        }
        return false;
    }

    public Boolean uploadFile(String bucketName, String objectName, String content){
        // 创建PutObjectRequest对象。
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content.getBytes());
        try {

            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, byteArrayInputStream);
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader("x-oss-forbid-overwrite", true);
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            putObjectRequest.setMetadata(metadata);
            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            log.info("上传成功:文件名 {}", objectName);
            return true;
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message:" + oe.getErrorMessage());
            log.error("Error Code:" + oe.getErrorCode());
            log.error("Request ID:" + oe.getRequestId());
            log.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message:" + ce.getMessage());
        }finally {
            if (byteArrayInputStream!=null){
                try {
                    byteArrayInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    public Boolean uploadFile(String bucketName, String objectName, InputStream inputStream){
        // 创建PutObjectRequest对象。
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader("x-oss-forbid-overwrite", true);
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            putObjectRequest.setMetadata(metadata);
            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            log.info("上传成功:文件名 {}", objectName);
            return true;
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message:" + oe.getErrorMessage());
            log.error("Error Code:" + oe.getErrorCode());
            log.error("Request ID:" + oe.getRequestId());
            log.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message:" + ce.getMessage());
        }finally {
            if (inputStream!=null){
                try {
                    //其实流已经被关闭了,我再关闭一下保险一点
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }
    public Boolean uploadFile(String objectName, InputStream inputStream){
        // 创建PutObjectRequest对象。
        return uploadFile(properties.getBucket(), objectName, inputStream);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/518075.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

水离子雾化壁炉与传统壁炉的区别与比较

水离子雾化壁炉与传统壁炉在工作原理、燃料、安全性和环保性等方面存在明显的区别和比较&#xff1a; 工作原理&#xff1a; 传统壁炉&#xff1a;传统壁炉通常使用木材、煤炭、天然气等燃料&#xff0c;并通过燃烧产生真实的火焰和热量。 水离子雾化壁炉&#xff1a;水离子雾…

备考ICA----Istio实验16---HTTP流量授权

备考ICA----Istio实验16—HTTP流量授权 1. 环境准备 kubectl apply -f istio/samples/bookinfo/platform/kube/bookinfo.yaml kubectl apply -f istio/samples/bookinfo/networking/bookinfo-gateway.yaml访问测试 curl -I http://192.168.126.220/productpage2. 开启mtls m…

MATLAB入门教程(带详细注释的MATLAB代码)

使用方法 将mlx文件在MATLAB上运行&#xff0c;即可得到下列结果&#xff1a; 完整代码 给出mlx文件的全文 MATLAB软件入门分析 Date&#xff1a;2023年3月13日 Author&#xff1a;Evand 入门综述 使用matlab编程时&#xff0c;通常使用.m文件&#xff0c;把所有代码编好后…

JAVA毕业设计133—基于Java+Springboot+Vue的网上宠物店商城管理系统(源代码+数据库+12000字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootVue的网上宠物店商城管理系统(源代码数据库12000字论文)133 一、系统介绍 本项目前后端分离&#xff0c;分为管理员、用户两种角色 1、用户&#xff1a; 注册…

注意,这类人无法在视频号开店!

我是王路飞。 视频号也可以开店铺去卖货了吗&#xff1f; 是的&#xff01;其实早在22年的时候&#xff0c;视频号就上线【小店】功能了&#xff0c;可以通过短视频、直播达人带货的形式&#xff0c;帮助商家转化商品。 当然了&#xff0c;视频号小店跟我一直在科普的抖音小…

团体程序设计天梯赛-练习集 01

天梯赛题解合集 团体程序设计天梯赛-练习集 (L1-001 - L1-012) 团体程序设计天梯赛-练习集 (L1-013 - L1-024) 团体程序设计天梯赛-练习集 (L1-025 - L1-036) 团体程序设计天梯赛-练习集 (L1-037 - L1-048) L1-001 Hello World 输出题 样例 输入 输出 Hello World!思…

kafka集群介绍+部署Filebeat+Kafka+ELK

一、消息队列 1、为什么需要消息队列&#xff08;MQ&#xff09; 主要原因是由于在高并发环境下&#xff0c;同步请求来不及处理&#xff0c;请求往往会发生阻塞。比如大量的请求并发访问数据库&#xff0c;导致行锁表锁&#xff0c;最后请求线程会堆积过多&#xff0c;从而触…

Mac电脑清理垃圾软件 Mac电脑清理垃圾的文件在哪 cleanMyMac X 4.8.0激活号码

Mac用户经常会有这样一些烦恼&#xff0c;比如软件之间的管理&#xff0c;应用生成的缓冲文件怎样删除&#xff0c;还有软件的卸载等等... 如何有效清理Mac中的垃圾文件&#xff0c;删除多余的软件成为Mac用户迫切的需求。本文就为大家介绍几款好用的Mac电脑清理垃圾软件&#…

AJAX —— 学习(一)

目录 一、原生 AJAX &#xff08;一&#xff09;AJAX 介绍 1.理解 2.作用 3.最大的优势 4.应用例子 &#xff08;二&#xff09;XML 介绍 1.理解 2.作用 &#xff08;三&#xff09;AJAX 的特点 1.优点 2.缺点 二、HTTP 协议 &#xff08;一&#xff09;HTTP 介…

GPT3, llama2, InternLM2技术报告对比

GPT3&#xff08;September 22, 2020&#xff09;是大语言应用的一个milestone级别的作品&#xff0c;Llama2&#xff08;February 2023&#xff09;则是目前开源大模型中最有影响力的作品&#xff0c;InternLM2&#xff08;2023.09.20&#xff09;则是中文比较有影响力的作品。…

05 - 7 段十进制数码管显示

---- 整理自B站UP主 踌躇月光 的视频 1. 实验设计 根据前一节的内容&#xff0c;这里也通过 ROM 的方法显示十进制。这里我们设计显示 3 位十进制数&#xff0c;需要三个数码管&#xff0c;地址位宽为 8&#xff0c;数据位宽为 12。 A7A6A5A4A3A2A1A0number000000000000000011…

SambaNova 芯片:深入解析其架构和高性能秘诀

SambaNova——一家总部位于帕洛阿尔托的公司已经筹集了超过10亿美元的风险投资&#xff0c;不会直接向公司出售芯片。相反&#xff0c;它出售其定制技术堆栈的访问权限&#xff0c;该堆栈具有专门为运行最大的人工智能模型而设计的专有硬件和软件。 最近&#xff0c;SambaNova…

【科研笔记】知识星球不可选择内容爬虫

知识星球不可选择内容爬虫 1 背景2 实现3 拓展遗留问题1 背景 针对与知识星球中,电脑打开网页不可选择复制粘贴的问题,进行爬虫处理,获取网页的内容,并保存在本地 2 实现 需要下载python,和爬虫的第三方库selenium,可以查看博客中有关selenium的内容进行回顾。当前使用…

在云端遇见雨云:一位服务器寻觅者的指南

引言&#xff1a;寻觅一座云端归宿 当我踏入数字世界的边缘&#xff0c;带着对网络的探索与期待&#xff0c;我迫切需要一座安全可靠的数字栖息地。云计算技术正如一场魔法般的变革&#xff0c;而在这片广袤的云端中&#xff0c;雨云就像是一位友善的向导&#xff0c;引领我穿越…

最优算法100例之28-n个骰子点数和出现的次数

专栏主页&#xff1a;计算机专业基础知识总结&#xff08;适用于期末复习考研刷题求职面试&#xff09;系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 把n个骰子扔在地上&#xff0c;所有骰子朝上一面的点数之和为S。输入n&#xff0c;打印出S的…

OpenTofu路在何方:定量分析Terraform issue数据,洞察用户需求|OpenTofu Day 闪电演讲

数澈软件 Seal 首席架构师李平辉提交的演讲议题“Alias TerraformTofu. Job’s Done, Now What?”入选 KubeCon EU 同场活动 OpenTofu Day&#xff0c;本文为演讲实录。 大家好&#xff0c;我是 Lawrence&#xff0c;是 Seal 的首席架构师。今天将由我为大家带来 Lightening T…

Linux: linux常见操作指令

目录 01.ls 指令 02. pwd命令 03. cd 指令 04. touch指令 05.mkdir指令&#xff08;重要&#xff09; 06.rmdir指令 && rm 指令&#xff08;重要&#xff09; 07.man指令&#xff08;重要&#xff09; 07.cp指令&#xff08;重要&#xff09; 08.mv指令&#…

如何创建一个TCP多人聊天室?

一、什么是TCP&#xff1f; TCP&#xff08;Transmission Control Protocol&#xff09;是一种可靠的 面向连接的协议 &#xff0c;可以保证数据在传输过程中不会丢失、重复或乱序。 利用TCP实现简单聊天程序&#xff0c;需要客户端和服务器端之间建立TCP连接&#xff0c;并通…

【数据分析面试】10. 计算平均通勤时间(SQL:timestampdiff() 和datediff()区别)

题目 假设你在Uber工作。rides表包含了关于Uber用户在美国各地的行程信息。 编写一个查询&#xff0c;以获取纽约&#xff08;NY&#xff09;每位通勤者的平均通勤时间&#xff08;以分钟为单位&#xff09;&#xff0c;以及纽约所有通勤者的平均通勤时间&#xff08;以分钟为…

谈谈 MySQL 的锁

前言 在 MySQL 中&#xff0c;锁这个定义其实还是蛮重要的。经过我这几天的学习&#xff0c;我感觉锁是一个可以说难又可以说不难的知识点。难就难在锁可以与事务、多线程、并发结合在一起&#xff0c;这就很难了。但是&#xff0c;假如锁没有结合这些知识点&#xff0c;就单单…