概念

hadoop是一个大数据的分布式存储,调度,计算框架。也可以说是一个生态圈,包含很多技术:Hive、Hbase、Flume、Kafka...

Hadoop的优点

  • Hadoop具有存储和处理数据能力的高可靠性。
  • Hadoop通过可用的计算机集群分配数据,完成存储和计算任务,这些集群可以方便地扩展到数以
  • 千计的节点中,具有高扩展性。
  • Hadoop能够在节点之间进行动态地移动数据,并保证各个节点的动态平衡,处理速度非常快,具
  • 有高效性。
  • Hadoop能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配,具有高容错性。

Hadoop的缺点

  • Hadoop不适用于低延迟数据访问。
  • Hadoop不能高效存储大量小文件。
  • Hadoop不支持多用户写入并任意修改文件。

集群搭建

下载:https://archive.apache.org/dist/hadoop/common/hadoop-2.9.2/

集群规划

框架linux121linux122linux123
HDFSNameNode,DataNodeDataNodeSecondaryNameNode,DataNode
YARNNodeManagerNodeManagerNodeManager,ResourceManager

解压到安装目录:tar -zxvf hadoop-2.9.2.tar.gz -C /opt/lxq/servers

编辑环境变量:vim /etc/profile

# HADOOP_HOME
export HADOOP_HOME=/opt/lxq/servers/hadoop-2.9.2
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin

使环境变量生效:source /etc/profile

验证hadoop:hadoop version

集群配置

vim hadoop-env.sh
export JAVA_HOME=/opt/lxq/servers/jdk1.8.0_231
vim core-site.xml
<!-- 指定HDFSNameNode的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://linux121:9000</value>
</property>
<!-- 指定Hadoop运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/lxq/servers/hadoop-2.9.2/data/tmp</value>
</property>
vim hdfs-site.xml
<!-- 指定Hadoop辅助名称节点主机配置 -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>linux123:50090</value>
</property>
<!--副本数量 -->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
vim slaves 这里要注意不能有空格,不能有空行
linux121
linux122
linux123
vim mapred-env.sh
export JAVA_HOME=/opt/lxq/servers/jdk1.8.0_231
mv mapred-site.xml.template mapred-site.xml
vim mapred-site.xml
<!-- 指定MR运行在Yarn-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 历史服务器端地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>linux121:10020</value>
</property>
<!-- 历史服务器web端地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>linux121:19888</value>
</property>
<!-- 文件压缩 -->
<property>
<name>mapreduce.output.fileoutputformat.compress</name>
<value>true</value>
</property>
<property>
<name>mapreduce.output.fileoutputformat.compress.type</name>
<value>RECORD</value>
</property>
<property>
<name>mapreduce.output.fileoutputformat.compress.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
vim yarn-site.xml
<!-- 指定YARNResourceManager的地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>linux123</value>
</property>
<!-- Reducer获取数据的方式 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 日志聚集功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 日志保留时间设置7 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
<property>
<name>yarn.log.server.url</name>
<value>http://linux121:19888/jobhistory/logs</value>
</property>
<!-- 指定我们的任务调度使用fairScheduler的调度方式 -->
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
<description>In case you do not want to use the default scheduler</description>
</property>
Hadoop安装目录/etc/hadoop创建fair-scheduler.xm文件
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<allocations>
<defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
<queue name="root" >
<queue name="default">
<aclAdministerApps>*</aclAdministerApps>
<aclSubmitApps>*</aclSubmitApps>
<maxResources>9216 mb,4 vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<minResources>1024 mb,1vcores</minResources>
<minSharePreemptionTimeout>1000</minSharePreemptionTimeout>
<schedulingPolicy>fair</schedulingPolicy>
<weight>7</weight>
</queue>
<queue name="queue1">
<aclAdministerApps>*</aclAdministerApps>
<aclSubmitApps>*</aclSubmitApps>
<maxResources>4096 mb,4vcores</maxResources>
<maxRunningApps>5</maxRunningApps>
<minResources>1024 mb, 1vcores</minResources>
<minSharePreemptionTimeout>1000</minSharePreemptionTimeout>
<schedulingPolicy>fair</schedulingPolicy>
<weight>3</weight>
</queue>
</queue>
<queuePlacementPolicy>
<rule create="false" name="specified"/>
<rule create="true" name="default"/>
</queuePlacementPolicy>
</allocations>

