Zookeeper 面试题总结

news2024/11/22 0:21:02

Zookeeper

  • 1、工作中 Zookeeper 有什么用途吗
  • 2、zookeeper 数据模型是什么样的
  • 3、那你知道 znode 有几种类型呢
  • 4、你知道 znode 节点里面存储什么吗
  • 5、每个节点数据最大不能超过多少呢
  • 6、你知道 znode 节点上监听机制嘛
  • 7、那你讲下 Zookeeper 特性吧
  • 8、你刚提到顺序一致性,那 zookeeper 如何保证事务顺序一致性呢
  • 9、你知道 Zookeeper 服务器有几种角色嘛
  • 10、Zookeeper 下 Server 工作状态又有几种
  • 11、ZooKeeper 集群部署图
  • 12、ZooKeeper 如何保证主从节点数据一致性
  • 13、你讲一下 ZooKeeper 选举机制吧
  • 14、讲一下 zk 分布式锁实现原理吧
  • 15、ZooKeeper 集群为啥最好奇数台

1、工作中 Zookeeper 有什么用途吗

  1. 注册中心
    • 什么是注册中心
      • 注册中心是只有在分布式架构中才有的概念,注册中心是分布式架构中所有服务器注册信息等相关功能的专用服务器,注册的地址是服务器的名称与对应IP地址。分布式环境下的应用在启动时候都会向这个地方来注册自己的网络地址和名称。用一句话来概括,注册中心的作用就是存放和调度服务,实现服务和注册中心,服务与服务之间的通信。
      • 在分布式架构中,服务会注册到注册中心,应用 a 访问应用 b 时,则应用 a 首先通过应用 b 的应用名称向注册中心获取最新的 ip 地址,再根据 ip 地址访问应用 b。
    • 为什么需要注册中心
      • ① 在不用服务注册之前,去维护这种关系网络呢就是写死 IP 地址。将其他模块的 ip 和 port 写死在自己的配置文件里,甚至写死在代码里,每次要去新增或者移除1个服务的实例的时候,就得去通知其他所有相关联的服务去修改。随之而来的就是各个项目的配置文件的反复更新、每隔一段时间大规模的 ip 修改和机器裁撤,非常的痛苦。
      • ② 有了注册中心之后,每个服务在调用别人的时候只需要服务的名称就好,调用时会通过注册中心根据服务编码进行具体服务地址进行调用。
  2. 分布式锁
    • 分布式锁的实现方式有很多种,比如 Redis 、数据库 、zookeeper 等。个人认为 zookeeper 在实现分布式锁这方面是非常非常简单的。
  3. 命名服务
    • 命名服务指通过指定名字来获取资源或者服务地址。Zookeeper 可以创一个全局唯一路径,这个路径就可以作为一个名字。被命名实体可以集群中机器,服务地址,或者远程对象等。
  4. 集群管理
    • 集群管理包括集群监控和集群控制,其实就监控集群机器状态,剔除机器和加入机器。zookeeper 可以方便集群机器管理,它可以实时监控 znode 节点变化,一旦发现有机器挂了,该机器就会与 zk 断开连接,对用临时目录节点会被删除,其他所有机器都收到通知。

2、zookeeper 数据模型是什么样的

ZooKeeper 数据模型采用层次化的多叉树形结构,每个节点上都可以存储数据,这些数据可以是数字、字符串或者是二级制序列。并且。每个节点还可以拥有 N 个子节点,最上层是根节点以“/”来代表。每个数据节点在ZooKeeper 中被称为 znode,它是 ZooKeeper 中数据的最小单元。并且,每个 znode 都一个唯一的路径标识。

从下图可以更直观地看出:ZooKeeper 节点路径标识方式和 Unix 文件系统路径非常相似,都是由一系列使用斜杠"/"进行分割的路径表示,开发人员可以向这个节点中写入数据,也可以在节点下面创建子节点。这些操作我们后面都会介绍到。

在这里插入图片描述

3、那你知道 znode 有几种类型呢

