镜像制作实战篇

“ 在失控边缘冲杀为,最终解脱”


CMD与EntryPoint实战

        EntryPoint 与 CMD都是docker 镜像制作中的一条命令,它们在概念上可能有些相似,但在使用中,两者是有明显的区别的。比如,执行一个没有调用EntryPoint、CMD的容器会返回错误,这两条命令一般都作为容器启动的入口命令~

🎨 覆盖        

        编写Dockerfile时,一旦使用了EntryPoint、CMD命令都会覆盖之前默认的EntryPoint、CMD命令集。我们在Docker镜像运行时,也可以通过携带 “命令+参数”,覆盖CMD;如果设置了EntryPoint,这些命令集又会被当成参数,喂给EntryPoint作为参数。或是携带 ”--entrypoint“用于覆盖EntryPoint中的命令。

        如果你只希望Docker容器在运行时,只执行一个具体的程序,建议使用EntryPoint。

🎨 Shell 与 EXEC模式

        ENTRYPOINT 与 CMD指令支持两种不同的写法: shell 、 EXEC

CMD指令写法:

# EXEC FORM
CMD ["excutable","param1","param2"]
# 用于给 EntryPoint传输参数
CMD ["param1","param2"]# shell FORM
CMD command param1 param2

ENTRYPOINT指令写法:

# EXEC FORM
ENTRYPOINT ["exutable","param1","param2"]# Shell FORM
ENTRYPOINT command param1 param2

使用shell表示法,言外之意。这些命令终将是喂给 shell程序来执行的!

即 —— docker使用:  /bin/sh -c 的语法调用

使用EXEC语法,不会启动 /bin/sh,而是直接运行命令,该命令PID=1

        使用docker ps就可以看到实际运行的命令模式~ 

        因此,无论你选择CMD或是ENTRYPOINT,都最后选用 ”EXEC表示法”

🎨 组合模式

        组合使用ENTRYPOINT 与 CMD时,ENTRYPOINT作为默认的运行命令,CMD指定运行参数。当ENTRYPOINT与CMD同时存在时,docker会把CMD中的命令都拼接在ENTRYPOINT之后,并最终执行命令~       

实战步骤

💎 多次覆盖

        我们创建一个Dockerfile文件,指定多个CMD,如下:

        构建镜像,查看运行结果,我们发现三条命令中,只打印了一句~

        我们继续创建第二个 dockerfile2,指定多个EntryPoint:

        构建、运行镜像:

        

💎 参数覆盖

        我们通过指定后面启动的参数,可以覆盖CMD的指令,但却无法对ENTRYPOINT进行覆盖~

        当我们指定 --entrypoint时,才会覆盖dockerfile中的ENTRYPOINT默认命令:

        

💎 Shell vs EXEC

        我们编写Dockerfile,让容器启动时,自动运行ping命令~

        编译运行镜像,进入镜像之中,查看进程ID,我们可以看到PID为1的进程为 /bin/sh。

        我们新建Dockerfile4,并采用EXEC的模式:

        编译运行镜像后,我们进入到容器中查看进程PID,此时发现PID为1的进程变为PING~

        使用entrypoint指令也是同样的结果,这里也就不再过多实验~

💎 组合

        我们新建Dockerfile5,同时设置ENTRYPOINT、CMD:

        此时,我们编译镜像+运行镜像看看是什么效果:

        其中CMD中的内容,作为ENTRYPOINT的参数,添加到了后面~

        又因为,我们可以在docker run启动时,通过命令行替换CMD中的内容,所以,我们又可以进行如下的执行:


Dockerfile搭建Mysql主从集群

build功能

        在 docker-cmpose.yml文件中,使用build选项 编译镜像:

# 方式一
services:frontend:image: awesome/webappbuild: ./webapp
# 注解:
该镜像的构建,是由 "awesome"的子目录“webapp"决定。
如果该文件(webapp) 缺少dockerfile 就会发生报错# 方式二backend:image: awesome/databasebuild: context: ./backenddockerfile: ./backend.dockerfile# 注解:
"./backend"作为镜像构建的上下文,这个"./backend"需要是一个子目录
"./backend.dockerfile" 与之是同级目录,其路径与"./backend"是相关的都是子目录