赋予权限:chown -R root:root /opt/lxq/servers/hadoop-2.9.2

安装分发工具:yum install -y rsync

用法:rsync -rvl /opt/lxq/software/ root@linux122:/opt/lxq/software

编写分发脚本 vim /usr/local/bin/rsync-script

#!/bin/bash
#1 获取命令输入参数的个数,如果个数为0,直接退出命令
paramnum=$#
if((paramnum==0)); then
echo no params;
exit;
fi
#2 根据传入参数获取文件名称
p1=$1
file_name=`basename $p1`
echo fname=$file_name
#3 获取输入参数的绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir
#4 获取用户名称
user=`whoami`
#5 循环执行rsync
for((host=121; host<124; host++)); do
echo ------------------- linux$host --------------
rsync -rvl $pdir/$file_name $user@linux$host:$pdir
done

赋予脚本权限:chmod 777 /usr/local/bin/rsync-script

拓展一些

chmod命令

用来变更文件或目录的权限。在UNIX系统家族里,文件或目录权限的控制分别以读取、写入、执行3种一般权限来区分,另有3种特殊权限可供运用。用户可以使用chmod指令去变更文件与目录的权限,设置方式采用文字或数字代号皆可。符号连接的权限无法变更,如果用户对符号连接修改权限,其改变会作用在被连接的原始文件。

权限范围的表示法如下:

u User,即文件或目录的拥有者;

g Group,即文件或目录的所属群组;

o Other,除了文件或目录拥有者或所属群组之外,其他用户皆属于这个范围;

a All,即全部的用户,包含拥有者,所属群组以及其他用户;

r 读取权限,数字代号为“4”; w 写入权限,数字代号为“2”;

x 执行或切换权限,数字代号为“1”;

- 不具任何权限,数字代号为“0”;

s 特殊功能说明:变更文件或目录的权限。

语法 chmod(选项)(参数)

选项

-c或——changes:效果类似“-v”参数,但仅回报更改的部分;

-f或--quiet或——silent:不显示错误信息;

-R或——recursive:递归处理,将指令目录下的所有文件及子目录一并处理;

-v或——verbose:显示指令执行过程;

--reference=<参考文件或目录>:把指定文件或目录的所属群组全部设成和参考文件或目录的所属群组相同;

<权限范围>+<权限设置>:开启权限范围的文件或目录的该选项权限设置;

<权限范围>-<权限设置>:关闭权限范围的文件或目录的该选项权限设置;

<权限范围>=<权限设置>:指定权限范围的文件或目录的该选项权限设置;

参数

权限模式:指定文件的权限模式;

文件:要改变权限的文件。

例:

rwx rw- r-- r=读取属性  //值=4

w=写入属性  //值=2

x=执行属性  //值=1

chmod u+x,g+w f01  //为文件f01设置自己可以执行,组员可以写入的权限

chmod u=rwx,g=rw,o=r f01

chmod 764 f01

chmod a+x f01  //对文件f01的u,g,o都设置可执行属性 文件的属主和属组属性设置

chown user:market f01  //把文件f01给uesr,添加到market组

ll -d f1 查看目录f1的属性

chown命令

改变某个文件或目录的所有者和所属的组,该命令可以向某个用户授权,使该用户变成指定文件的所有者或者改变文件所属的组。用户可以是用户或者是用户D,用户组可以是组名或组id。文件名可以使由空格分开的文件列表,在文件名中可以包含通配符。 只有文件主和超级用户才可以便用该命令。