我们通常是将 znode 分为 4 大类:

  • 持久(PERSISTENT)节点 :一旦创建就一直存在即使 ZooKeeper 集群宕机,直到将其删除。
  • 临时(EPHEMERAL)节点 :临时节点的生命周期是与 客户端会话(session) 绑定的,会话消失则节点消失 。并且,临时节点只能做叶子节点 ,不能创建子节点。
  • 持久顺序(PERSISTENT_SEQUENTIAL)节点 :除了具有持久(PERSISTENT)节点的特性之外, 子节点的名称还具有顺序性。比如 /node1/app0000000001 、/node1/app0000000002 。
  • 临时顺序(EPHEMERAL_SEQUENTIAL)节点 :除了具备临时(EPHEMERAL)节点的特性之外,子节点的名称还具有顺序性

4、你知道 znode 节点里面存储什么吗

  • stat :状态信息。

Stat 类中包含了一个数据节点的所有状态信息的字段,包括事务 ID(cZxid)、节点创建时间(ctime) 和子节点个数(numChildren) 等等,如下:

在这里插入图片描述

  • data : znode 存储业务数据信息。
  • acl : 记录客户端对 znode 节点访问权限,如 IP 等。
    • ZooKeeper 采用 ACL(AccessControlLists)策略来进行权限控制,类似于 UNIX 文件系统的权限控制。对于 znode 操作的权限,ZooKeeper 提供了以下 5 种:
      • CREATE : 能创建子节点
      • READ :能获取节点数据和列出其子节点
      • WRITE : 能设置/更新节点数据
      • DELETE : 能删除子节点
      • ADMIN : 能设置节点 ACL 的权限
    • 其中尤其需要注意的是,CREATE 和 DELETE 这两种权限都是针对 子节点 的权限控制。对于身份认证,提供了以下几种方式:
      • world : 默认方式,所有用户都可无条件访问。
      • auth :不使用任何 id,代表任何已认证的用户。
      • digest :用户名:密码认证方式: username:password 。
      • ip : 对指定 ip 进行限制
  • child : 当前节点子节点引用。

5、每个节点数据最大不能超过多少呢

为了保证高吞吐和低延迟,以及数据一致性,znode 只适合存储非常小数据,不能超过 1M,最好都小于 1K。

6、你知道 znode 节点上监听机制嘛

Watcher 为事件监听器,是 zk 非常重要的一个特性,很多功能都依赖于它,它有点类似于订阅的方式,即客户端向服务端注册指定的 watcher ,当服务端符合了 watcher 的某些事件或要求则会向客户端发送事件通知 ,客户端收到通知后找到自己定义的 Watcher 然后执行相应的回调方法 。

在这里插入图片描述

可以把 Watcher 理解成客户端注册在某个 Znode 上触发器,当这个 Znode 节点发生变化时(增删改查),就会触发 Znode 对应注册事件,注册客户端就会收到异步通知,然后做出业务改变。

zookeeper 监听原理

zookeeper的监听事件有四种

  • nodedatachanged 节点数据改变
  • nodecreate 节点创建事件
  • nodedelete 节点删除事件
  • nodechildrenchanged 子节点改变事件

在这里插入图片描述

ZooKeeper Watcher 机制主要包括客户端线程、客户端WatcherManager、Zookeeper 服务器三部分。

  1. 客户端向 ZooKeeper 服务器注册 Watcher 同时,会将 Watcher 对象存储在客户端 WatchManager 中。
  2. 当 zookeeper 服务器触发 watcher 事件后,会向客户端发送通知, 客户端线程从 WatcherManager 中取出对应Watcher 对象来执行回调逻辑。

7、那你讲下 Zookeeper 特性吧

  1. 全局数据一致:集群中每个服务器保存一份相同的数据副本,client无论连接到哪个服务器,展示的数据都是一致的,这是最重要的特征。
  2. 可靠性:如果消息被其中一台服务器接受,那么将被所有的服务器接受。
  3. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
  4. 数据更新原子性:一次数据更新要么成功(半数以上节点成功),要么失败,不存在中间状态。
  5. 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。

8、你刚提到顺序一致性,那 zookeeper 如何保证事务顺序一致性呢

9、你知道 Zookeeper 服务器有几种角色嘛

在这里插入图片描述