Mysql主从同步原理

什么是Mysql的主从同步?        

        所谓主从 —— 即一个主节点,多个从节点的模式。在Mysql中,主节点的Mysql服务器上的数据可以通过一定的方式,“同步复制”给其他从节点,从而保证主、从节点数据的一致性。

        Mysql默认采用异步复制的方式,这样的好处在于,从节点不用频繁地找主节点更新拷贝新数据,数据的更新可以放在连接上。

为什么需要Mysql主从同步?

🎯 读写分离,性能提升: 让主库负责写,从库负责读。这样当主库进行写触发锁机制时,因为有从库的存在,也不会停止提供读服务。

🎯 数据实时备份: 主数据库实时保存,当主节点突然宕机、挂掉,主库可以去从库哪里找到历史数据~

🎯 高可用: 某个节点发送故障,仍然有其他节点提供服务~不会致使整个服务瘫痪~

主从同步架构

        在主从复制中存在3个线程用来执行这个过程,一个是"binlog dump thread",该线程位于master节点上,另外两个线程分别为 I/O 、SQL线程,它们分别存在于从节点上。

同步过程:

🎃 当master接收到一个写请求(增\删除\改),这些操作都会被记录进 binlog 之中.

🎃 master节点会为每一个 slave节点(前提是,slave节点连接到了master节点上),分别创建一个 线程(binlog dump thread),并将binlog中的内容通过线程发送给各slave节点。 

🎃 binlog dump thread线程会 "互斥地"(加锁)读取master节点上的binlog日志,并将该日志信息发送到 slave节点的 I/O上

🎃 slave节点的 I/O接收到binlog日志信息后,会将其存放到本节点上的 relaylog中~

🎃 slave启用SQL THREAD,前去读取relaylog中的内容,将其具体解析成执行的SQL,并执行这些SQL,实现某种意义上的还原~

        从而实现一种 主从节点数据上,一致性的现象。

Binlog

        Binlog本质上虽然是一个二进制文件,但其内部存储的是一个一个的事件~ 所谓的事件就是指使用数据库过程中产生的各个SQL 指令: INSERT、UPDATE、DELETE等等。

        主库每提交一次”事务“(即,一组持有原子性、持久性、隔离性、一致性语句的逻辑),都会把数据进行变更,记录到一个 二进制文件之中 —— binlog。

参数值含义缺点
Statement记录原始的SQL语句SQL中包含了每次执行结果不一致的函数、触发器时,同步数据时会造成不一致
row记录了数据被更改的具体值每条数据的更改被详细记录,如整表删除,alter表等操作涉及的数据行都会记录,ROW格式会产生大量日志。
mixed混合模式以上两种格式的混合版无法对误操作数据进行单独恢复。
主从同步方式

💰 全同步方式: 

        当主库处理执行完一个事务之后,要求所有的从库也必须执行完该事务,才可以继续返回处理客户端的请求。这样虽然能够极大程度上保障主从节点数据的一致性,但却带来的是请求处理性能的损耗,从库宕机也会对主库产生影响。

💰 异步同步方式: 

        这是Mysql默认采取的主从同步方式。主库在执行完客户端提交的事务之后,立即返回结果给客户端,并不关心从库,是否已经同步完成 新增数据信息~

        所以,这必然会在某一个周期时间内,主从库数据会产生不一致的问题。而且,一旦主库宕机挂掉,此时的binlog可能还没有发送新提交事务的信息,就会产生数据丢失问题。由此,异步同步方式虽然性能上比 同步方式下更优,但是数据安全、一致性问题上显得欠缺~

💰 半同步方式: 

        基于异步同步方式的缺陷,mysql在5.5版本退出,半同步复制。其本质就是对传统异步复制的改进。在Master事务的commit提交之前,必须确保slave收到一个relay log并且响应ACK,简单来说,就是新增了一个从库的 反馈机制

        在Mysql5.7版本中,又新增一个参数: "rpl_semi_sync_master_wait_for_slave_count"。这个参数是用来干嘛的呢 ? 你可以把它类似于一种投票机制,默认设置为1。也就是说,一旦一个从库进行了响应,那么就可以告诉主节点,可以返回给客户端了。 当这个参数设置得越大,也就说明需要从库进行确认的个数越多,更大程度上地提升数据一致性的强度,但也会增加咱们主库等待ACK响应的时延~

       不过,半同步方式也存在一系列的问题:

⌛ 性能较低: 异步复制一旦客户端进行commit提交,立马就能得到返回响应。但,半同步复制则需要等待至少一个库发送 确认收到relaylog后,才能进行返回客户端。

⌛ 主库等待的最大时长可以进行配置的,一旦超过了配置的时间,半同步复制就会演变为异步复制,异步复制的问题也会显现~

⌛ 半同步复制还会存在幻读问题!!

所谓幻读,其本质就是一种 “不可重复读“问题的一种~

主要针对的是在执行了Insert 插入语句后,可能导致的事务前后查询数据 不一致的问题

💰 增强半同步方式: 

        看这个方式的名字也就知晓,这是半同步复制的一种改进,原理上几乎与半同步复制一样,但解决了其遗留的幻读问题!

        其核心在于:

        主库配置了新的参数 "rpl_semi_sync_mater_wait_point=AFTER_SYNC"。现在的主库不再将写入binlog中的内容,立即同步给 ”存储引擎“,而是直到收到Slave的relay log的ACK后,才能进行提交存储引擎,完成向客户端的请求反馈、处理。

💰 组复制:

        Mysql官方在5.7.17版本中,正式推出组复制(Mysql Group Replication) —— MGR。

        由若干个节点共同组织成一个组,一个事务的提交,必须经由绝大多数组内节点的确认  —— (N / 2 + 1)。例如,如果是由3个Mysql服务器共同组成的组复制,在事务提交的过程中,至少需要2个节点决议,是否通过这个提交决议~

        引入组复制,根本上是为解决传统异步复制、半同步复制存在的数据不一致性的问题。

        不过,MGR的解决方案是也有一定的局限,如仅由Innodb表能够支持,并且对表的结构也有一顶的要求……

Mysql主从形式

👑 一主一从(多):

👑 双主复制:

        每个master都是对端master的slave,任何一方做变更,都会复制应用到另一方。 

👑 级联复制:

        级联复制下,部分slave的数据同步不跟随主节点,而是连接的从节点。通过增加replication层,可以缓解主节点replication产生的性能损耗,对数据一致性也没什么负面影响,但数据同步时的时延性会增加~ 

Mysql主从集群搭建

搭建步骤:

⛳ 创建主库,并在主库中创建单独的Mysql用户,用于数据的同步,授予该用户所有权限。

⛳ 创建从库,配置从库的数据,同步到主库。

⛳ 启动从库,开始同步。

配置Mysql文件 + Dockerfile:

        咱们选择的主从模式是一主多从,创建一个主节点两个从节点:

        创建主库的配置sql脚本:

# 创建新用户
CREATE USER 'root'@'%' IDENTIFIED BY 'root';
# 让"root"授予访问 slave1 slave2 的所有权限
grant replication slave1,replication slave2 on *.* to 'root'@'%';
flush privileges;

        创建从库的配置sql脚本: 

change master to master_host='mysql-server';
# 填写主节点的用户信息
master_user='root',master_password='root',master_port=3306;
start slave;

        进入"mysql-cluster-master"目录下,创建并配置主库Dockerfile文件 —— "Dockerfile-master":

         这里本质上就是将Mysql初始化库的启动命令更换为了咱们写的sql语句。并且进行了时间同步,可以看到Linux系统中有许多地区、城市的时间信息~

FROM mysql:5.7
RUN ls /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 
COPY ./master/master.sql /docker-entrypoint-initdb.d

        还有Dockerfile-slave:

FROM mysql:5.7
RUN ls /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 
COPY ./slave/slave.sql /docker-entrypoint-initdb.d

        

编写docker-compose.yml 统一编排容器

        我们进入到 "/root/mysql-cluster/",创建.yml文件:

