当前位置: 首页 > news >正文

怎么做一元抽奖网站/seo搜索引擎优化总结报告

怎么做一元抽奖网站,seo搜索引擎优化总结报告,另类小说 Wordpress,传媒公司招聘etcd 介绍 etcd 简介 etc (基于 Go 语言实现)在 Linux 系统中是配置文件目录名;etcd 就是配置服务; etcd 诞生于 CoreOS 公司,最初用于解决集群管理系统中 os 升级时的分布式并发控制、配置文件的存储与分发等问题。基…

etcd 介绍


etcd 简介


etc (基于 Go 语言实现)在 Linux 系统中是配置文件目录名;etcd 就是配置服务;

etcd 诞生于 CoreOS 公司,最初用于解决集群管理系统中 os 升级时的分布式并发控制、配置文件的存储与分发等问题。基于此,etcd 设计为提供高可用、强一致性的小型** kv 数据存储**服务。项目当前隶属于 CNCF 基金会,被包括 AWS、Google、Microsoft、Alibaba 等大型互联网公司广泛使用;

etcd 是一个可靠的分布式 KV 存储,其底层使用 Raft 算法保证一致性,主要用于共享配置、服务发现、集群监控、leader 选举、分布式锁等场景;

1)共享配置:配置文件的存储与分发,将配置文件存储在 etcd 中,其它节点加载配置文件;如需修改配置文件,则修改后,其它节点只需重新加载即可;

2)服务发现:客户端请求经过 etcd 分发给各个服务端,此时如果增加一个服务端并连接到 etcd,由于客户端在一直监听着 etcd,所以客户端能够快速拉去新增服务端地址,并将客户端请求通过 etcd 下发到新增的服务端;

3)集群监控:客户端会通过 etcd 监控所有的 master、slave 节点,一旦有节点发生宕机,客户端能够及时发现;

4)leader 选举:假设一个 master 节点连接多个 slave 节点,如果 master 节点发生宕机,此时 etcd 会从 slave 节点中选取一个节点作为 master 节点;

5)分布式锁:常规情况下锁的持有者和释放者是进程中的线程,而在分布式情况下,锁的持有者和释放者可以是微服务或进程;

etcd 安装


1)安装 golang 环境;

2)下载并编译安装 etcd;

// 下载源代码
git clone https://gitee.com/k8s_s/etcd.git// 设置源代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct// 进入 etcd 目录
cd etcd// 切换最新分支
git checkout release-3.5go mod vendor
./build在 etcd/bin 目录生成对应的执行文件 etcd、etcdctl 和 etcdutl// 查看 etcd 版本
./etcdctl version

说明:可以到 Gitee - 基于 Git 的代码托管和研发协作平台 网站搜 etcd 下载最新的即可!

执行结果如下:

etcd 使用


etcd 的启动与使用

cd etcd/bin// 启动 etcd
nohup ./etcd > ./start.log 2>&1 &// 使用 v3 版本 api
export ETCDCTL_API=3// ./etcdctl + etcd 命令即可
./etcdctl put key val

执行结果如下所示:

etcd v2 和 v3 比较


扩展:一般情况下一个请求需要建立一条连接,比较浪费资源,所以有了 http + json 通信模式(json 是一种协议),但 json 加解密非常慢;

  • 使用 gRPC + protobuf 取代 http + json 通信,提高通信效率;gRPC 只需要一条连接;http 是每个请求建立一条连接;protobuf(是一种二进制协议所以包体小)加解密比 json 加解密速度得到数量级的提升;包体也更小;
  • v3 使用 lease (租约)替换 key ttl 自动过期机制(lease 将过期日期一致的 key 绑定到实体(该实体被称为 lease),通过检测实体的过期时间达到批量检查 key 过期时间的效果,效率更高);
  • v3 支持事务和多版本并发控制(一致性非锁定读)的磁盘数据库;而 v2 是简单的 kv 内存数据库(可靠性低,一旦服务器宕机数据无法得到保存);
  • v3 是扁平的 kv 结构;v2 是类型文件系统的存储结构;

扩展:

1)文件系统的存储结构

  • /node
  • /node/node1
  • /node/node2
  • /node/node1/sub1
  • /node/node1/sub2

2)扁平的 kv 结构

  • node
  • node1
  • node2
  • node3
  • 使用 get node --prefix 命令获取对应文件

etcd 架构(体系结构)