10、Zookeeper 下 Server 工作状态又有几种

  1. LOOKING:寻找 Leader 状态。当服务器处于该状态时,它会认为当前集群中没有 Leader,因此需要进入 Leader 选举状态。
  2. FOLLOWING:跟随者状态。表明当前服务器角色✁ Follower。
  3. LEADING:领导者状态。表明当前服务器角色✁ Leader。
  4. OBSERVING:观察者状态。表明当前服务器角色✁ Observer。

11、ZooKeeper 集群部署图

为了保证高可用,最好是以集群形态来部署 ZooKeeper,这样只要集群中大部分机器是可用的(能够容忍一定的机器故障),那么 ZooKeeper 本身仍然是可用的。通常 3 台服务器就可以构成一个 ZooKeeper 集群了。ZooKeeper 官方提供的架构图就是一个 ZooKeeper 集群整体对外提供服务。

在这里插入图片描述
上图中每一个 Server 代表一个安装 ZooKeeper 服务的服务器。组成 ZooKeeper 服务的服务器都会在内存中维护当前的服务器状态,并且每台服务器之间都互相保持着通信。集群间通过 ZAB 协议(ZooKeeper Atomic Broadcast)来保持数据的一致性。

最典型集群模式: Master/Slave 模式(主备模式)。在这种模式中,通常 Master 服务器作为主服务器提供写服务,其他的 Slave 服务器从服务器通过异步复制的方式获取 Master 服务器最新的数据提供读服务。

12、ZooKeeper 如何保证主从节点数据一致性

ZooKeeper 主要提供数据的一致性服务,其实现分布式系统的状态一致性依赖一个叫 Paxos 的算法。Paxos 算法在多台服务器通过内部的投票表决机制决定一个数据的更新与写入。

但Paxos 算法有点过于复杂、实现难度也比较高,所以 ZooKeeper 在编程实现的时候将其简化成了一种叫做 ZAB 的算法(Zookeeper Atomic Broadcast, Zookeeper 原子广播)。

在这里插入图片描述

ZAB 算法的目的,同样是在多台服务器之间达成一致,保证这些服务器上存储的数据是一致的。ZAB 算法的主要特点在于:需要在这些服务器中选举一个 Leader,所有的写请求都必须提交给 Leader。由 Leader 服务器向其他服务器(Follower)发起 Propose,通知所有服务器:我们要完成一个写操作请求,大家检查自己的数据状态,是否有问题。

如果所有 Follower 服务器都回复 Leader 服务器 ACK,即没有问题,那么 Leader 服务器会向所有 Follower 发送 Commit 命令,要求所有服务器完成写操作。这样包括 Leader 服务器在内的所有 ZooKeeper 集群服务器的数据,就都更新并保持一致了。如果有两个客户端程序同时请求修改同一个数据,因为必须要经过 Leader 的审核,而 Leader 只接受其中一个请求,数据也会保持一致。

在实际应用中,客户端程序可以连接任意一个 Follower,进行数据读写操作。如果是写操作,那么这个请求会被这个 Follower 发送给 Leader,进行如上所述的处理;如果是读操作,因为所有服务器的数据都是一致的,那么这个 Follower 直接返回自己本地的数据给客户端就可以了。

13、你讲一下 ZooKeeper 选举机制吧

服务器启动或者服务器运行期间(Leader 挂了),都会进入 Leader 选举,我们来看一下~假设现在 ZooKeeper 集群有五台服务器。

服务器启动 Leader 选举

在这里插入图片描述

服务器运行期间 Leader 选举

在这里插入图片描述

选举Leader规则:①EPOCH大的直接胜出 ②EPOCH相同,事务id大的胜出 ③事务id相同,服务器id大的胜出

总结:择优选取,保证leader是zk集群中数据最完整、最可靠的一台服务器。

14、讲一下 zk 分布式锁实现原理吧

ZooKeeper 分布式锁是基于临时顺序节点和Watcher(事件监听器) 实现的。

获取锁:

  1. 首先我们要有一个持久节点/locks,客户端获取锁就是在locks下创建临时顺序节点。
  2. 假设客户端 1 创建了/locks/lock1节点,创建成功之后,会判断 lock1是否是 /locks 下最小的子节点。
  3. 如果 lock1是最小的子节点,则获取锁成功。否则,获取锁失败。
  4. 如果获取锁失败,则说明有其他的客户端已经成功获取锁。客户端 1 并不会不停地循环去尝试加锁,而是在前一个节点比如/locks/lock0上注册一个事件监听器。这个监听器的作用是当前一个节点释放锁之后通知客户端 1(避免无效自旋),这样客户端 1 就加锁成功了。