version: "3.6"
services:mysql-master:build: context: ./ dockerfile: ./master/Dockerfile-masterimage: mysqlmaster:v1.0restart: alwayscontainer_name: mysql-mastervolumes: - ./mastervarlib:/var/lib/mysqlports: - 8080:3306environment: MYSQL_ROOT_PASSWORD: rootprivileged: truecommand: ['--server-id=1','--log-bin=master-bin','--binlog-ignore-db=mysql','--binlog_cache_size=256M','--binlog_format=mixed','--lower_case_table_names=1','--character-set-server=utf8','--collation-server=utf8_general_ci']mysql_slave:build: context: ./ dockerfile: ./slave/Dockerfile-slaveimage: mysqlslave:v1.0restart: alwayscontainer_name: mysql-slavevolumes:- ./slavevarlib:/var/lib/mysqlports:- 8081:3306environment:- MYSQL_ROOT_PASSWORD=rootprivileged: truecommand: ['--server-id=2','--relay-log=slave-relay','--lower_case_table_names=1','--character-set-server=utf8','--collation-server=utf8_general_ci']  depends_on:- mysql-mastermysql_slave2:# build: #   context: ./ #   dockerfile: ./slave/Dockerfile-slaveimage: mysqlslave:v1.0restart: alwayscontainer_name: mysql-slave2volumes:- ./slavevarlib2:/var/lib/mysqlports:- 8082:3306environment:- MYSQL_ROOT_PASSWORD=rootprivileged: truecommand: ['--server-id=3','--relay-log=slave-relay','--lower_case_table_names=1','--character-set-server=utf8','--collation-server=utf8_general_ci']  depends_on:- mysql-master

        我们使用 "docker compose config" 检查.yml是否编写规范~

        没问题后,我们就可以选择构建镜像了:

        启动服务进行测试,这些容器能够正常启动~

        连接上主库,查看数据库~

                查看数据库角色、同步状态、连接上的从库信息等~

SHOW MASTER STATUS\G
SHOW SLAVE STATUS\G

master:

slave:       

        在主库上创建数据:

        查看从库上数据的同步写入~

        我们可以瞧见,最终完成了同步~


Dockerfile搭建Redis主从集群

修改redis.conf文件

        我们可以在Windows上先下载redis7.x的源码: Download | Redis

        亦或是在linux机器下,使用wget命令: 

        https://codeload.github.com/redis/redis/tar.gz/refs/tags/7.2.4

        准备目录,将下载的redis源码放在新建目录中:

        找到redis中的配置文件模板,完成以下redis.conf内容的修改,把该文件继续放在新建目录("/data/wgzzs/rediscluster/redis"):

编写docker-file 

        在"/data/wgzzs/rediscluster/redis"编写Dockerfile-redis文件,用于构建自己的redis镜像~

        通过"docker build -t"来构建镜像:

        启动一个容器测试看看能否正常运行~

        清理容器资源,之后会启动redis集群,需要的服务资源也会增多~     

进行容器编排 —— 编写docker-compose.yml 

        我们需要启动多个容器而不再是一个了!又因为咱们的redis容器需要自定义所以采用了dockerfile编写,现在需要启动多个容器则需要用到 —— 容器编排~

        “docker compose config”检查编写符合规范~ 

        执行完成构建镜像:

值得注意的是:当我们设置.context时,就是以这个路径去寻找相对路径下的文件

        启动服务,查看服务状态:

        查看redis07打印的日志,是否正确 —— 哈希槽已经被各个节点支配~

        我们再次进入redis01 ~ redis07任意一个容器中,检查容器功能是否正常~

# 进入容器
docker exec -it redis01 bash# -c 插入key值时,会自动重定向 映射的slots分片
/redis/redis-cli -c -a 123456

        查看集群节点详情信息~

        我们可以插入一些 {Key,Value}~

         完成资源释放,咱们使用Dockerfile搭建的Redis集群也就得到了一个圆满的成功~


Dockerfile结合Docker-Compose搭建C++微服务

构建C++微服务

        之前我们在容器中搭建的C++程序,一旦运行完成后就会自动退出~我们现在打算使用Dockerfile构建一个长时间运行的 C++服务器。

        这个服务器的功能很简单,就是一问一答,返回一个nginx经典的html~        

        构建相应目录:

        “/data/wgzzs/webcpp/cppweb”中,编写源代码main.cpp:

        这只是一个简短的C-S客户端模型,用来给客户端返回前端编写的html文件(这个文件我们借用的是Nginx页面)~