etcd 体系结构如下所示:

  • boltdb 是一个单机的支持事务的 kv 存储,etcd 的事务是基于 boltdb 的事务实现的;boltdb 为每一个 key 都创建一个索引(B+树);该 B+ 树存储了 key 所对应的版本数据;
  • wal(write ahead log)预写式日志实现事务日志的标准方法;执行写操作前先写日志,跟 mysql 中 redo 类似,wal 实现的是顺序写,而若按照 B+ 树写,则涉及到多次 io 以及随机写;
  • snapshot 快照数据,用于其他节点同步主节点数据从而达到一致性地状态;类似 redis 中主从复制中 rdb 数据恢复;流程:1. leader 生成 snapshot;2. leader 向 follower 发送 snapshot;3. follower 接收并应用 snapshot;gRPC server ectd 集群间以及 client 与 etcd 节点间都是通过 gRPC 进行通讯;

etcd APIs


数据版本号机制


  • term:leader 任期,leader 切换时 term 加一;全局单调递增,64bits;
  • revision:etcd 键空间版本号,key 发生变更,则 revision 加一;全局单调递增,64bits;
  • kvs:
    • create_revision 创建数据时,对应的版本号;
    • mod_revision 数据修改时,对应的版本号;
    • version 当前的版本号;标识该 val 被修改了多少次;

示例分析:

# ./etcdctl put key2 val2
OK
# ./etcdctl get key2
key2
val2
# ./etcdctl get key2 -w json
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":9,"raft_term":7},"kvs":[{"key":"a2V5Mg==","create_revision":9,"mod_revision":9,"version":1,"value":"dmFsMg=="}],"count":1}

参数说明:

  • cluster_id:集群 id;
  • member_id:当前 etcd 节点 id;
  • revision:整个 etcd 的版本 id,且只要 key 发生变更(增、删、改),则 revision 加一;全局单调递增,64bits;
  • raft_term:leader 任期,leader 切换时 term 加一;全局单调递增,64bits;
  • kvs:
    • create_revision 创建数据时,对应的版本号;
    • mod_revision 数据修改时,对应的版本号;
    • version 当前的版本号;标识该 val 被修改了多少次;

注:"key":"a2V5Mg==" 和 "value":"dmFsMg==" 是因为值被加密了,在 get 时会对其进行解密!

执行结果:

设置


设置即存储共享配置信息;

NAME:put - Puts the given key into the storeUSAGE:etcdctl put [options] <key> <value> (<value> can also be given fromstdin) [flags]DESCRIPTION:Puts the given key into the store.When <value> begins with '-', <value> is interpreted as a flag.Insert '--' for workaround:$ put <key> -- <value>$ put -- <key> <value>If <value> isn't given as a command line argument and '--ignorevalue' is not specified,this command tries to read the value from standard input.If <lease> isn't given as a command line argument and '--ignorelease' is not specified,this command tries to read the value from standard input.For example,$ cat file | put <key>will store the content of the file to <key>.OPTIONS:-h, --help[=false] help for put--ignore-lease[=false] updates the key using its current lease--ignore-value[=false] updates the key using its current value--lease="0" lease ID (in hexadecimal) to attach to thekey--prev-kv[=false] return the previous key-value pair beforemodification

语法命令:

put key val// 存储 key value 的同时返回上一次存储的 key value
put key val --prev-kv

删除


删除 key vla;

NAME:del - Removes the specified key or range of keys [key, range_end)USAGE:etcdctl del [options] <key> [range_end] [flags]OPTIONS:--from-key[=false] delete keys that are greater than or equal to the given key using byte compare-h, --help[=false]        help for del--prefix[=false]      delete keys with matching prefix--prev-kv[=false]     return deleted key-value pairs

语法命令:

del key// 删除成功,返回 1
// 若 key 不存在,则返回 0

获取


获取 key vla;

NAME:get - Gets the key or a range of keysUSAGE:etcdctl get [options] <key> [range_end] [flags]OPTIONS:--consistency="l"             Linearizable(l) or Serializable(s)--count-only[=false]          Get only the count--from-key[=false]            Get keys that are greater than or equal to the given key using byte compare-h, --help[=false]                help for get--keys-only[=false]           Get only the keys--limit=0                     Maximum number of results--order=""                    Order of results; ASCEND or DESCEND(ASCEND by default)--prefix[=false]              Get keys with matching prefix--print-value-only[=false]    Only write values when using the "simple" output format--rev=0                       Specify the kv revision--sort-by=""                  Sort target; CREATE, KEY, MODIFY, VALUE, or VERSION

语法命令:

get key// 获取前缀匹配 key 的所有 key val
get key --prefix   // 获取字符串小于 key2 的所有 key val
get key key2 // 获取字符串大于等于 key2 的所有 key val
get key2 --from-key// 只获取字符串等于 key2 的 key
get key2 --keys-only// 获取前缀匹配 key 的所有 key
get key --prefix --keys-only// 获取前缀匹配 key 的前两个 key
get key --prefix --keys-only --limit=2// 先排序,再获取前缀匹配 key 的前两个 key
get key --prefix --keys-only --limit=2 --sort-by=value

get “小于” 案例

// 获取所有前缀和 key 匹配的 key val
# ./etcdctl get key --prefix
key
val2023
key1
val1
key2
val2
key20
val20
key2024
val2024// 范围查询,获取 key2 之前(范围区间为左闭右开)的 key val    
# ./etcdctl get key key2
key
val2023
key1
val1

注:比较范围区间时是按字符串进行比较的,如:key、key1、key2、key20、key2024 中只有 key、key1 小于 key2;

执行结果:

get “大于等于” 案例

# ./etcdctl get key --prefix
key
val2023
key1
val1
key2
val2
key20
val20
key2024
val2024
# ./etcdctl get key2 --from-key
key2
val2
key20
val20
key2024
val2024

执行结果:

监听


用来实现监听和推送服务;

NAME:watch - Watches events stream on keys or prefixesUSAGE:etcdctl watch [options] [key or prefix] [range_end] [--] [execcommand arg1 arg2 ...] [flags]OPTIONS:-h, --help[=false]                    help for watch     -i, --interactive[=false]             Interactive mode--prefix[=false]                  Watch on a prefix if prefix is set--prev-kv[=false]                 get the previous key-value pair before the event happens --progress-notify[=false]         get periodic watch progress notification from server--rev=0                           Revision to start watching

语法命令:

// 监听 key 的变动
watch key    1) 启两个 session
2) 在 session A 中执行:WATCH key
3) 在 session B 中执行操作 key 的命令,如:PUT key val,DEL key 等,则同时会在 session A 中显示具体操作// 当前事件发生前先获取前一个 key val
watch key --prev-kv// 监听多个 key 的变动
watch key --prefix

说明:监听时也可以指定监听范围和版本等信息;

事务


用于分布式锁以及 leader 选举;保证多个操作的原子性;确保多个节点数据读写的一致性;

有关数据版本号信息请参考上述:数据版本号机制 部分;

NAME:txn - Txn processes all the requests in one transactionUSAGE:etcdctl txn [options] [flags]OPTIONS:-h, --help[=false]                     help for txn-i, --interactive[=false]              Input transaction in interactive mode事务
1. 比较1. 比较运算符 > = < !=2. create 获取key的create_revision3. mod 获取key的mod_revision4. value 获取key的value5. version 获取key的修改次数
2. 比较成功,执行下述代码1. 成功后可以操作多个 del put get2. 这些操作保证原子性
3. 比较失败,执行下述代码1. 成功后可以操作多个 del put get2. 这些操作保证原子性

语法命令:

TXN if/ then/ else ops

mod 比较案例

# ./etcdctl put key val1995
OK
# ./etcdctl get key -w json
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":12,"raft_term":7},"kvs":[{"key":"a2V5","create_revision":2,"mod_revision":12,"version":5,"value":"dmFsMTk5NQ=="}],"count":1}# ./etcdctl put key val2024
OK
# ./etcdctl get key -w json
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":13,"raft_term":7},"kvs":[{"key":"a2V5","create_revision":2,"mod_revision":13,"version":6,"value":"dmFsMjAyNA=="}],"count":1}
# ./etcdctl txn -i
compares:
mod("key")="9"
Error: malformed comparison: mod("key")="9"; got mod("key")  ""
# ./etcdctl txn -i
compares:
mod("key") = "12"success requests (get, put, del):
get keyfailure requests (get, put, del):
get key --rev=12FAILUREkey
val1995

从上述执行结果来看,代码走的是 比较失败 的逻辑;

注:mod("key") = "12" 等号前后要有空格,不然会报错!

执行结果:

create 比较案例

# ./etcdctl txn -i
compares:
create("key") = "2"success requests (get, put, del):
get keyfailure requests (get, put, del):
del keySUCCESSkey
val2024

执行结果:

version 比较案例

