深入理解Docker

news2024/11/24 14:13:47

文章目录

  • 1 Docker理论
    • 1.1 背景知识
    • 1.2 是什么
    • 1.3 Docker基本三要素
    • 1.4 镜像原理
    • 1.5 安装教程
  • 2 Docker常用命令
    • 2.0 防火墙相关命令
    • 2.1 镜像命令
    • 2.2 容器命令
    • 2.3 进阶命令
  • 3. 实战之Docker部署springboot项目
    • 步骤一:Springboot项目配置
      • 1.1 添加docker的maven依赖
      • 1.2 新建Dockfile构建镜像
      • 1.3 执行构建命令
    • 步骤二 启动docker镜像
    • 步骤三:访问测试
    • 坑:镜像无法启动
  • 4. 实战之Dockerfile编写指南

1 Docker理论

1.1 背景知识

​ **传统软件开发与运维痛点:**一款产品从开发到上线,从操作系统到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验。Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。环境配置如此麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装? 也就是说,安装的时候,把原始环境一模一样地复制过来,消除协作编码时“在我的机器上可正常工作,在他人机器上不能运行”的问题。
从而打破之前开发人员只提供代码(代码即应用)的方式,改为提交Docker镜像包括(运行文档、配置环境、运行环境、运行依赖包、操作系统发行环境),即镜像即应用。

1.2 是什么

​ Docker是基于Go语言实现的云开源项目。Docker的主要目标是"Build,Ship and Run Any App,Anywhere",也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP (可以是一个WEB应用或数据库应用等)及其运行环境能够做到“一次封装,到处运行”。

​ Linux容器技术的出现就解决了这样一个问题,而Docker就是在它的基础上发展过来的。将应用运行在Docker容器上面,而Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署,大大简化了操作。

在这里插入图片描述

与虚拟机的区别?
虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在Windows系统里面运行Linux系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。

虚拟机的缺点:
1、资源占用多 2、冗余步骤多 3、启动慢(分钟级别)

在这里插入图片描述

1.3 Docker基本三要素

仓库Repository + 镜像Image + 容器Container

在这里插入图片描述

仓库Repository—>镜像Image(类Person)–>容器Container(对象p1、p2)

  1. 仓库Repository是存放镜像文件的场所,仓库Repository与仓库注册器Registry是有区别的,仓库注册服务器上往往存放多个仓库,每个仓库有多个镜像,每个镜像有不同的标签tag(仓库分为公开仓库public和私有库private,最大的仓库Docker Hub,但由于其服务器在国外,从中拉去镜像速度很慢,国内一般使用的是阿里云、网易云。)
  2. 镜像Image就是从docker Hub仓库拉取到本地的一个只读的模版,镜像Image用来创建容器Container,一个镜像可以创建多个容器
    镜像Image(类)—>容器Container(对象)
  3. Docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就似乎image镜像文件。只有通过这个镜像文件才能生成Docker容器(集装箱)。

1.4 镜像原理

在这里插入图片描述

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。

​ UnionFS (联合文件系统) : Union文件系统(UnionFS) 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

	特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

1.5 安装教程

1. Docker官网:https://www.docker.com
2. Docker Hub官网:https://hub.docker.com
3. MAC安装教程:https://docs.docker.com/desktop/install/mac-install/
4. LinuxC安装教程
# 1.移除以前docker相关包
	yum remove docker* 															
# 2.配置yum源
    sudo yum install -y yum-utils
    sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 

# 3.安装docker并启动
    sudo yum install -y docker-ce docker-ce-cli containerd.io  					# 安装docker及其组件
    yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7  containerd.io-1.4.6 # 以下是在安装k8s的时候使用,暂时不安装
    systemctl enable docker --now		# 启动docker,并设置开机自启动,首次优先使用该命令
    service docker status				# 查看状态
    service docker start        		# 启动
    service docker stop					# 停止

# 4.配置加速
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
      "exec-opts": ["native.cgroupdriver=systemd"],
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "100m"
      },
      "storage-driver": "overlay2"
    }
    EOF

    sudo systemctl daemon-reload
    sudo systemctl restart docker

2 Docker常用命令

2.0 防火墙相关命令

sudo firewall-cmd --list-all --zone=public                         # 查看防火墙对外提供访问的接口
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent      # 开放TCP端口80(HTTP)
sudo firewall-cmd --zone=public --remove-port=80/tcp --permanent   # 关闭TCP端口80(HTTP
sudo firewall-cmd --permanent --query-port=80/tcp                  # 查看端口是否开启
service firewalld status
service firewalld stop
service firewalld start
service firewalld restart