#include <iostream>
#include <cstring>
#include <cassert>
#include <fstream>
#include <string>#include <netinet/in.h>
#include <pthread.h>
#include <unistd.h>#include <sys/types.h>
#include <sys/socket.h>
using namespace std;struct pthread_data
{struct sockaddr_in client_addr;int clientfd;
};void InitNet(struct sockaddr_in &local, int &sock_fd)
{// init addrmemset(&local, 0, sizeof local);local.sin_family = AF_INET;local.sin_addr.s_addr = htons(INADDR_ANY);local.sin_port = htons(8011);// socket()int opt = 1;sock_fd = socket(AF_INET, SOCK_STREAM, 0);// reuse addrassert(sock_fd >= 0);setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));// bind()if (bind(sock_fd, (struct sockaddr *)&local, sizeof local) < 0){perror("bind error");cout << strerror(errno) << endl;}// listen()assert(listen(sock_fd, 5) == 0);cout << "WebCpp-Server Created..." << endl;
}void readfile(string *body)
{ifstream ifs("index.html", std::ios::binary);if (ifs.is_open() == false){perror("readfile");return;}size_t fsize = 0;ifs.seekg(0, ifs.end);fsize = ifs.tellg();ifs.seekg(0, ifs.beg);if (fsize > 0){body->resize(fsize);ifs.read(&(*body)[0], fsize);}ifs.close();
}void *serverHandler(void *args)
{struct pthread_data *pdata = (struct pthread_data *)args;int conn_fd = pdata->clientfd;std::cout << "Handler Task: " << pdata->clientfd << endl;char request[1024];int len = recv(conn_fd, request, 1024, 0);assert(len >= 0);// cout << "Message From Cli: " << request << endl;// char header[128] = "HTTP/1.1 200 ok\r\n";// char body[128] = "connection:close\r\n";// char blank_row[4] = "\r\n";char response_head[128] = "HTTP/1.1 200 ok\r\nconnection:close\r\n\r\n";// 首行+报头int s = send(conn_fd, response_head, strlen(response_head), 0);assert(s > 0);// 正文string body;readfile(&body);if(body.size() > 0) assert(send(conn_fd, body.c_str(), body.size(), 0) > 0);close(conn_fd);return nullptr;
}int main()
{int sock_fd;struct sockaddr_in local;InitNet(local, sock_fd);// 作为监听while (1){struct sockaddr_in client;int client_len = sizeof(client);int conn_fd = accept(sock_fd, (struct sockaddr *)&client, (socklen_t *)&client_len);// 分配线程去 完成任务struct pthread_data data;data.client_addr = client;data.clientfd = conn_fd;assert(data.clientfd >= 1);cout << "Get a new Link:" << data.clientfd << "~~" << endl;pthread_t pt;pthread_create(&pt, NULL, serverHandler, (void *)&data);}return 0;
}

        启动服务器,我们来看看效果~

        服务器访问效果:

        结果是,我们的程序能够正确地执行,达到我们想要的效果~

编写C++ Dockerfile应用

        我们现在要做的,就是将这份程序制作成镜像,并让它在咱们的容器中运行。

        进入 “/data/wgzzs/webcpp/cppweb” 目录,编写Dockerfile~

         进入 "/data/wgzzs/webcpp/nginx目录,编写bit.conf,用于使用nginx作为负载均衡器的功能~

        我们还需要继续编写nginx的Dockerfile:

     

C++微服务容器编排

        进入"/data/wgzzs/webcpp"目录,编写docker-compose.yml文件:

version: "3.6"
services: mywebcpp1:image: mywebcpp:v1.0build:context: ./cppwebmywebcpp2:image: mywebcpp:v1.0mywebcpp3:image: mywebcpp:v1.0web:image: mynginx:v1.0build:context: ./nginxports: - 8112:80depends_on:mywebcpp1:condition: service_startedmywebcpp2:condition: service_startedmywebcpp3:condition: service_started

        构建镜像: 

        启动服务,从nginx的日志来看,启动是没有任何问题的~

         访问nginx服务器6次,我们看看nginx是否能够将连接打在其他cpp服务器中~        

        我们都可以得知,连接请求被负载到了不同的服务器容器中~

        清理资源,完成咱们最后的收尾工作~        