# ./etcdctl put key val2020
OK
# ./etcdctl get key -w json
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":14,"raft_term":7},"kvs":[{"key":"a2V5","create_revision":2,"mod_revision":14,"version":7,"value":"dmFsMjAyMA=="}],"count":1}
# ./etcdctl put key val2023
OK
# ./etcdctl get key -w json
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":15,"raft_term":7},"kvs":[{"key":"a2V5","create_revision":2,"mod_revision":15,"version":8,"value":"dmFsMjAyMw=="}],"count":1}
# ./etcdctl txn -i
compares:
version("key") = "7"success requests (get, put, del):
get keyfailure requests (get, put, del):
get key --rev=14FAILUREkey
val2020

执行结果:

租约


用于集群监控以及服务注册发现;

etcdctl lease grant <ttl> [flags]                                 创建一个租约
etcdctl lease keep-alive [options] <leaseID> [flags]              续约
etcdctl lease list [flags]                                        枚举所有的租约
etcdctl lease revoke <leaseID> [flags]                            销毁租约
etcdctl lease timetolive <leaseID> [options] [flags]              获取租约信息OPTIONS:--keys[=false]         Get keys attached to this lease

语法命令:

// 创建一个 100 秒的租约
lease grant 100// 如果租约创建成功会显示如下输出
lease 694d7b82c54a9309 granted with TTL(100s)// 将多个 key 绑定到租约
put key1 vla1 --lease=694d7b82c54a9309
put key2 vla2 --lease=694d7b82c54a9309
put key3 vla3 --lease=694d7b82c54a9309// 获取具有匹配前缀的 key(包括:绑定租约的 key 和未绑定租约的 key)
get key --prefix    // 输出结果
key1
vla1 
key2 
vla2 
key3 
vla3 // 销毁租约
lease revoke 694d7b82c54a9309// 获取具有匹配前缀的 key(因为租约已被销毁,所以此时返回的只有未绑定租约的 key)
get key --prefix // 获取租约信息(如果租约未过期,则输出结果会显示租约的剩余日期;如果租约已过期,则显示已过期)
lease timetolive 694d7b82c54a9309// 输出结果(租约已过期)
lease 694d7b82c54a9309 already expired// 续约(可以让租约剩余日期一直保持在设定时间;续约前提是当前租约未过期)
lease keep-alive 694d7b82c54a9309


USAGE:etcdctl lock <lockname> [exec-command arg1 arg2 ...] [flags]OPTIONS:-h, --help[=false]             help for lock--ttl=10                   timeout for session

Go 操作 etcd


驱动包安装


不能直接 go get go.etcd.io/etcd/clientv3(官方提供驱动包)不然会报错的;因为 gRPC 版本过新的缘故;

这里我们需要指定 gRPC 的版本信息;

# 指定 gRPC 版本为 v1.26.0
go mod edit --require=google.golang.org/grpc@v1.26.0# 下载安装 gRPC 驱动包
go get -u -x google.golang.org/grpc@v1.26.0# 下载安装 etcd 驱动包
go get go.etcd.io/etcd/clientv3

Go 操作 etcd 实例


启动 etcd

1)方式一

nohup ./etcd > ./start.log 2>&1 &// 查看端口对外开放情况(etcd 默认端口为 2379)
lsof -i:2379

执行结果:

从上述执行结果可知,使用方式一启动时,etcd 的端口号只能在本地连接。

2)方式二

nohup ./etcd --listen-client-urls 'http://0.0.0.0:2379' --advertise-client-urls 'http://0.0.0.0:2379' > ./start.log 2>&1 &// 查看端口对外开放情况(etcd 默认端口为 2379)
lsof -i:2379

执行结果:

从上述执行结果可知,使用方式一启动时,etcd 的端口号可以被外部连接。

注:使用方式二启动 etcd!


注:如果 etcd 所在机器是公司内部机器,需要把安全组对应端口号放开,即需要放开 2379!


put、get 使用

package mainimport ("context""fmt""time""github.com/coreos/etcd/clientv3"
)func main() {// 创建连接cli, err := clientv3.New(clientv3.Config{// Endpoints 是一个切片,可同时连接多个服务器Endpoints:   []string{"120.92.144.250:2379"},DialTimeout: 5 * time.Second, // 连接超时时间})if err != nil {panic(err)}// 程序执行结束前释放连接资源defer cli.Close()// v3 通讯服务使用的是 gRPC,需设置超时控制(即如果 put 命令执行后,在超时时间内没有返回结果,则取消 put 命令的执行)ctx, cancel := context.WithTimeout(context.Background(), time.Second)_, err = cli.Put(ctx, "key", "mark")cancel()if err != nil {panic(err)}// 获取 keyctx, cancel = context.WithTimeout(context.Background(), time.Second)/*此处的 get 等同于在终端执行 ./etcdctl get key -w json输出结果:{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":17,"raft_term":7},"kvs":[{"key":"a2V5","create_revision":2,"mod_revision":15,"version":8,"value":"dmFsMjAyMw=="}],"count":1}*/resp, err := cli.Get(ctx, "key")cancel()if err != nil {panic(err)}for _, ev := range resp.Kvs {fmt.Printf("%s:%s\n", ev.Key, ev.Value)}
}