2.1 镜像命令

1 帮助命令:
	docker version
	docker info
	docker --help

2 镜像命令:
	1、列出本地镜像:docker images [-options]
		-a:列出本地所有镜像
		-q:只显示镜像ID
		--digests:显示镜像的摘要信息
		--no-trunc:显示完整的镜像信息
		docker images -a
		docker images -q
	2、查询DockerHub镜像:docker search [-options] 镜像名
		docker search tomcat:列出tomcat的镜像
		docker search --no-trunc tomcat:显示完整的镜像描述
	3、下载镜像到本机:docker pull 镜像名
        docker pull tomcat   		下载最新镜像tomcat,等同于docker pull tomcat:latest
        docker pull redis:6.2.4 	下载指定版本镜像
	4、删除本机镜像:docker rmi -f 镜像名/镜像id
		docker rmi [-f] tomcat

在这里插入图片描述

2.2 容器命令

容器命令:有镜像才能实例化容器(提前下载一个centos镜像仅有200MB)
	1、新建并启动一个容器:docker run [-options] 具体镜像名称:版本号 /bin/bash:
		--name:容器的新别名
		-i:以交互方式启动容器,通常与-t同时使用
		-t:为容器分配一个伪输入终端
		-d:以守护进程方式启动容器

以交互方式启动容器(为主):前台启动
		docker run –it --name my-centos centos:7 /bin/bash
以守护进程方式启动容器:运行在后台
		docker run -d --name=mynginx --restart=always -p 88:80 nginx

	2、列出所有正在运行的容器: docker ps [-options] 
        -l:显示最近创建的容器
        -n 2:显示最近2个创建的容器
        -a:显示当前多元的正在运行的容器+历史上运行过的
        -q:静默模式,只显示容器编号
        --no-trunc:不截断输出显示
    
    3、退出容器
        exit:			在容器内,关闭该容器并推出
        ctrl+P+Q: 在容器内,关闭该容器但是不推出
	
    4、停止容器				docker stop 容器名称或容器id
    5、强制停止容器		   docker kill容器名称或容器id
    6、重启容器	 			docker restart 容器名称或容器id
    7、删除容器				docker rm 容器名称或容器id
    8、查看容器日志		   docker logs [-options] 容器名称或容器id
    	docker logs -f 3063af3e3f86    

2.3 进阶命令

1、进容器内部
	docker exec -it 容器id  /bin/bash  # 在新的容器中打开新的命令终端,可以启动新的进程
2、挂载数据到外部修改
	docker run --name=mynginx \ 
	-d --restart=always \
	-p  88:80 \
	-v /data/html:/usr/share/nginx/html:ro \ # 修改页面只需要去主机的 /data/html
	nginx:latest 
3、镜像分享方案一
    docker save -o mynginx.tar nginx # 将镜像保存成压缩包
    docker load -i abc.tar 			 # 别的机器将压缩包加载为镜像
4、镜像分享方案二【需要docker hub账号】
	docker commit -m "首页变化" 341d81f7504f guignginx:v1.0  # 将自己修改好的镜像提交
	在docker hub 注册仓库
	docker tag guignginx:v1.0 leifengyang/guignginx:v1.0 	# 把旧镜像的名字,改成仓库要求的新版名字
	docker login  							# 登录到docker hub
	docker push leifengyang/guignginx:v1.0  # 推送
	docker logout 							# 推送完成镜像后退出
	docker pull leifengyang/guignginx:v1.0  # 别的机器下载
5、查看容器运行情况
	docker top 容器名称或容器id   # 查看容器内运行的进程
	docker inspect 容器名称或容器id # 查看容器内部细节
	docker attach 容器名称或容器id # 进入正在运行的容器并以命令行交互, 不会启动新的进程
6、从容器内拷贝文件到主机上:		
	docker cp 容器id: 容器路径 目的主机路径

在这里插入图片描述

3. 实战之Docker部署springboot项目

需求:

  1. 手动部署:本地IDE打包成jar,在docker环境中创建java环境容器,将jar包使用命令行拷贝至docker容器中,启动。
  2. 自动部署:通过Maven插件配置参数自动部署。(优先选这个)

步骤一:Springboot项目配置