本篇到此结束,感谢你的阅读

祝你好运,向阳而生~

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

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

相关文章

#QT(事件--快捷键保存文件)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;QEvent,QMouseEvent,QKeyEvent。 在上一个文本编辑器的基础上实现快捷键"ctrls"保存文件。 3.记录 &#xff08;1&#xff09;查看QEVENT的有效事件 &#xff08;2&#xff09; 所有时间均继承于QEvent&#xff0c;任…

微信小程序《简单、快速上手的微信小程序音乐播放器》+源代码+文档说明

文章目录 源代码下载地址项目介绍项目功能使用方法界面预览 项目备注源代码下载地址 源代码下载地址 点击这里下载源码 项目介绍 项目功能 首页&#xff1a;歌曲歌手搜索&#xff0c;轮播图&#xff0c;各大榜单&#xff0c;热门歌单 正在播放&#xff1a; 当前播放歌曲展示…

Parade Series - Web Streamer Low Latency

Parade Series - FFMPEG (Stable X64) 延时测试秒表计时器 ini/config.ini [system] homeserver storestore\nvr.db versionV20240312001 verbosefalse [monitor] listrtsp00,rtsp01,rtsp02 timeout30000 [rtsp00] typelocal deviceSurface Camera Front schemartsp ip127…

如何从不同维度对服务进行拆分

1.压力模型 高频高并发 商品详情页 低频突发流量 如秒杀 批量上架 2.主链路规划 不可缺少的环节 如果缺少了就无法形成完整的服务 如图营销计算就是一个服务业务 3.领域模型拆分DDD 4.用户群体拆分 2C 2B

springboot整合swagger,postman,接口规范

一、postman介绍 1.1概述 工具下载 Postman&#xff08;发送 http 请求的工具&#xff09; 官网&#xff08;下载速度比较慢&#xff09;&#xff1a;Download Postman | Get Started for Free 网盘下载&#xff1a;百度网盘 请输入提取码 1.2Http 请求格式 请求地址请求方法状…

VsCode 配置go开发环境之下载go tools

ctrl shift P 选择 go install/update tools&#xff0c;下载go tools 报错&#xff0c; 提升dial err。 将GOPROXY 和 GOSUMDB 按照如下配置&#xff0c;重启IDE即可成功下载 set GOPROXYhttps://goproxy.cn set GOSUMDBoff

jupyter中pip安装包会安装到别的环境。

文章目录 1. 查看jupyter当前环境和默认环境的路径和python版本2.安装包到正确的环境 如果你在 Jupyter Notebook 中使用 pip 安装包&#xff0c;它默认会将包安装到 Jupyter Notebook 所在的Python 环境。这可能会导致安装的包与你期望的环境不匹配。 1. 查看jupyter当前环境和…

麒麟系统Redis7.2哨兵集群部署

redis哨兵集群部署 1、原理 Redis 哨兵模式是指在 Redis 集群中,有一组专门的进程(即哨兵进程)负责监控主节点和从节点的状态,并在发现故障时自动进行故障转移,以保证 Redis 集群的高可用性。 Redis 提供了哨兵的命令,哨兵命令是一个独立的进程,哨兵进程会周期性地向主…

App的测试,和传统软件测试有哪些区别?增加哪些方面的测试用例

从上图可知&#xff0c;测试人员所测项目占比中&#xff0c;App测试占比是最高的。 这就意味着学习期间&#xff0c;我们要花最多的精力去学App的各类测试。也意味着我们找工作前&#xff0c;就得知道&#xff0c;App的测试点是什么&#xff0c;App功能我们得会测试&#xff0…

如何通过小程序上的产品力和品牌力提升用户的复购能力?

随着网络购物小程序的发展以及内容电商、社交电商、垂直电商、品牌自营等多个细分类型的出现&#xff0c;小程序成为用户日常购物、大促囤货以及首发抢购的重要场景&#xff0c;市场竞争也逐渐激烈。如何在用户侧获得更多转化、留存与复购&#xff0c;成为企业品牌日益关注的话…