语法 chown(选项)(参数)

选项

-c或——changes:效果类似“-v”参数,但仅回报更改的部分;

-f或--quite或——silent:不显示错误信息;

-h或--no-dereference:只对符号连接的文件作修改,而不更改其他任何相关文件;

-R或——recursive:递归处理,将指定目录下的所有文件及子目录一并处理;

-v或——version:显示指令执行过程;

--dereference:效果和“-h”参数相同;

--help:在线帮助;

--reference=<参考文件或目录>:把指定文件或目录的拥有者与所属群组全部设成和参考文件或目录的拥有者与所属群组相同;

--version:显示版本信息。

参数

用户:组:指定所有者和所属工作组。当省略“:组”,仅改变文件所有者;

文件:指定要改变所有者和工作组的文件列表。支持多个文件和目标,支持shell通配符。

实例 将目录/usr/meng及其下面的所有文件、子目录的文件主改成 liu:

chown -R liu /usr/meng

分发hadoop到集群其它节点:rsync-script /opt/lxq/servers/hadoop-2.9.2

第一次启动格式化(不是第一次不用这句命令):hadoop namenode -format

群起yarn:start-yarn.sh [stop-yarn.sh]

群起hdfs:start-dfs.sh [stop-dfs.sh]

历史服务器起关命令

$HODOOP_HOME/sbin/mr-jobhistory-daemon.sh start historyserver 

$HODOOP_HOME/sbin/mr-jobhistory-daemon.sh stop historyserver 

HDFS WEB界面:http://linux121:50070/dfshealth.html#tab-overview

历史服务器web页面:http://linux121:19888/jobhistory

查看启动的服务命令:jps

HDFS命令

hdfs dfs -help rm
hdfs dfs -ls /
hdfs dfs -mkdir -p /a/b/c
hdfs dfs -removeFromLocal /opt/lxq/a.txt /a/b/c/
hdfs dfs -appendToFile /xx /xx/xx.csv
hdfs dfs -cat /a/b/c/a.txt
hdfs dfs -chmod 666 /a/b/c/a.txt
hdfs dfs -chown root:root /a/b/c/a.txt
hdfs dfs -copyFromLocal /opt/lxq/b.txt /a/b/c/
hdfs dfs -cp /a/b/c/a.txt /a/b/a.txt
hdfs dfs -mv  /a/b/a.txt /a/b/c/d/
hdfs dfs -get /a/b/c/a.txt
hdfs dfs -copyToLocal /a/b/c/a.txt /opt/lxq/data/
hdfs dfs -put xxx xxx
hdfs dfs -tail /xx/xx/xx.log
hdfs dfs -rm -r /a/b/c/d
hdfs dfs -du -s -h /a
hdfs dfs -du -h /a
hdfs dfs -setrep 10 /a/b/c/a.txt

Java整合Hadoop的依赖

<dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client -->
<dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.9.2</version></dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
<dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.9.2</version>
</dependency>

Java HDFSUtils类