1.1 添加docker的maven依赖

		<plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>
                <configuration>
                    <imageName>docker/${project.artifactId}</imageName> <!-- 镜像名称  -->
                    <dockerDirectory>src/main/docker</dockerDirectory>  <!-- Dockerfile文件存放目录:后续改为项目根目录,后续Dockfile文件一定要放在这 -->
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

            <!--这个插件,可以将应用打包成一个可执行的jar包-->
  					<!--千万不能丢掉,不然web项目没有main入口-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>

1.2 新建Dockfile构建镜像

# 基于openjdk 镜像,如果镜像不是本地的会从 DockerHub 进行下载
FROM openjdk:8

# VOLUME 指向了一个/tmp的目录,由于 SpringBoot使用内置的Tomcat容器,Tomcat 默认使用/tmp作为工作目录。
# 这个命令的效果是:在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录
VOLUME /tmp

# 作者
MAINTAINER zhupeng

# 将本地JAR包打包到容器中,并重命名
ADD springboot-1.0-SNAPSHOT.jar app.jar

# 声明需要暴露的端口 在Dockerfile中声明了那些端口是需要开放的,在构建容器时通过-p可以随机映射端口,如果EXPOSE没有指定端口,那么使用-p参数无效。本配置只是声明,一般我们需要在构建docker容器时使用-p(小写的p)指定开放的端口。
EXPOSE 8080

# 配置容器启动后执行的命令
ENTRYPOINT ["java","-jar","app.jar"]

1.3 执行构建命令

mvn clean package -Dmaven.test.skip=true docker:build # 前提要有docker环境

PS:如果还win执行mvn指令:mvn clean package ‘-Dmaven.test.skip=true’

在这里插入图片描述

步骤二 启动docker镜像

 docker images -a
 docker run -d --name my-springboot -p 8080:8080 docker/springboot-multipart [务必指定暴露端口]
 
 docker ps -a
 docker logs -f 976e5ee13513ed3

在这里插入图片描述

步骤三:访问测试

http://10.1.42.71:8080/test/show

在这里插入图片描述

坑:镜像无法启动

如果没连接数据库的话,是可以正常启动的,但是如果application.yml连接了数据库,那就会无法启动。

Host '10.1.42.71' is not allowed to connect to this MySQL server" MySQL不允许远程登录

解决方案:
1. update user set host = '%' where user = 'root'; 会警告报错
2. UPDATE `mysql`.`user` SET `Host` = '%' WHERE (`Host` = 'localhost') and (`User` = 'root');
   或者手动改

use mysql;
Select user from mysql.user; MySQL 服务器中所有用户的列表
mysql -u root -h 10.1.42.71 -p: MySQL远程登录

4. 实战之Dockerfile编写指南

https://zhuanlan.zhihu.com/p/143109114

Dockerfile中文名叫镜像描述文件,是一个包含用于组合镜像目录的文本文档,也可以叫“脚本”。他通过读取Dockerfile中的指令安装步骤自动生成镜像。

补充:文件名称必须是:Dockerfile

基础命令

# 1. FROM
# 制作基础镜像:基于openjdk 镜像
FROM openjdk:8

# 2. MAINTAINER
# 谁创造了它(作者信息)
MAINTAINER zhupeng

# 3. WORKDIR
# 类似于Linux中的cd命令:cd高级的地方在于,若发现没有这个目录,就自动创建出来,建议使用绝对路径
WORKDIR /usr/local/testdir

# 4.COPY
# 文件拷贝
# 案例一:将1.txt拷贝到根目录下。它不仅仅能拷贝单个文件,还支持Go语言风格的通配符,比如如下:
COPY 1.txt /
# 案例二:拷贝所有 abc 开头的文件到testdir目录下
COPY abc* /testdir/
# 案例三:? 是单个字符的占位符,比如匹配文件 abc1.log
COPY abc?.log /testdir/

# 5.ADD
# 往它肚子里放点文件(会自动解压)
ADD springboot-1.0-SNAPSHOT.jar app.jar
# 案例一:将1.txt拷贝到根目录的abc目录下。若/abc不存在,则会自动创建
ADD 1.txt /abc
# 案例二:将test.tar.gz解压缩然后将解压缩的内容拷贝到/home/work/test
ADD test.tar.gz /home/work/test
# docker官方建议当要从远程复制文件时,尽量用curl/wget命令来代替ADD。因为用ADD的时候会创建更多的镜像层。镜像层的size也大。

# ADD/COPY对比
# 1.二者都是只复制目录中的文件,而不包含目录本身。
# 2.COPY能干的事ADD都能干,甚至还有附加功能。
# 3.ADD可以支持拷贝的时候顺带解压缩文件,以及添加远程文件(不在本宿主机上的文件)
# 4.只是文件拷贝的话可以用COPY,有额外操作可以用ADD代替。