第七课-----分支切平面

割平面方法的基本思想是对于一个优化问题而言&#xff0c;通过不断添加约束条件来切割可行域&#xff0c; 最终将可行域不断变小&#xff0c;相当于搜索空间变小。在LP中讲过&#xff0c;一个等式约束就等价于一个超平面&#xff0c;一个不等式约束就代表一个半空间&#xff0c…

【TB作品】MSP430,单片机,Proteus仿真,数字音乐盒,蜂鸣器音乐仿真

文章目录 题目要求如何根据简谱编曲仿真图代码介绍宏定义部分全局变量部分LCD 控制函数按键检测和处理函数蜂鸣器控制函数主函数部分 获取代码和仿真 题目要求 86 数字音乐盒的制作 1 设计要求 制作一个数字音乐盒,盒内存有3首乐曲,每首不少于30s。采用LCD显示乐曲信息, 开机时…

展开说说:Android之SharedPreferences

SharedPreferences 是一种轻量级的数据持久化存储机制。以key/value键值对形式存储在xml文件&#xff0c;用于保存一些应用程序数据。保存在 /data/data/PACKAGE_NAME/shared_prefs/xxx.Xml文件。 SharedPreferences 只能存储string&#xff0c;int&#xff0c;float&#xff…

【洛谷 P8661】[蓝桥杯 2018 省 B] 日志统计 题解(滑动窗口+优先队列+双端队列+集合)

[蓝桥杯 2018 省 B] 日志统计 题目描述 小明维护着一个程序员论坛。现在他收集了一份“点赞”日志&#xff0c;日志共有 N N N 行。其中每一行的格式是 ts id&#xff0c;表示在 t s ts ts 时刻编号 i d id id 的帖子收到一个“赞”。 现在小明想统计有哪些帖子曾经是“热…

matlab 电机仿真平台GUI

1、内容简介 略 74-可以交流、咨询、答疑 2、内容说明 略 电机仿真平台GUI 包含直流机要加调电压启动、回馈制动、串电阻调速 异步电动机要加串电阻启动、星三角启动、回馈制动模块 3、仿真分析 略 4、参考论文 略

【QT入门】VS2019+QT的开发环境配置

声明&#xff1a;该专栏为本人学习Qt知识点时候的笔记汇总&#xff0c;希望能给初学的朋友们一点帮助(加油&#xff01;) 往期回顾&#xff1a; 【QT入门】什么是qt&#xff0c;发展历史&#xff0c;特征&#xff0c;应用&#xff0c;QtCreator-CSDN博客【QT入门】Windows平台下…

项目三 操作学生管理数据库中的表

项目三 操作学生管理数据库中的表 1&#xff0c;使用MySQL中的常用数据类型 数据类型决定了数据的取值范围、存储方式与占用的空间大小以及能够对其进行的一组合法操作。 1.1&#xff0c;使用数值类型 1&#xff0c;MySQL 的数值类型大致可以分为两个类别&#xff1a;整数类…

论文阅读——GeoChat(cvpr2024)

GeoChat : Grounded Large Vision-Language Model for Remote Sensing 一、引言 GeoChat&#xff0c;将多模态指令调整扩展到遥感领域以训练多任务会话助理。 遥感领域缺乏多模式指令调整对话数据集。受到最近指令调优工作的启发&#xff0c;GeoChat 使用 Vicuna-v1.5和自动化…

深度学习-解读GoogleNet深度学习网络

深度学习-解读GoogleNet深度学习网络 深度学习中&#xff0c;经典网络引领一波又一波的技术革命&#xff0c;从LetNet到当前最火的GPT所用的Transformer&#xff0c;它们把AI技术不断推向高潮。2012年AlexNet大放异彩&#xff0c;它把深度学习技术引领第一个高峰&#xff0c;打…

android studio 连接mumu模拟器调试

1、打开mumu模拟器 2、在Android Studio 中 控制台 cd 到 sdk 目录下 platform-tools 文件夹&#xff0c;有一个adb.exe 可运行程序 一般指令&#xff1a; adb connect 127.0.0.1:7555 但是这个执行在window环境下可能会报错 解决方法是在 adb 之前加 ".\", 问题…