头像

下次还填非常简单




离线:16分钟前


最近来访(17)
用户头像
PayAttention
用户头像
星之守护者
用户头像
浮生若梦_57
用户头像
StarLi9ht
用户头像
lzz_9
用户头像
世蒂
用户头像
huangbq
用户头像
每天亿遍展开式
用户头像
yxc的小迷妹
用户头像
HfjNUlYZ
用户头像
zst_2001
用户头像
MengLe
用户头像
AᴄWing
用户头像
kxzz
用户头像
胡歌-此生不换
用户头像
後藤独

分享 docker k8s

文章没有什么内容

k8s是对于容器的管理平台,docker 是k8s的组成部分

有什么用

运维技术

k8s官网

https://kubernetes.io/zh-cn/

参考链接

https://zhuanlan.zhihu.com/p/53260098 -> 漫画好懂,看几幅k8s结构图就好,大部分都是废话




wsl

  • Windows Subsystem for Linux

  • docker windows 版

官方文档

视频教学

https://www.bilibili.com/video/BV11L411g7U1

参考

https://blog.csdn.net/lb0737/article/details/80904242

wsl卸载命令

wsl –unregister Ubuntu-20.04

wsl查看命令

wsl -l -v




事务的性质

  • A:Atomicity
  • C: Consistency
  • I: Isolation
  • D: Durability
    即原子性、一致性、隔离性、持久性

脏读、不可重复读、幻读

  • 脏读:读到其他事务未提交的数据
  • 不可重复读:前后读取的记录内容不一致
  • 幻读:前后读取的记录数量不一致。

当数据库上有多个事务同时执行的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题,为了解决这些问题,就有了“隔离级别”的概念。在谈隔离级别之前,你首先要知道,你隔离得越严实,效率就会越低。因此很多时候,我们都要在二者之间寻找一个平衡点。

事务隔离级别

  • 读未提交(read uncommitted)
  • 读提交(read committed)
  • 可重复读(repeatable read)
  • 串行化(serializable )

  • 读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到
  • 读提交是指,一个事务提交之后,它做的变更才会被其他事务看到
  • 可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的
  • 串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。队列,先来后到

https://static001.geekbang.org/resource/image/7d/f8/7dea45932a6b722eb069d2264d0066f8.png?wh=1142*1420

在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。

常见数据库事务隔离级别

  • MySQL默认的隔离级别是repeatable read
  • Oracle 数据库是read committed

对于一些从 Oracle 迁移到 MySQL 的应用,为保证数据库隔离级别的一致,你一定要记得将 MySQL 的隔离级别设置为“读提交”

不使用长事务是因为长事务的存在会

  1. 占有锁资源,可能拖垮整个库
  2. 长事务可能导致暂时需要保存很多undo log,会占用内存空间。



redo log和binlog

  • redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  • redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。简单的说一个记载的是数据页修改,一个记得是sql语句。
  • redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

写数据要保证数据的一致性




mysql

不同的存储引擎共用一个 Server 层,所以跨引擎相关的功能都在server层实现

  • 存储引擎
    • InnoDB
    • MyISAM
    • Memory 等

mysql有多个存储引擎,常见的为InnoDB,默认也是