释放锁:

  1. 成功获取锁的客户端在执行完业务流程之后,会将对应的子节点删除。
  2. 成功获取锁的客户端在出现故障之后,对应的子节点由于是临时顺序节点,也会被自动删除,避免了锁无法被释放。
  3. 我们前面说的事件监听器其实监听的就是这个子节点删除事件,子节点删除就意味着锁被释放。

在这里插入图片描述

分布式锁

package com.example.canal.zk;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class DistributedLock {

    private final String connectionString = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183";
    private final int sessionTimeout = 2000;
    private final ZooKeeper zk;
    private CountDownLatch countDownLatch = new CountDownLatch(1);
    private CountDownLatch waitLatch = new CountDownLatch(1);
    private String waitPath;
    private String currentMode;

    public DistributedLock() throws IOException, InterruptedException, KeeperException {

        // 获取连接
        zk = new ZooKeeper(connectionString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                // connectLatch 如果连接上zk 可以释放
                if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                    countDownLatch.countDown();
                }
                // waitLatch 需要释放
                if (watchedEvent.getType() == Event.EventType.NodeDeleted && watchedEvent.getPath().equals(waitPath)) {
                    waitLatch.countDown();
                }
            }
        });
        // 等待zk正常连接后,往下走程序
        countDownLatch.await();

        // 判断根节点/locks是否存在
        Stat stat = zk.exists("/locks", false);

        if (stat == null) {
            // 创建根节点,这是⼀个完全开放的ACL,持久节点
            zk.create("/locks", "locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }

    }

    // 对zk加锁
    public void zkLock() {

        try {
            // 创建对应的临时顺序节点
            currentMode =
                zk.create("/locks/" + "seq-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

            // 判断创建的节点是否是序号最小的节点,如果是获取到锁,如果不是,监听他序号前一个节点
            List<String> children = zk.getChildren("/locks", false);
            if (children.size() == 1) {
                return;
            } else {

                //[seq-0000000016, seq-0000000017]
                Collections.sort(children);

                // 获取节点名称 /locks/seq-0000000017 -> seq-0000000017
                String thisNode = currentMode.substring("/locks/".length());

                // 通过seq-0000000017获取该节点在children集合的位置
                int index = children.indexOf(thisNode);

                // 判断
                if (index == -1) {
                    System.out.println("数据异常");
                } else if (index == 0) {
                    // 就一个节点,可以获取锁了
                    return;
                } else {
                    // 需要监听 他前一个结点的变化
                    waitPath = "/locks/" + children.get(index - 1);
                    zk.getData(waitPath, true, null);
                    // 等待监听
                    waitLatch.await();
                }

            }

        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    // 解锁
    public void unZkLock() {
        // 删除节点
        try {
            zk.delete(currentMode, -1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }
}

测试类

package com.example.canal.zk;

import org.apache.zookeeper.KeeperException;

import java.io.IOException;

public class DistributedLockTest {

    public static void main(String[] args) throws InterruptedException, IOException, KeeperException {
        final DistributedLock lock1 = new DistributedLock();
        final DistributedLock lock2 = new DistributedLock();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock1.zkLock();
                    System.out.println("线程1 启动,获取到锁");
                    Thread.sleep(5 * 1000);
                    lock1.unZkLock();
                    System.out.println("线程1 释放锁");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock2.zkLock();
                    System.out.println("线程2 启动,获取到锁");
                    Thread.sleep(5 * 1000);
                    lock2.unZkLock();
                    System.out.println("线程2 释放锁");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

为什么要用临时顺序节点

临时节点相比持久节点,最主要的是对会话失效的情况处理不一样,临时节点会话消失则对应的节点消失。这样的话,如果客户端发生异常导致没来得及释放锁也没关系,会话失效节点自动被删除,不会发生死锁的问题。

使用 Redis 实现分布式锁的时候,我们是通过过期时间来避免锁无法被释放导致死锁问题的,而 ZooKeeper 直接利用临时节点的特性即可。

假设不适用顺序节点的话,所有尝试获取锁的客户端都会对持有锁的子节点加监听器。当该锁被释放之后,势必会造成所有尝试获取锁的客户端来争夺锁,这样对性能不友好。使用顺序节点之后,只需要监听前一个节点就好了,对性能更友好。

为什么要设置对前一个节点的监听

同一时间段内,可能会有很多客户端同时获取锁,但只有一个可以获取成功。如果获取锁失败,则说明有其他的客户端已经成功获取锁。获取锁失败的客户端并不会不停地循环去尝试加锁,而是在前一个节点注册一个事件监听器。

这个事件监听器的作用是: 当前一个节点对应的客户端释放锁之后(也就是前一个节点被删除之后,监听的是删除事件),通知获取锁失败的客户端(唤醒等待的线程,Java 中的 wait/notifyAll ),让它尝试去获取锁,然后就成功获取锁了。

15、ZooKeeper 集群为啥最好奇数台

ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooKeeper 服务器个数大于宕掉的个数的话整个 ZooKeeper 才依然可用。假如我们的集群中有 n 台 ZooKeeper 服务器,那么也就是剩下的服务数必须大于 n/2。先说一下结论,2n 和 2n-1 的容忍度是一样的,都是 n-1,大家可以先自己仔细想一想,这应该是一个很简单的数学问题了。

比如假如我们有 3 台,那么最大允许宕掉 1 台 ZooKeeper 服务器,如果我们有 4 台的的时候也同样只允许宕掉 1 台。 假如我们有 5 台,那么最大允许宕掉 2 台 ZooKeeper 服务器,如果我们有 6 台的的时候也同样只允许宕掉 2 台。

综上,何必增加那一个不必要的 ZooKeeper 呢?

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

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

相关文章

LRU缓存淘汰策略——面试高频

⭐️前言⭐️ 本文主要介绍在面试中常见的高频手撕算法题目&#xff0c;LRU算法&#xff0c; &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区…

LEVIR-CD遥感建筑变化检测数据集

LEVIR-CD是一个新的大规模遥感二元变化检测数据集&#xff0c;它将有助于开发新的基于深度学习的遥感图像变化检测算法。 下载地址&#xff1a;https://justchenhao.github.io/LEVIR/ 历史消息 20230311:我们为LEVIR_CD中的每个样本补充了地理空间信息&#xff08;例如&#…

实例分割算法BlendMask

实例分割算法BlendMask 论文地址&#xff1a;https://arxiv.org/abs/2001.00309 github代码&#xff1a;https://github.com/aim-uofa/AdelaiDet 我的个人空间&#xff1a;我的个人空间 密集实例分割 ​ 密集实例分割主要分为自上而下top-down与自下而上bottom-up两类方法…

Node.js代码实例:简单Web服务端

文章目录 前言代码仓库为什么要写一份Node.js简单Web服务端的代码实例&#xff1f;内容目录结构代码server.jsindex.htmlindex.cssindex.jsvalue.html 结果总结参考资料作者的话 前言 Node.js代码实例&#xff1a;简单Web服务端。 代码仓库 yezhening/Programming-examples: …

LVS-DR

系列文章目录 文章目录 系列文章目录一、1.2. 二、实验1.2. 总结 一、 1. 2. 二、实验 1. 先把四台机器都关闭防火墙和安全机制 vim /etc/sysconfig/selinux把selinux都改成disabled 在NFS里面建立两个共享目录 给文件执行权限并写入内容给html 和www vim /etc/expor…

【C++】C++中的类型转化

说起类型转化&#xff0c;我们在C语言之前的学习中可以了解到&#xff0c;类型转换可以分为两种情况&#xff1a;隐式类型转化&#xff1b;显示类型转化。但是为什么在c中还要继续对类型转化做文章呢&#xff1f;我们一起来看&#xff1a; 目录 1. C语言中的类型转换 2. C强制…

【Transformer系列(5)】Transformer代码超详细解读(Pytorch)

前言 前面几篇我们一起读了transformer的论文&#xff0c;更进一步了解了它的模型架构&#xff0c;这一篇呢&#xff0c;我们就来看看它是如何代码实现的&#xff01; &#xff08;建议大家在读这一篇之前&#xff0c;先去看看上一篇模型结构讲解 这样可以理解更深刻噢&…

Python 基础(十二):字典

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录 一、声明字典1.1 使用 {} 声明字典1.2 使用 dict 函数声明字典1.3 声明一个空的字典 二…

【数据结构】AVLTree

1.AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数G.M.Adelson-Velskii 和E.M.Landis在1962年 发明了一种解决上…

会话与会话技术(Session)

前言 Cookie将用户的信息保存在各自的浏览器中&#xff0c;并且可以在多次请求下实现数据的共享。但是如果当传递的信息较多时&#xff0c;Cookie技术会增大服务器程序处理的难度&#xff0c;因此&#xff0c;Servlet提供了另一种会话技术————Session&#xff0c;Session可…

跟李沐学AI——实用机器学习(入门版)

机器学习目录 2.1 探索性数据分析 2.2 数据清理 2.3 数据变换 2.4 特征工程 2.5 数据科学家的日常 Stanford University Practical machine learning 2.1 探索性数据分析 ​ 对目标的ftr数据进行处理&#xff0c;针对不同的信息做出不同的图形 输出数据集的行数和列数以及前十…

ArcGIS Pro地理空间数据处理完整工作流实训及python技术融合

GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来&#xff0c;达到对地理和属性信息的综合管理。GIS的…

1、TI335x环境建立

记录裸机开发&#xff0c;TI A8系列处理器的AM335x过程&#xff0c;本次开发的是3352&#xff0c;在此基础上开发。 1、硬件准备&#xff1a; 已经测试调试ok的3352测试板&#xff0c;经过查看发现&#xff0c;am3352引出的下载接口是JTAG口&#xff0c;而我手里只有Jlink&…

Kubernetes---Pod调度、标签、配额、策略

静态pod 静态pod由user直接创建调用&#xff0c;不能迁移 由kebelet守护进程直接管理的pod&#xff0c;无需APIserver监管 kubelet监视每个静态pod 静态pod永远绑定到一个指定节点上的kubelet 静态pod spec不能引用其他API对象 静态pod配置路径/var/lib/kubelet/config.yaml里面…

CSS背景相关属性

一、背景颜色 属性名&#xff1a;background-color (bgc) 属性值&#xff1a;颜色取值&#xff1a;关键字&#xff0c;rgb表示法&#xff0c;rgba表示法&#xff0c;十六进制表示。 注&#xff1a; 背景颜色默认透明&#xff1a;rgba&#xff08;0&#xff0c;0&#xff0c…

C语言积锦

代码区&#xff1a;text 代码执行二进制码&#xff08;程序指令&#xff09; 具有共享、只读特性 数据区&#xff1a;1.初始化数据区data 2.未初始化数据区 bss 3.常量区 栈区&#xff1a;系统为每一个程序分配一个临时的空间 局部变量、函数信息、函数参数、数组。栈区大…

干货|Graphpad Prism也能做ERP图?So Easy!

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 不知道你是否注意过这样一个现象。 在心理学大会报告的时候&#xff0c;专家经常会说一句话&#xff1a; 这个结果很漂亮&#xff01;&#xff01;&#xff01; 第一次听见的时候&#x…

K8s图形化管理工具Dasboard部署及使用

文章目录 一、Dashboard简介二、Dashboard部署安装三、配置Dashboard登入用户1、通过Token令牌登入2、通过kubeconfig文件登入 四、Dashboard创建容器 一、Dashboard简介 Kubernetes Dashboard是一个Web UI&#xff0c;用于管理Kubernetes集群中的应用程序和资源。它提供了一个…

使用wireshark抓包理解tcp协议和tls

首先下载安装wireshark 打开软件 1.选则自己连结的网络&#xff1b; 此时就会捕获的数据 2.加上端口过滤。 3.启动一个本地的http服务(这里采用的nodejs)&#xff1b; // server.js import koa from koa; const app new koa(); app.use(ctx > {ctx.body "hell…

托福听力专项 // Unit1 Listening for Main Ideas // Practice with Lectures // 共4篇

目录 Listening for Main Idea Lecture A a music class 单词 内容总结 Lecture B 单词 错题分析 Lecture C 单词 错题分析 Lecture D 单词 Listening for Main Idea Lecture A a music class 单词 evolve(v)to develop slowlyincorporate(v)to take in or includ…