watch 使用

package mainimport ("context""fmt""github.com/coreos/etcd/clientv3"
)func main() {// 创建连接cli, err := clientv3.NewFromURL("120.92.144.250:2379")if err != nil {panic(err)}defer cli.Close()// watch key 的操作//watch := cli.Watch(context.Background(), "key")// watch 大于等于 key3 的操作,监听对象由第三个参数控制watch := cli.Watch(context.Background(), "key", clientv3.WithFromKey())for resp := range watch {for _, ev := range resp.Events {fmt.Printf("Type: %s Key: %s Value: %s\n", ev.Type, ev.Kv.Key, ev.Kv.Value)}}
}

执行上述代码后会阻塞等待其它用户操作 etcd,如下所示:

1)在终端执行 etcd 操作

2)在 go 客户端查看监听情况

lease 使用

package mainimport ("context""fmt""github.com/coreos/etcd/clientv3"
)func main() {// 创建连接cli, err := clientv3.NewFromURL("120.92.144.250:2379")if err != nil {panic(err)}defer cli.Close()// 创建租约lease, err := cli.Grant(context.Background(), 5)if err != nil {panic(err)}fmt.Println("lease id", lease.ID)// 把 key-val 绑定到租约_, err = cli.Put(context.Background(), "key", "mark", clientv3.WithLease(lease.ID))if err != nil {panic(err)}// 续租:长期续租、短期续租// 长期续租:不停的续租if false {ch, err := cli.KeepAlive(context.Background(), lease.ID)if err != nil {panic(err)}for {recv := <-chfmt.Println("time to live", recv.TTL)}}// 短期续租:只续租一次if true {res, err := cli.KeepAliveOnce(context.Background(), lease.ID)if err != nil {panic(err)}fmt.Println("time to live", res.TTL)}
}

lock 使用

package mainimport ("context""fmt""github.com/coreos/etcd/clientv3""github.com/coreos/etcd/clientv3/concurrency"
)func main() {// 创建连接cli, err := clientv3.New(clientv3.Config{Endpoints: []string{"127.0.0.1:2379"},})if err != nil {panic(err)}defer cli.Close()// 创建 session1s1, err := concurrency.NewSession(cli, concurrency.WithContext(context.Background()), concurrency.WithTTL(10))if err != nil {panic(err)}defer s1.Close()// 为 session1 创建锁m1 := concurrency.NewMutex(s1, "lock")// 创建 session2s2, err := concurrency.NewSession(cli, concurrency.WithContext(context.Background()))if err != nil {panic(err)}defer s2.Close()// 为 session2 创建锁m2 := concurrency.NewMutex(s2, "lock")// 对 session1 加锁if err := m1.Lock(context.Background()); err != nil {panic(err)}fmt.Println("s1 acquired lock")// 创建管道m2ch := make(chan struct{})// 开启协程,对 session2 加锁,但由于已经被 session1 锁住,所以 session2 的加锁操作,阻塞等待go func() {defer close(m2ch)if err := m2.Lock(context.Background()); err != nil {panic(err)}}()// session1 释放锁if err := m1.Unlock(context.Background()); err != nil {panic(err)}fmt.Println("s1 released lock")// 通知 session2 session1 已经释放锁,此时 session2 可执行加锁操作<-m2chfmt.Println("s2 acquired lock")
}

注:Go 项目在创建好之后,需要在终端执行:go mod init 项目名称,生成 go.mod 文件。

etcd 存储原理及读写机制


存储原理


etcd 为每个 key 创建一个索引;一个索引对应着一个 B+ 树;B+ 树 key 为 revision,B+ 树节点存储的值为 value;B+ 树存储着 key 的版本信息从而实现了 etcd 的 mvcc;etcd 不会任由版本信息膨胀,通过定期的 compaction 来清理历史数据;