CREATE TABLE `hui_user` (
    xxx
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;

hh,没用过后面的参数,笑死

- 参数解释
    - ENGINE: 可走默认InnoDB
    - AUTO_INCREMENT:开始id
    - CHARSET: my.ini 设置过mysql语言编码,这里是设置表单编码 

可能不准,hh

mysql -h$ip -P$port -u$user -p

在后面接上密码可能导致密码泄露,头一次见,很有意思
因为Linux 中的history可以查看终端命令 -> 无语住了,就这???

“Access denied for user” 错误

MySQL不能确定是用户名不正确还是密码不正确。防破解

只有再新建的连接才会使用新的权限设置。


mysql 会在没有操作的情况下(8小时)断开连接,由参数 wait_timeout 控制,有没有人试试,头一次见,6

mysql> show variables like ‘wait_timeout’;


Lost connection to MySQL server during query

连接断开了,字面意思,一眼懂


长连接和短连接

// 短连接
连接 mysql 服务(TCP 三次握手)
执行sql
断开 mysql 服务(TCP 四次挥手)

// 长连接
连接 mysql 服务(TCP 三次握手)
执行sql
执行sql
执行sql

断开 mysql 服务(TCP 四次挥手)

数据库里面,长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个

一眼懂,hh

可以看到,使用长连接可以减少建立和断开连接的过程,所以一般是推荐使用长连接。
但是,使用长连接后可能会占用内存增多,因为 MySQL 在执行查询过程中临时使用内存管理连接对象,这些连接对象资源只有在连接断开时才会释放。如果长连接累计很多,将导致 MySQL 服务占用内存太大,有可能会被系统强制杀掉,这样会发生 MySQL 服务异常重启的现象。

解决长连接占用内存的问题?
可以使用定时超时断开,或通过重新初始化链接来清空

根据原理也猜到频繁使用用长连接,不然短连接

短连接可能要多个ip进行端口开放,因为不够用,监听多个ip地址
长连接可以减少创建连接开销,但是呢,它要维持,需要一定的花费

用户需要频繁访问数据库,那么可能会在流量增大的时候产生性能问题,此时长短连接都是无法解决问题的,所以应该进行合理的设计和优化来避免性能问题

连接池

数据库连接池是一些网络代理服务或应用服务器实现的特性,如J2EE服务器,它实现了一个持久连接的“池”,允许其他程序、客户端来连接,这个连接池将被所有连接的客户端共享使用,连接池可以加速连接,也可以减少数据库连接,降低数据库服务器的负载。


mysql5 sql语句查询后经过更新数据操作后缓存失效,mysql8都给它删除了都,没有缓存查询这步

你可以将参数 query_cache_type 设置成 DEMAND,这样对于默认的 SQL 语句都不使用查询缓存

sql语法分析

  1. 识别传进来的字符串
  2. 根据传进来的字符串用语法规则进行判断
  3. 如果有错误,将会收到You have an error in your SQL syntax的报错

优化器:索引和连接顺序优化


权限验证
1. 分析器进行的权限验证叫做 precheck
2. 执行器进行的权限验证叫做 权限验证,hh,不知道叫啥

权限验证不仅仅在执行器这部分会做,在分析器之后,也就是知道了该语句要“干什么”之后,也会先做一次权限验证。叫做precheck。而precheck是无法对运行时涉及到的表进行权限验证的,比如使用了触发器的情况。因此在执行器这里也要做一次执行时的权限验证。

  1. 连接器会鉴权用户是否具有连接 MySQL 实例的权限,包括用户的账号和密码是否正确,以及用户是否被授予连接权限。
  2. 分析器会鉴权用户是否具有对所请求的数据库和表的查询权限,包括是否具有查询、插入、更新、删除等操作的权限,以及是否具有访问某些列的权限。
  3. 执行器会鉴权用户是否具有执行所请求的操作的权限,包括对表的读、写等操作权限,以及是否具有执行存储过程和触发器的权限。

你会在数据库的慢查询日志中看到一个 rows_examined 的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。

引擎扫描行数跟 rows_examined 并不是完全相同的。



活动打卡代码 AcWing 1346. 回文平方

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

char get(int x){
    if (x <= 9) return x + '0';
    return x - 10 + 'A';
}

bool check(string s){
    for(int i = 0, j = s.size() - 1;i < j;i ++,j --){
        if(s[i] != s[j])
            return false;
    }
    return true;
}

string base(int a,int b){
    string num;
    while(a) num += get(a % b), a /= b;
    reverse(num.begin(), num.end());
    return num;
}


int main()
{
    int n;
    cin >> n;

    for(int i = 1; i <= 300; i ++){
        auto num = base(i * i, n);
        if(check(num))
            cout << base(i, n) << " " << num << endl;
    }
}


活动打卡代码 AcWing 1113. 红与黑

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

typedef pair<int, int> PII;
const int N = 25;

int n, m;
char g[N][N];


int bfs(int sx,int sy){

    queue<PII> q;
    q.push({sx, sy});
    g[sx][sy] = '#';


    int res = 0;

    int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};


    while(q.size()){
        auto t = q.front();
        q.pop();
        res ++;

        for(int i = 0 ; i < 4; i ++){
            int x = t.first + dx[i], y = t.second + dy[i];
            if(x < 0 || x >= n || y < 0 || y >= m || g[x][y] != '.')
                continue;
            g[x][y] = '#';
            q.push({x, y});
        }
    }
    return res;
}


int main()
{
    while (cin >> m >> n, n || m)
    {
        for (int i = 0; i < n; i ++ ) 
            cin >> g[i];

        int x, y;

        for (int i = 0; i < n; i ++ )
            for (int j = 0; j < m; j ++ )
                if (g[i][j] == '@')
                {
                    x = i;
                    y = j;
                }
        cout << bfs(x, y) << endl;
    }

    return 0;
}


活动打卡代码 AcWing 898. 数字三角形

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 510;
const int INF=0x3f3f3f3f;

int q[N][N];
int f[N][N];
int n;


int main(){

    cin >> n;

    for(int i = 1; i <= n; i ++)
        for(int j = 1 ; j <= i; j ++)
            cin >> q[i][j];


    memset(f, -INF, sizeof f);

    // f[0][0] 和 f[0][1] 是没有的,推导不出来
    f[1][1] = q[1][1];
    for(int i = 2 ; i <= n; i ++)
        for(int j = 1 ; j <= i; j ++)
            f[i][j] = max(f[i - 1][j - 1],f[i - 1][j]) + q[i][j];

    int res = -INF;

    for(int i = 1 ; i <= n; i ++){
        res = max(res,f[n][i]);
    }

    cout << res << endl;
    return 0;
}


新鲜事 原文

大佬,请问如何让自己坚持去学习呢?日复一日,好无聊,没有动力
图片 图片


活动打卡代码 AcWing 4956. 冶炼金属

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int main(){
    int n;
    cin >> n;

    int res1 = 1,res2 = 1e9;

    while (n -- ){
        int a,b;
        cin >> a >> b;

        res1 = max(res1, a / (b + 1) + 1);
        res2 = min(res2, a / b);
    }
    cout << res1 << " " << res2 << endl;
    return 0;
}