package ;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.io.IOUtils;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;@Slf4j
public class HDFSUtil {private static final Configuration configuration = new Configuration();private static volatile FileSystem fileSystem = null;private HDFSUtil() {}private static FileSystem getFS() {if (null == fileSystem) {synchronized (HDFSUtil.class) {if (null == fileSystem) {try {fileSystem = FileSystem.get(new URI("hdfs://linux121:9000"), configuration, "root");} catch (IOException | InterruptedException | URISyntaxException e) {throw new RuntimeException(e);}}}}return fileSystem;}/*** 获取 HDFS 集群节点信息** @param hdfsUri 集群路径* @return List<String>* @author lxq* @since 2025-07-31*/public static DatanodeInfo[] getHDFSNodes(String hdfsUri) {if (StringUtils.isBlank(hdfsUri)) {return null;}DatanodeInfo[] dataNodeStats = new DatanodeInfo[0];try (FileSystem fs = getFS()) {// 获取分布式文件系统DistributedFileSystem hdfs = (DistributedFileSystem) fs;dataNodeStats = hdfs.getDataNodeStats();} catch (IOException e) {log.error("Get DataNode Info exception:", e);}return dataNodeStats;}/*** 获取目标路径下的所有文件或者文件夹的全路径列表** @param target 目标路径* @return List<String>* @author lxq* @since 2025-07-31*/public static List<String> listFile(String target) {if (StringUtils.isBlank(target)) {return null;}try (FileSystem fs = getFS()) {FileStatus[] status = fs.listStatus(new Path(target));/*for (FileStatus s : status) {s.isFile();s.isDirectory();}*/// 获取目录下的所有文件路径return Arrays.stream(FileUtil.stat2Paths(status)).map(Path::toString).collect(Collectors.toList());} catch (IllegalArgumentException | IOException e) {log.error("list file exception:", e);}return null;}/*** @param target* @return*/public static List<LocatedFileStatus> getFileLocatedStatus(String target) {List<LocatedFileStatus> locatedFileStatusList = new ArrayList<>();if (StringUtils.isNotBlank(target)) {try (FileSystem fs = getFS()) {RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path(target), true);while (listFiles.hasNext()) {LocatedFileStatus status = listFiles.next();// 输出详情// 文件名称System.out.println(status.getPath().getName());// 长度System.out.println(status.getLen());// 权限System.out.println(status.getPermission());// 分组System.out.println(status.getGroup());// 获取存储的块信息BlockLocation[] blockLocations = status.getBlockLocations();for (BlockLocation blockLocation : blockLocations) {// 获取块存储的主机节点String[] hosts = blockLocation.getHosts();for (String host : hosts) {System.out.println(host);}}}} catch (Exception e) {log.error("list file located status exception:", e);}}return locatedFileStatusList;}/*** 查找某个文件在 HDFS集群的位置*/public static BlockLocation[] getFileBlockLocations(String target) {if (StringUtils.isBlank(target)) {return null;}// 文件块位置列表BlockLocation[] blkLocations = new BlockLocation[0];try (FileSystem fs = getFS()) {// 获取文件目录FileStatus filestatus = fs.getFileStatus(new Path(target));// 获取文件块位置列表blkLocations = fs.getFileBlockLocations(filestatus, 0, filestatus.getLen());} catch (IOException e) {log.error("Block Location exception:", e);}return blkLocations;}/*** 创建文件夹 是不能创建文件的*/public static void mkdir(String target) {if (StringUtils.isBlank(target)) {return;}try (FileSystem fs = getFS()) {fs.mkdirs(new Path(target));log.info("Dir:{} Create Success.", target);} catch (Exception e) {log.error("make dir exception!", e);}}/*** 上传文件** @param sourcePath 源路径* @param targetPath 目标路径* @author lxq* @since 2025-07-31*/public static void uploadFile(String sourcePath, String targetPath) {if (StringUtils.isBlank(sourcePath) || StringUtils.isBlank(targetPath)) {return;}try (FileSystem fs = getFS()) {File file = new File(sourcePath);if (!file.exists()) {return;}if (file.isDirectory()) {// ... 需要完善文件夹的处理return;}String filename = file.getName();fs.copyFromLocalFile(new Path(sourcePath), new Path(targetPath + "/" + filename));log.info("Had Upload File:{} To Hdfs:{}", sourcePath, targetPath);} catch (Exception e) {log.error("upload file exception!", e);}}/*** 上传文件** @param sourcePath 源路径* @param targetPath 目标路径* @author lxq* @since 2025-07-31*/public static void downFile(String sourcePath, String targetPath) {if (StringUtils.isBlank(sourcePath) || StringUtils.isBlank(targetPath)) {return;}try (FileSystem fs = getFS()) {// boolean delSrc 指是否将原文件删除// Path src 指要下载的文件路径// Path dst 指将文件下载到的路径// boolean useRawLocalFileSystem 是否开启文件校验fs.copyToLocalFile(false, new Path(sourcePath), new Path(targetPath), true);log.info("Had Download File:{} To {}", sourcePath, targetPath);} catch (Exception e) {log.error("download file exception!", e);}}/*** 删除文件 / 文件夹** @param target 目标文件或者文件夹* @author lxq* @since 2025-07-31*/public static void delFileOrDir(String target) {try (FileSystem fs = getFS()) {if (StringUtils.isNotBlank(target)) {// 删除文件或者文件目录  delete(Path f) 此方法已经弃用fs.delete(new Path(target), true);log.info("Had Deleted File Or Dir Under the {} From Hdfs", target);}} catch (Exception e) {log.error("delete file or dir exception!", e);}}/*** 判断目录是否存在** @param target 目标路径* @param create 不存在是否创建* @return 是否存在路径*/public static boolean existDir(String target, boolean create) {if (StringUtils.isBlank(target)) {return false;}try (FileSystem fs = getFS()) {Path path = new Path(target);if (create) {if (!fs.exists(path)) {fs.mkdirs(path);}}if (fs.isDirectory(path)) {return true;}} catch (Exception e) {log.error("exist Dir exception:", e);}return false;}/************************** 流相关API *****************************//*** 流方式 文件上传*/public static void uploadWithStream(String sourcePath, File file, String targetPath) {if ((StringUtils.isNotBlank(sourcePath) || null != file) && StringUtils.isNotBlank(targetPath)) {try (FileSystem fs = getFS()) {if (null == file) {file = new File(sourcePath);}if (!file.exists()) {return;}if (file.isDirectory()) {return;}String filename = file.getName();FileInputStream fis = new FileInputStream(file);FSDataOutputStream fos = fs.create(new Path(targetPath + "/" + filename));IOUtils.copyBytes(fis, fos, configuration);IOUtils.closeStream(fos);IOUtils.closeStream(fis);log.info("Had Upload File:{} To Hdfs:{} With Stream.", sourcePath, targetPath);} catch (Exception e) {log.error("upload file with stream exception!", e);}}}/*** 流方式 文件下载*/public static void downloadWithStream(String sourcePath, String targetPath) {if (StringUtils.isNotBlank(sourcePath) && StringUtils.isNotBlank(targetPath)) {try (FileSystem fs = getFS()) {Path path = new Path(sourcePath);/*if (!fs.exists(path)) {}if (fs.isDirectory(path)) {}*/FSDataInputStream fis = fs.open(path);FileOutputStream fos = new FileOutputStream(new File(targetPath));IOUtils.copyBytes(fis, fos, configuration);IOUtils.closeStream(fos);IOUtils.closeStream(fis);log.info("Had Download File:{} From Hdfs:{} With Stream.", sourcePath, targetPath);} catch (Exception e) {log.error("download file with stream exception!", e);}}}
}

感谢阅读!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96049.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96049.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/96049.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

electron之win/mac通知免打扰

目录 系统区别 win&#xff1a;不支持桌面通知&#xff0c;使用气泡显示 mac&#xff1a;有镜像/共享屏幕时 通知免打扰设置 代码 Vuex&#xff1a;免打扰状态 src/store/App/mutations.ts src/store/App/state.ts src/views/miracast/index.vue Util 【可选】src/ut…

为什么Integer缓存-128 ~ 127

背景 面试题, 相关问题的考察. 题目大概是, 包装类型Integer 比较的时候 : -127 ~ 128 是否相等. 其他是否相等? 原理比较的是地址. 如果是不同的对象, 那么就不相等. 实践 下面是几个简单实践. 全部新建对象 解释: 新建对象后, 地址不同, 所以都是false不新建对象 暂时的理解…

微软Wasm学习-创建一个最简单的c#WebAssembly测试工程

要创建一个最简单的微软 WebAssembly&#xff08;Wasm&#xff09;测试工程&#xff0c;最直接的方式是使用 Blazor WebAssembly&#xff0c;这是微软官方推荐的 WebAssembly 开发框架。下面是创建和运行最简单 Blazor WebAssembly 项目的步骤&#xff1a; 相关&#xff1a;微…

通过 GitHub520 项目自动获取最新 Hosts 配置,无需手动查询 IP。

操作步骤&#xff1a;打开终端Command 空格 聚焦搜索“终端”&#xff0c;打开应用。执行一键脚本复制以下命令粘贴到终端运行&#xff08;需输入密码授权&#xff09;&#xff1a;bashsed -i "" "/# GitHub520 Host Start/,/# Github520 Host End/d" /et…

C# 目录与文件操作笔记

一、基本概念1. 数据存储方式对比存储方式适用场景特点数据库存储大量、关系复杂、有序的数据结构化强&#xff0c;支持复杂查询和事务文件存储少量、关系简单的数据&#xff08;如日志&#xff09;操作简便&#xff0c;可存储于任意介质2. 文件与流文件&#xff1a;存储在磁盘…

docker部署flask并迁移至内网

需要直接使用的可以使用下面的链接&#xff1a; 通过网盘分享的文件&#xff1a;docker_flask.tar 链接: https://pan.baidu.com/s/163ocPFw8cqfXgVXeejv36g?pwdqxqm 提取码: qxqm 来自百度网盘超级会员v6的分享 外网部署docker版flask 目录结构 ./miniconda-docker/ ├── d…

161. Java Lambda 表达式 - 使用工厂方法创建 Predicates

文章目录161. Java Lambda 表达式 - 使用工厂方法创建 Predicates&#x1f3af; Predicate 工厂方法概览&#x1f9ea; 示例一&#xff1a;Predicate.isEqual() 工厂方法&#x1f9ea; 示例二&#xff1a;Predicate.not() 工厂方法&#xff08;Java 11&#xff09;&#x1f3af…

c#Blazor WebAssembly在网页中多线程计算1000万次求余

在 Blazor WebAssembly 中实现多线程计算并获取线程 ID 是可行的&#xff0c;但需要正确配置多线程环境并处理线程安全和 UI 更新逻辑。以下是完整示例和检测方法&#xff1a;一、准备工作&#xff1a;启用多线程支持首先需确保项目已启用 WebAssembly 多线程&#xff0c;修改项…

鼠标右键没有“通过VSCode打开文件夹”

1, WinR 打开运行&#xff0c;输入regedit&#xff0c;打开注册表&#xff0c;找到HKEY_CLASSES_ROOT\*\shell分支&#xff0c;如果没有shell分支&#xff0c;则在*下点击右键&#xff0c;选择“新建&#xff0d;项”&#xff0c;建立shell分支。 2, 在shell下新建“VisualCod…

[ Spring 框架 ] 框架搭建和属性赋值

目录 1. Spring定义: (1). IOC( Inversion of Control): (2). AOP (Aspect Oriented Programming): (3)一站式: 2. spring搭建: (1). 创建一个Maven项目 (2). 导入核心 jar包 (3). 编写 spring 配置文件 (4). 编写实体类,并生成set方法 (5). 在resource中加入spring核…

前端 大文件分片下载上传

前端 大文件分片下载上传 背景介绍&#xff1a; 当前项目是给投行部门做系统&#xff0c;业务方需要有专门的文档中心去管理文件&#xff0c;包括但是不限于文件的上传和下载等等。笔者本来就是采用的浏览器表单上传的方式进行文件上传&#xff0c;但是谁曾想在进行稍微大一点的…

【Python练习】097. 编写一个函数,实现简单的版本控制工具

097. 编写一个函数,实现简单的版本控制工具 097. 编写一个函数,实现简单的版本控制工具 示例代码 功能说明 使用方法 注意事项 实现方法 基于文件快照的实现方法 基于差异存储的实现方法 基于命令模式的实现方法 基于Git-like的实现方法 097. 编写一个函数,实现简单的版本控…

嵌入式硬件篇---Tof

TOF 的原理与本质TOF&#xff08;Time of Flight&#xff0c;飞行时间&#xff09;是一种通过测量信号&#xff08;通常是光&#xff09;在空间中传播时间来计算距离的技术。其本质是利用 “距离 速度 时间” 的物理公式&#xff1a;通过发射信号&#xff08;如激光、红外光&…

Vue diff简介

Vue3 diff 最长递增子序列双端diff 理念 相同的前置和后置元素的预处理&#xff0c;考虑边界情况&#xff0c;减少移动&#xff1b;最长递增子序列&#xff08;动态规划、二分法&#xff09;&#xff0c;判断是否需要移动 操作 前置与后置预处理判断是否需要移动 递增法&#x…

罗技MX Anywhere 2S鼠标修复记录

【现象】单击时总是出现双击的现象 【问题原因】从网络收集&#xff1a; 说法1&#xff0c;欧姆龙微动损坏&#xff1b;说法2&#xff0c;按键磨损导致按键和微动开关接触不良&#xff1b; 【问题排查】 微动损坏&#xff1a;拆掉壳子后&#xff0c;用手按住左键的微动开关&…

常见IP模块的仲裁策略和实现

在一个 Message Unit 中包含两个 Core&#xff08;处理器核心&#xff09;&#xff0c;它们之间访问共享资源&#xff08;如寄存器、FIFO、buffer 等&#xff09;时&#xff0c;仲裁机制&#xff08;Arbitration&#xff09; 是确保系统稳定性和正确性的关键。以下是常见的仲裁…

上周60+TRO案件,波比的游戏时间/丹迪世界/飞盘/迪奥/多轮维权,手表/汽车品牌持续发力,垃圾桶专利等新增侵权风险!

赛贝整理上周&#xff08;2025年8月11日-8月15日&#xff09;的TRO诉讼案件发案情况&#xff0c;根据赛贝TRO案件查询系统了解到&#xff0c;上周合计发起了超60起诉讼案件&#xff0c;涵盖 IP /品牌、版权、专利等多个领域&#xff0c;涉及影视、奢侈品、汽车、游戏、日常用品…

用 Python 在 30 分钟内搭一个「可回放的实时日志」——把攻击流量变成可视化剧情

业务背景 我们运营一款 FPS 端游&#xff0c;外挂作者常把 DDoS 伪装成「玩家掉线」来骗客服。以前排查要捞 CDN 日志、对时间戳、人工比对&#xff0c;平均 2 小时才能定位。现在用一条 30 行的 Python 脚本把边缘节点日志实时打到 Kafka&#xff0c;再回放到 Grafana&#xf…

如何将 LM Studio 与 ONLYOFFICE 结合使用,实现安全的本地 AI 文档编辑

人工智能正在改变我们的工作方式——但如今大多数 AI 工具都存在弊端&#xff1a;速度和便利性虽有所提升&#xff0c;但也意味着数据需要发送到外部服务器。对于教育工作者、企业、非政府组织以及任何处理敏感信息的人来说&#xff0c;这都是不可接受的风险。 LM Studio 和 O…

超市电商销售分析项目:从数据分析到业务决策

国际超市电商销售数据分析实战&#xff1a;从数据清洗到业务决策的完整流程 在电商行业&#xff0c;数据是驱动业务增长的核心引擎。本文将以国际超市电商销售数据为研究对象&#xff0c;完整拆解从数据准备 → 深度分析 → 策略输出的实战流程&#xff0c;涵盖数据清洗、多维度…