etcd 为了加速索引数据,在内存中维持着一个 B 树;B 树 key 为 key-val 中的 key,value 为该 key 的 revision;示意图如下:

etcd 不同命令执行流程:

  • etcd get 命令执行流程:etcd 在执行 get 获取数据时,先从内存中的 B 树中寻找,如果找不到,再从 B+ 树中寻找,从 B+ 树中找到数据后,将其缓存到 B 树并输出到客户端;
  • etcd put 命令执行流程:etcd 在执行 put 插入或修改数据时,先从内存中的 B 树中寻找,如果找到了,则对其进行修改并将其写入到 B+ 树;

问题:mysql 的 mvcc 是通过什么实现的?

答:undolog;

问题:mysql B+ 树存储什么内容?

答:具体分为聚簇索引和二级索引;

问题:mysql 为了加快索引数据,采用什么数据结构?

答:MySQL 采用自适应 hash 来加速索引;

扩展:B-树和 B+ 树区别?

  • B-树和 B+ 树都是多路平衡搜索树;采用中序遍历的方式会得到一个有序的结构;都是通过 key 的方式来维持树的有序性;
  • B-树一个节点中 n 个元素对应着 n+1 个指针;而 B+ 树一个节点中 n 个元素对应着 n 个指针;
  • B-树每个节点都存储节点信息,B+ 树只有叶子节点存储节点信息,非叶子节点只存储索引信息;
  • B+ 树叶子节点之间通过双向链表连接,对于范围查询速度更快,这样减少了磁盘 io;

读写机制


etcd 是串行写(避免不必要的加锁),并发读;

并发读写时(读写同时进行),读操作是通过 B+ 树 mmap 访问磁盘数据;写操作走日志复制流程;可以得知如果此时读操作走 B 树出现脏读幻读问题;通过 B+ 树访问磁盘数据其实访问的事务开始前的数据,由 mysql 可重复读隔离级别下 MVCC 读取规则可智能避免脏读和幻读问题;

并发读时,可走内存 B 树;

注:由于 etcd 写的时候是先写到内存中的 B 树,然后再写到磁盘上的 B+ 树,因此并发读写时需要读 B+ 树数据,否则容易出现脏读幻读问题;

相关文章:

Etcd 介绍与使用(入门篇)

etcd 介绍 etcd 简介 etc &#xff08;基于 Go 语言实现&#xff09;在 Linux 系统中是配置文件目录名&#xff1b;etcd 就是配置服务&#xff1b; etcd 诞生于 CoreOS 公司&#xff0c;最初用于解决集群管理系统中 os 升级时的分布式并发控制、配置文件的存储与分发等问题。基…...

Docker 安装 LogStash

关于LogStash Logstash&#xff0c;作为Elastic Stack家族中的核心成员之一&#xff0c;是一个功能强大的开源数据收集引擎。它专长于从各种来源动态地获取、解析、转换和丰富数据&#xff0c;并将这些结构化或非结构化的数据高效地传输到诸如Elasticsearch等存储系统中进行集…...

Selenium笔记

Selenium笔记 Selenium笔记 Selenium笔记element not interactable页面刷新 element not interactable "element not interactable"是Selenium在执行与网页元素交互操作&#xff08;如点击、输入等&#xff09;时抛出的一个常见错误。这个错误意味着虽然找到了对应的…...

ChatGPT :确定性AI源自于确定性数据

ChatGPT 幻觉 大模型实际应用落地过程中&#xff0c;会遇到幻觉&#xff08;Hallucination&#xff09;问题。对于语言模型而言&#xff0c;当生成的文本语法正确流畅&#xff0c;但不遵循原文&#xff08;Faithfulness&#xff09;&#xff0c;或不符合事实&#xff08;Factua…...

linux驱动开发面试题

1.linux中内核空间及用户空间的区别&#xff1f; 记住“22”&#xff0c;两级分段两级权限。 例如是32位的机器&#xff0c;从内存空间看&#xff1a;顶层1G是内核的&#xff0c;底3G是应用的&#xff1b;从权限看&#xff1a;内核是0级特权&#xff0c;应用是3级特权。 2.用…...

【AI】Ubuntu系统深度学习框架的神经网络图绘制

一、Graphviz 在Ubuntu上安装Graphviz&#xff0c;可以使用命令行工具apt进行安装。 安装Graphviz的步骤相对简单。打开终端&#xff0c;输入以下命令更新软件包列表&#xff1a;sudo apt update。之后&#xff0c;使用命令sudo apt install graphviz来安装Graphviz软件包。为…...

