镜像制作实战篇

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


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/webapp
    build: ./webapp
# 注解:
该镜像的构建,是由 "awesome"的子目录“webapp"决定。
如果该文件(webapp) 缺少dockerfile 就会发生报错


# 方式二
  backend:
    image: awesome/database
    build: 
      context: ./backend
      dockerfile: ./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-master
    image: mysqlmaster:v1.0
    restart: always
    container_name: mysql-master
    volumes: 
      - ./mastervarlib:/var/lib/mysql
    ports: 
      - 8080:3306
    environment: 
      MYSQL_ROOT_PASSWORD: root
    privileged: true
    command: ['--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-slave
    image: mysqlslave:v1.0
    restart: always
    container_name: mysql-slave
    volumes:
      - ./slavevarlib:/var/lib/mysql
    ports:
      - 8081:3306
    environment:
      - MYSQL_ROOT_PASSWORD=root
    privileged: true
    command: ['--server-id=2',
              '--relay-log=slave-relay',
              '--lower_case_table_names=1',
              '--character-set-server=utf8',
              '--collation-server=utf8_general_ci']  
    depends_on:
      - mysql-master

  mysql_slave2:
    # build: 
    #   context: ./ 
    #   dockerfile: ./slave/Dockerfile-slave
    image: mysqlslave:v1.0
    restart: always
    container_name: mysql-slave2
    volumes:
      - ./slavevarlib2:/var/lib/mysql
    ports:
      - 8082:3306
    environment:
      - MYSQL_ROOT_PASSWORD=root
    privileged: true
    command: ['--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 addr
    memset(&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 addr
    assert(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.0
  build:
    context: ./cppweb
  mywebcpp2:
    image: mywebcpp:v1.0
  mywebcpp3:
    image: mywebcpp:v1.0

  web:
    image: mynginx:v1.0
    build:
      context: ./nginx
    ports: 
    - 8112:80
    depends_on:
      mywebcpp1:
        condition: service_started
      mywebcpp2:
        condition: service_started
      mywebcpp3:
        condition: service_started

        构建镜像: 

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

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

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

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


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

祝你好运,向阳而生~

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

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

相关文章

Linux系统部署DolphinScheduler任务调度系统并实现无公网IP远程访问

文章目录 前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinScheduler公网地址 前言 本篇教程和大家分享一下DolphinScheduler的安装部署及如何实现公网远程访问&#xff0c;结合内…

常用加密算法解析

对称加密算法 所谓对称&#xff0c;就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。算法是一组规则&#xff0c;规定如何进行加密和解密。 分类 常用的算法有&#xff1a;DES、3DES、AES等。 DES 全称为Data Encryption…

代码随想录阅读笔记-字符串【替换数字】

题目 给定一个字符串 s&#xff0c;它包含小写字母和数字字符&#xff0c;请编写一个函数&#xff0c;将字符串中的字母字符保持不变&#xff0c;而将每个数字字符替换为number。 例如&#xff0c;对于输入字符串 "a1b2c3"&#xff0c;函数应该将其转换为 "anu…

地下电缆频繁被挖断!智能地钉保卫电缆不马虎

随着城市规模的不断扩大和环境美化的高需求&#xff0c;越来越多管道线路转战地下&#xff0c;然而在城市建设过程中&#xff0c;却经常发生地下电缆、燃气管道、水管被破坏或挖断的事故&#xff0c;对居民生活和社会生产造成严重影响。以下是几起地下管线外破事故&#xff1a;…

实体门店加盟全解析:如何选择加盟项目与避免风险

对于想要开实体店或创业的人来说&#xff0c;拥有一个全面的运营方案是成功的关键。作为一名开鲜奶吧5年的创业者&#xff0c;我将为大家详细分享从选址到日常管理的实体店运营要点&#xff0c;帮助创业者少走弯路。 一、选择加盟项目 1.行业前景&#xff1a;选择一个有发展前…

CrossEntropyLoss 和NLLLoss的关系

交叉熵损失在做一件什么事? 看公式: x是预测(不需要softmax归一化),y是label, N是batch维度的数量,交叉熵损失,干了三件事. 1. 对输入在类别维度求softmax 2. 多softmax后的数,求log 3. 对(样本数, 类别数)为shape的tensor计算NLLLoss. 其中,NLLloss做的就是log取负, 和o…

WanAndroid(鸿蒙版)开发的第四篇

前言 DevEco Studio版本&#xff1a;4.0.0.600 WanAndroid的API链接&#xff1a;玩Android 开放API-玩Android - wanandroid.com 其他篇文章参考&#xff1a; 1、WanAndroid(鸿蒙版)开发的第一篇 2、WanAndroid(鸿蒙版)开发的第二篇 3、WanAndroid(鸿蒙版)开发的第三篇 …

(三)OpenOFDM符号对齐

符号对齐 模块&#xff1a;sync_long.v输入&#xff1a;I (16), Q (16), phase_offset (32), short_gi (1)输出&#xff1a;long_preamble_detected (1), fft_re (16), fft_im (16) 检测到数据包后&#xff0c;下一步是精确确定每个 OFDM 符号的起始位置。在802.11中&#xf…

基于大语言模型(LLM)的表格理解任务探索与实践

大语言模型&#xff08;LLMs&#xff09;的发展日新月异&#xff0c;为表格理解任务带来了新的可能性。表格理解任务&#xff0c;如基于表格的问答和表格事实验证&#xff0c;要求从自由形式的文本和半结构化的表格数据中提取深层次的语义信息。与泛化的文本推理任务不同&#…

数字电子技术实验(八)

单选题 1.3线-8线译码器74138&#xff0c;当输入时&#xff0c;输出有效的是哪路信号 答案&#xff1a;D 评语&#xff1a;0分 单选题 2.用74161计数器实现十进制计数器&#xff0c;置数端的输入信号为&#xff1f; 答案&#xff1a;C 评语&#xff1a;0分 单选题 3.电路中…

《ElementPlus 与 ElementUI 差异集合》el-input 多包裹一层 el-input__wrapper

差异 element-ui el-input 中&#xff0c;<div class"el-input"> 下一级就是 <input> 标签 &#xff1b;element-plus el-input中&#xff0c;<div class"el-input"> 和 <input> 标签之间多了一层 <div class"el-input__…

【LabVIEW FPGA入门】FPGA中的数据流

LabVIEW 以数据流方式执行代码。 当节点的所有输入上都存在数据时&#xff0c;该节点就会执行。 当节点完成执行时&#xff0c;节点的输出将数据传递到下游的下一个节点。 LabVIEW FPGA 使用三个组件来维护这种数据流范例。 节点具有与其功能相对应的逻辑 同步&#xff0c;该组…

直播预告 | 同立海源联合景达生物、星奕昂生物共话“NK细胞药物研发进展及工艺开发策略”!

2023年&#xff0c;免疫细胞治疗领域的产业化步伐显著加快&#xff0c;多种新型细胞治疗药物的上市进程不断推进&#xff0c;为市场带来了多元化和差异化的发展机遇。通用型免疫细胞产品、TCR-T、TIL等创新药物的涌现&#xff0c;不仅丰富了治疗选择&#xff0c;还推动了整个行…

redis学习-redis介绍

目录 1.redis介绍 2.redis常用命令&#xff08;可以在官网的命令中查看redis的所有命令&#xff09; 2.1终端命令 2.2 redis通用命令 2.3五大基本类型的命令以及特殊情况分析 &#xff08;导航&#xff09; 3.事务 4. redis实现消息订阅 5. redis的两种持久化策略 …

第二证券|换手率高代表什么?

换手率是衡量一只股票交易是否活泼的重要目标之一&#xff0c;换手率越高阐明该股交易越活泼&#xff0c;换手率越低阐明该股越不活泼&#xff0c;其所呈现的方位不同&#xff0c;其含义也有所不同。 当股票经过长期的上涨之后&#xff0c;在高位呈现较高的换手率时&#xff0c…

使用ChatGPT高效完成简历制作[中篇2]-有爱AI实战教程(九)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、导读&#xff1a; 在使用 ChatGPT 时&#xff0c;当你给的指令越精确&#xff0c;它的回答会越到位&#xff0c;举例来说&#xff0c;假如你要请它帮忙写文案&#xff0c…

算法——贪心

「贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优」 贪心无套路 1. 分发饼干 贪心策略&#xff1a; &#xff08;1&#xff09;局部最优就是大饼干喂给胃口大的&#xff0c;充分利用饼干尺寸喂饱一个&#xff0c;全局最优就是喂饱尽可能多的小孩 &#xff08…

智能化代采系统在供应链管理中的应用探讨

随着信息技术的飞速发展和智能化技术的应用&#xff0c;供应链管理领域迎来了巨大的变革。智能化代采系统作为一种先进的供应链管理工具&#xff0c;正在逐渐改变传统的采购和供应链管理模式。本文将从系统集成与优化、数据分析与预测、智能采购决策、供应商管理、风险控制与优…

[HackMyVM] Quick

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 0a:00:27:00:00:05 (Un…