# 6.ENV
# 设置环境常量,方便下文引用
ENV JAVA_HOME /usr/local/jdk1.8
RUN ${JAVA_HOME}/bin/java -jar xxx.jar

# 7.RUN
# RUN指令是在构建镜像时运行,在构建时能修改镜像内部的文件[docker::build]
# SHELL命令格式:RUN yum -y install vim
# EXEC命令格式:	RUN ["yum","-y","install","vim"]

# SHELL:当前shell是父进程,生成一个子shell进程去执行脚本,脚本执行完后退出子shell进程,回到当前父进程。
# EXEC:用EXEC进程替换当前进程,并且保持PID不变,执行完毕后直接退出,不会退回原来的进程。
# 总结:也就是说shell会创建子进程执行,EXEC不会创建子进程。推荐EXEC命令格式

# 8.CMD
# 1.容器启动时执行,而不是镜像构建时执行[docker run]
# 2.Dockerfile中只有最后一个ENTRYPOINT会被执行,推荐用EXEC格式。
# 3.重点在于如果容器启动的时候有其他额外的附加指令,则CMD指令不生效。

# 9.ENTRYPOINT
# 容器创建时执行,而不是镜像构建时执行。
# Dockerfile中只有最后一个ENTRYPOINT会被执行,推荐用EXEC格式。
ENTRYPOINT ["java","-jar","app.jar"]

# 给我一个存放行李的地方(目录挂载):将本地文件夹挂载到当前容器
VOLUME /tmp

# 声明需要暴露的端口
EXPOSE 8080

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring boot概述

SpringBoot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。 该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。 通过这种方式&#xff0c;SpringBoot致力于在蓬勃发展的快速应用开发…

“祖传代码“的是是非非

程序员眼中的“祖传代码”&#xff0c;就像一本古老而神秘的魔法书&#xff0c;藏着无穷的智慧和技巧&#xff0c;有些代码像家传宝贝&#xff0c;有些像祖传秘方。快来分享一下你遇到的“祖传代码”吧~ 祖传代码的历史与文化价值 祖传代码通常指的是经过长时间使用和传承的代…

Linux操作系统——进程信号

1.信号的概念 生活当中哪些场景算信号呢&#xff1f;比如说你晚上调了个闹钟&#xff0c;然后第二天早上你听到了闹钟响了你就知道该起床了&#xff0c;这种机制就叫做信号机制。在生活中我们的信号是非常非常多的&#xff0c;比如说有&#xff1a;红绿灯&#xff0c;下课铃声…

网络编程作业day3

项目作业1&#xff1a;TCP机械臂测试 客户端操作代码&#xff1a; /*机械臂客户端控制代码*/ #include <myhead.h>#define SER_IP "192.168.125.176" //机械臂服务器IP地址 #define SER_PORT 8888 //机械臂服务器端口号 #define CLI_IP "…

代码随想录算法训练营第35天 | 435. 无重叠区间 ,763.划分字母区间 , 56. 合并区间

贪心算法章节理论基础&#xff1a; https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 435. 无重叠区间 题目链接&#xff1a;https://leetcode.cn/problems/non-overlapping-intervals/ 思路&#xff1a; 相信…

理疗美容按摩小程序有哪些功能

医疗、美容和按摩等行业是一个快速发展的领域&#xff0c;很多美容院和理疗中心都希望通过小程序来提升服务质量和用户体验。下面我们来看看一个理疗美容小程序可以具备哪些功能&#xff0c;并介绍如何使用这些功能。 1. **在线预约服务**&#xff1a;用户可以通过小程序预约理…

第8章:Nginx与Web应用《Nginx实战:从入门到精通》

Nginx不仅仅是一个高效的静态内容服务器和反向代理服务器&#xff0c;它还能与各种流行的Web应用框架和语言环境无缝集成&#xff0c;从而提供强大的动态内容处理能力。在本章中&#xff0c;我们将深入探讨Nginx如何与PHP、Python、Ruby和Node.js等常见的Web应用和语言环境协同…

爬虫入门到精通_实战篇10(使用Redis+Flask维护动态代理池)

1 目标 为什么要用代理池 许多网站有专门的反爬虫措施&#xff0c;可能遇到封IP等问题。互联网上公开了大量免费代理&#xff0c;利用好资源。通过定时的检测维护同样可以得到多个可用代理。 代理池的要求 多站抓取&#xff0c;异步检测定时筛选&#xff0c;持续更新提供接…