AI推介-大语言模型LLMs论文速览(arXiv方向):2024.03.05-2024.03.10—(2)

论文目录~ 1.Debiasing Large Visual Language Models2.Harnessing Multi-Role Capabilities of Large Language Models for Open-Domain Question Answering3.Towards a Psychology of Machines: Large Language Models Predict Human Memory4.Can we obtain significant succ…...

AI解答——DNS、DHCP、SNMP、TFTP、IKE、RIP协议

使用豆包帮助我解答计算机网络通讯问题—— 1、DHCP 服务器是什么&#xff1f; DHCP 服务器可是网络世界中的“慷慨房东”哦&#x1f923; 它的全称是 Dynamic Host Configuration Protocol&#xff08;动态主机配置协议&#xff09;服务器。 DHCP 服务器的主要任务是为网络中的…...

【TypeScript系列】声明合并

声明合并 介绍 TypeScript中有些独特的概念可以在类型层面上描述JavaScript对象的模型。 这其中尤其独特的一个例子是“声明合并”的概念。 理解了这个概念,将有助于操作现有的JavaScript代码。 同时,也会有助于理解更多高级抽象的概念。 对本文件来讲,“声明合并”是指编…...

zookeeper基础学习之六: zookeeper java客户端curator

简介 Curator是Netflix公司开源的一套zookeeper客户端框架&#xff0c;解决了很多Zookeeper客户端非常底层的细节开发工作&#xff0c;包括连接重连、反复注册Watcher和NodeExistsException异常等等。Patrixck Hunt&#xff08;Zookeeper&#xff09;以一句“Guava is to Java…...

MySQL数据库操作学习(2)表查询

文章目录 一、表查询1.表字段的操作①查看表结构②字段的增加③字段长度/数据类型的修改④字段名的修改⑤删除字符段⑥清空表数据⑦修改表名⑧删除表 2、表数据查询3、where 字段4、聚合函数 一、表查询 1.表字段的操作 ①查看表结构 desc 表名; # 查看表中的字段类型&#…...

Java学习

目录 treeSet StringBuilder treeSet TreeSet 是 Java 中实现了 Set 接口的一种集合类&#xff0c;它使用红黑树数据结构来存储元素&#xff0c;放到TreeSet集合中的元素: 无序不可重复&#xff0c;但是可以按照元素的大小顺序自动排序。 TreeSet一般会和Iterator迭代器一起使…...

C#八皇后算法:回溯法 vs 列优先法 vs 行优先法 vs 对角线优先法

目录 1.八皇后算法&#xff08;Eight Queens Puzzle&#xff09; 2.常见的八皇后算法解决方案 &#xff08;1&#xff09;列优先法&#xff08;Column-First Method&#xff09;&#xff1a; &#xff08;2&#xff09;行优先法&#xff08;Row-First Method&#xff09;&a…...

springboot整合swagger,postman,接口规范

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

029—pandas 遍历行非向量化修改数据

前言 在 pandas 中&#xff0c;向量化计算是指利用 pandas 对象的内置方法和函数&#xff0c;将操作应用到整个数据结构的每个元素&#xff0c;从而在单个操作中完成大量的计算。 但在一些需求中&#xff0c;我们无法使用向量化计算&#xff0c;就需要迭代操作&#xff0c;本例…...

相机安装位置固定后开始调试设备供电公司推荐使用方法

摄像头安装位置固定后开始调试 设备供电&#xff1a;无电源设备需要连接12V/2A电源并连接到摄像机的DC端口&#xff0c;而有电源的摄像机可以直接连接到220V电源。 连接设备&#xff1a;如果是有线连接&#xff0c;请使用网线将设备连接到电脑&#xff08;建议直接连接&#…...

AI视频批量混剪系统|罐头鱼AI视频矩阵获客

AI视频批量混剪系统助您轻松管理和编辑视频素材 如今&#xff0c;视频营销已成为企业推广的重要方式。为了满足用户对视频管理、发布和编辑的需求&#xff0c;《罐头鱼AI视频批量混剪系统》应运而生。这款智能化系统集成了多种功能&#xff0c;助您轻松管理和发布精彩视频内容…...

线程池学习-了解,自定义线程池

什么是线程池&#xff0c;这个池字是什么 线程池&#xff0c;主要利用池化思想&#xff0c;线程池&#xff0c;字符串常量池等 为什么要有一个线程池&#xff1f; 正常线程的创建&#xff1a;1&#xff0c;手动创建一个线程 2.给该线程分配任务&#xff0c;线程执行任务 3…...

CentOS7.9 安装SIPp3.6

epel里面的SIPp版本比较旧&#xff0c;先不要epel yum remove -y epel-release okay有很多CentOS软件&#xff0c;可以这样安装&#xff1a; 编辑 /etc/yum.repos.d/okay.repo&#xff0c;内容为&#xff1a; [okay] nameExtra OKay Packages for Enterprise Linux - $basearc…...

Java零基础入门-LinkedHashMap集合

一、本期教学目标 学习LinkedHashMap集合的概念及特点。学习LinkedHashMap存储结构。学习LinkedHashMap集合常用方法及示例代码演示。 二、正文 1、概述 我们学习了map接口之HashMap集合&#xff0c;今天我们要来学习map接口的另一个实现类-LinkedHashMap&#xff0c;不知道…...

LRC转SRT

最近看到一首很好的英文MTV原版&#xff0c;没又字幕&#xff0c;自己找字幕&#xff0c;只找到LRC&#xff0c;ffmpeg不支持LRC&#xff0c;网上在线转了SRT。 Subtitle Converter | Free tool | GoTranscript 然后用 ffmpeg 加字幕 ffmpeg -i LoveMeLikeYouDo.mp4 -vf sub…...

mybatis源码阅读系列(二)

前言 上一篇文章mybatis源码阅读系列&#xff08;一&#xff09;介绍了mybatis和原生jdbc的区别&#xff0c;并通过代码展示了两者的运行过程和结果&#xff0c;下面让我们继续详细了解下mybatis的执行过程&#xff1b; package com.wyl.mybatis.service;import com.wyl.mybat…...

【Web开发】CSS教学(超详细,满满的干货)

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Web开发】CSS教学(超详细,满满的干货) &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 CSS一. 什么是CSS?1.1 基本语法规范1.2 引入方式1.3 规范 二. CSS选…...

系列学习前端之第 5 章:学习 ES6 ~ ES11

1、什么是 ECMAScript ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。 从第 6 版开始&#xff0c;发生了里程碑的改动&#xff0c;并保持着每年迭代一个版本的习惯。 ES62015年&#xff0c;ES72016年&#xff0c;ES82017年&#xff0c;ES92018年&#…...

Linux学习(4)——使用编辑器

1.gedit编辑器 简单易懂&#xff0c;依赖图形界面。可以使用ctrlc ctrlv等快捷键&#xff0c;ctrls进行保存&#xff0c;与windows系统中相类似。 2.vi/vim编辑器 vi/vim可以直接通过控制台的终端完成文本的编辑&#xff0c;不依赖图形界面&#xff0c;使用范围更广。它的编辑…...

简单函数_短信计费

任务描述 用手机发短信&#xff0c;一条短信资费为0.1元&#xff0c;但限定一条短信的内容在70个字以内&#xff08;包括70个字&#xff09;。如果你一次所发送的短信超过了70个字&#xff0c;则会按照每70个字一条短信的限制把它分割成多条短信发送。假设已经知道你当月所发送…...

centos命令history设置记录10000行

今天在操作服务器的时候&#xff0c;用history查看操作记录的时候&#xff0c;发现只能查看10条&#xff0c;这样不行啊&#xff0c;我想查看所有人对服务器操作的命令。 [rootbogon ~]# history解决办法&#xff1a; #1、找到/etc/profile文件中的histsize 把10改成10000 […...

SpringBoot打造企业级进销存储系统 第七讲

Transientprivate String roles; // 所拥有的角色package com.java1234.entity;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.p…...

1.实用Qt:解决绘制圆角边框时,圆角锯齿问题

目录 问题描述 解决方案 方案1&#xff1a; 方案2&#xff1a; 结果示意图 问题描述 做UI的时候&#xff0c;我们很多时候需要给绘制一个圆角边框&#xff0c;初识Qt绘制的童鞋&#xff0c;可能绘制出来的圆角边框很是锯齿&#xff0c;而且粗细不均匀&#xff0c;如下图&…...

JavaWeb08-Filter和Listener

目录 一、Filter 1.概述 2.作用 3.快速入门 4.执行流程 5.拦截路径配置 6.拦截器链&#xff08;多个过滤器&#xff09; 7.登录验证 二、Listener&#xff08;了解即可&#xff09; 1.概述 2.主要作用 3.分类 4.快速入门 一、Filter 1.概述 Filter 表示过滤器&am…...