【大厂AI课学习笔记NO.56】(9)模型评测

作者简介&#xff1a;giszz&#xff0c;腾讯云人工智能从业者TCA认证&#xff0c;信息系统项目管理师。 博客地址&#xff1a;https://giszz.blog.csdn.net 声明&#xff1a;本学习笔记来自腾讯云人工智能课程&#xff0c;叠加作者查阅的背景资料、延伸阅读信息&#xff0c;及学…

数字化转型导师坚鹏:BLM金融机构数字化转型战略工作坊

BLM金融机构数字化转型战略工作坊 ——以BLM模型为核心&#xff0c;实现知行果合一 课程背景&#xff1a; 很多金融机构存在以下问题&#xff1a; 不知道如何系统地制定金融机构数字化转型战略&#xff1f; 不清楚其它金融机构数字化转型战略是如何制定的&#xff1f; …

动态IP代理技术在网络爬虫中的实际使用

目录 前言 一、什么是动态IP代理技术&#xff1f; 二、动态IP代理技术的实际使用 1. 获取代理IP地址 2. 在网络爬虫中设置代理 3. 周期性更换代理 结论 前言 网络爬虫是一种通过自动化程序从互联网上获取数据的技术。然而&#xff0c;由于某些网站对爬虫进行限制&#…

No matching version found for @babel/traverse@^7.24.0.

问题&#xff1a; npm安装 依赖失败&#xff0c;找不到所需依赖。 原因&#xff1a; npm镜像源中没有该依赖。&#xff08;大概率是因为依赖最近刚更新&#xff0c;当前镜像源没有同步&#xff09; 解决&#xff1a; 查看自己的npm镜像&#xff1a;npm config get registry…

史上最细,企业性能测试步骤详细,测试老鸟带你一篇打通!

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、性能测试流程 …

nodejs,JSDOM 补 window环境

window[atob] 是一个在浏览器中使用的 JavaScript 函数&#xff0c;用于将 base64 编码的字符串解码为原始数据。具体来说&#xff0c;atob 函数会将 base64 字符串解码为一个 DOMString&#xff0c;其中包含解码后的二进制数据。这在处理从服务器获取的 base64 编码的数据或在…

[Vulnhub]靶场 Red

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 …

带你从Spark官网啃透Spark Structured Streaming

By 远方时光原创&#xff0c;可转载&#xff0c;open 合作微信公众号&#xff1a;大数据左右手 本文是基于spark官网结构化流解读 Structured Streaming Programming Guide - Spark 3.5.1 Documentation (apache.org) spark官网对结构化流解释 我浓缩了一些关键信息&#xff…

LCR 134. Pow(x, n)

解题思路&#xff1a; 分治 快速幂 Java中向下取整n/2即可 需要结合下图理解&#xff0c;算法就是实现的该过程 class Solution {public double myPow(double x, int n) {if(x 0.0f) return 0.0d;long b n;double res 1.0;//例如:2^-5(1/2)^5if(b < 0) {x 1 / x;b -b…

嵌入式中很多MCU公司,为什么都是仿STM32?

做了单片机开发十多年了&#xff0c;STM32是我用过的单片机里面&#xff0c;最省心的。 用STM32做过的产品&#xff0c;至少10几个以上了。 其实不仅仅是STM32&#xff0c;还有STM8系列&#xff0c;也很稳。 我们无际单片机特训营好几个项目&#xff0c;都用了STM8和STM32系…

挂耳式蓝牙耳机性价比推荐,六大必备选购策略全揭秘!

生活水平的提升往往伴随着个人素质的增长。在公共场合&#xff0c;越来越多的人选择佩戴耳机&#xff0c;以避免打扰他人&#xff0c;同时也追求个人的舒适体验。挂耳式蓝牙耳机因其独特的设计成为了新宠。这类耳机不压迫耳道&#xff0c;提供自然的声音体验&#xff0c;同时确…

【卡尔曼滤波】图文结合带你详细推导卡尔曼滤波(超详解)

大家好&#xff0c;好久不见&#xff0c;我是小政。读研期间&#xff0c;我的研究方向是协作定位&#xff0c;涉及到多机器人分布式融合&#xff0c;主要用到了卡尔曼滤波&#xff0c;CI融合等概念。卡尔曼滤波我也是研究了很久&#xff0c;一直在思考的问题就是&#xff0c;卡…