头像

小肥龙

TJNU




离线:38分钟前


最近来访(20)
用户头像
Galaxyer
用户头像
Adamska
用户头像
CoderXx
用户头像
TheBlaze
用户头像
小飞龙
用户头像
zombotany
用户头像
甘棠
用户头像
rouse
用户头像
njh
用户头像
lukelmouse
用户头像
吊车尾92
用户头像
ㅤ_77
用户头像
吴子涵
用户头像
Syseg
用户头像
如果我是AC之王你会爱我吗
用户头像
star17
用户头像
山外小楼夜听雨
用户头像
wwww_wwww


1.简单模式-默认交换机

生产者和消费者都只需要建立连接conn和chanel连接队列就可以,不需要使用交换机
1.生产者绑定队列
2.消费者绑定队列

2.work模式

和简单模式差不多,只需要开两个一模一样的消费者就行。通过轮询的方式,每个消息只发给一个消费者
1.生产者连接队列
2.消费者1连接队列
3.消费者2连接队列

3.订阅模式-fanout

生产者连接交换机,由交换机根据不同的模式和匹配规则(这里的交换机类型选择为fanout,会将消息发送到所有绑定的队列中)将消息转发到不同的队列,不同的消费者绑定不同的队列。
1.生产者绑定交换机
2.交换机绑定队列1
3.交换机绑定队列2
4.消费者1绑定队列1
5.消费者2绑定队列2

4.路由模式-routin

Routin路由模式要求队列绑定交换机的时候要指定routing key,消息会转发到符合routing key的队列。
1.生产者绑定交换机
2.队列1绑定交换机并指定routing key1
3.队列2绑定交换机并指定routing key1
4.队列2板顶交换机并指定routing key2
5.消费者1绑定队列1
6.消费者2绑定队列2
此时发送携带routing key1的消息给交换机,消费者1、2都可以收到消息,发送携带routing key2的消息,只有消费者2会收到消息。

5.通配符模式-topic

通配符模式,每个队列绑定路由的使用声明一个通配符,*代表一个单词,#代表0个或多个单词,交换机接收到消息后会将消息转发到匹配的队列。
#.aaa.bbb可以匹配:aaa.bbb、qwe.aaa.bbb、qwe.asd.aaa.bbb
*.aaa.bbb可以匹配:qwe.aaa.bbb、asd.aaa.bbb
和上面4.路由模式步骤一样,将routing key换位通配符。

6.RPC

不算是一种模式,也基本不用,不做介绍



因为高并发编程是多个协程共同访问同一块内存,所以要传引用才可以让多个协程的锁对象一致

Mutex

mutex := &sync.Mutex{}

mutex.Lock()
mutex.Unlock()

RWMutex

// 效率: RWMutex.RLock() > Mutex.Lock() > RWMutex.Lock
// 所以一般只有在读多写少的情况下才会使用RWMutex
mutex := &sync.RWMutex{}

mutex.Lock()
mutex.Unlock()

mutex.RLock()
mutex.RUnlock()

WaitGroup

wg := &sync.WaitGroup{}

wg.Add(1)
wg.Done()   //底层实现wg.Add(-1)
wg.Wait()

Map

m := &sync.Map{}

m.Store(key,val)
m.Load(key)
m.LoadOrStore(key,value)    //有就获取返回true,没有就存储返回FALSE
m.Delete(key)
m.LoadAndDelete(key)

// 迭代所有元素
m.Range(func(key, value interface{}) bool {
  fmt.Printf("%d: %s\n", key.(int), value.(string))
  return true
})

Once

once := &sync.Once{}

once.Do(func)

Pool

// 并发池
pool := &sync.Pool{}

pool.Put(NewConnection(1))
pool.Get().(*Connection)

Cond

实现一对一,一对多的广播



镜像和容器就像是面向对象中的类和对象之间的关系

镜像

docker images   //查看镜像列表
docker pull     //拉取镜像到本地
docker push 注册用户名/镜像名   //推送镜像到远端仓库
docker save -o 导出的路径 镜像ID    //保存到本地镜像
docker load -i 镜像路径     //加载本地镜像
docker tag 镜像ID 新镜像名称:版本  //修改镜像名称
docker rmi  镜像名称或ID    //删除一个或多个镜像

容器

docker run 镜像ID -it 镜像ID /bin/bash  //运行一个交互式的镜像,并运行/bin/bash
docker run 镜像ID -id 镜像ID    //运行一个镜像,在后端运行
docker ps   //查看一正在运行的容器
docker ps -qal  //查看最近创建的所有容器
    -q  只显示容器ID
    -a显示所有容器
    -l李处最近创建的容器
docker logs -f ID   //查看容器日志
docker rm Name/ID
docker rm -f Name/ID    //强制删除容器
docker top Name/ID  //查看容器内运行的进程
docker attach Name/ID  //进入容器内部操作
docker exec Name/ID     //进入容器内部
docker cp f9e29e8455a5:/tmp/yum.log /root   //从容器里面拷贝文件/目录到本地一个路径
开启一个rabbitMQ
docker run -it --hostname my-rabbit --name rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.9-management

-i  以交互式模式运行容器
-t  为容器重新分配一个伪输入终端
-d  后台运行容器,并返回容器ID
--hostname  指定容器主机名称
--name  指定容器名称
-p  将mq的端口号映射到本地(本地:mq)
15672:控制台端口(配置后可访问http://127.0.0.1:15672/#/queues)
5672:应用访问端口(配置后可以访问应用进行消息的收发)
rabbitmq:3.9-management (REPOSITORY:TAG) 


分享 MySQL笔记

小肥龙
10天前

建表

create table user(
    `id` bigint unsigned not null auto_increment,
    `userid` bigint unsigned not null comment '用户id',
    `username` varchar(128) not null comment '用户名',
    `password` varchar(128) not null comment '密码',
    `wechatid` varchar(128) comment '微信号',
    `statu` tinyint not null comment '0普通用户 1超级管理员',
    `extra` longtext comment 'extra',
    primary key (`id`),
    unique key `unique_username` (`username`),
    unique key `unique_userid` (`userid`),
    key `key_statu` (`statu`)
)engine=innodb default charset=utf8 comment='用户表';
select @@global.tx_isolation;  //老版本查看事务隔离级别
select @@global.transaction_isolation;  //新版查看事务隔离级别
set global transaction isolation level read committed;  //设置全局事务隔离级别
set session transaction isolation level read committed;  //设置当前session事务隔离级别
use databese    //选择数据库
desc table      //查看标的结构
show tables     //查看当前数据库的所有表
drop table tablename    //删除表



分享 Redis笔记

小肥龙
10天前
redis-cli
redis-server

数据类型:
    0.通用
        del key
        flushall    //删除所有数据库的所有数据
        dump key    //序列化key,并返回序列化的结果
        exists key  //查看key是否存在
        expire key seconds  //设置key的过期时间(单位秒)
        pexpire key milliseconds    //设置过期时间(单位毫秒)
        expireat key timestamp      //设置过期时间时间戳
        pexpireat key milliseconds-timestamp    //设置毫秒时间戳
        keys pattern    //查看所有pattern类型
        keys *          //查看所有key
        move key db     //将key移到db数据库内
        persist key     //将key永久保存,移除过期时间
        ttl key         //以秒为单位返回过期时间
        pttl key        //以毫秒为单位返回过期时间
        randomkey       //从数据库随机返回一个key
        rename key newkey   //重命名
        renamenx key newkey //只有当新的名字不存在才重命名
        type key            //查看key的类型

    1.string
        set key val     //key和val可以加单双引号,也可以不加引号
        get key val
        setex key second value  //设置键名、过期时间、键值

    2.hash
        hset key field value
        hmset key field1 value1 field2 value2
        hget key field
        hgetall key
        hdel key field1 field2 ... //删除一个key下面的一个或者多个键
        hexists key fields      //判断hash下的字段是否存在

    3.list
        lpush key val1 val2 ...
        rpush key val1 val2 ...
        lrange key start stop

    4.set
        sadd key val1 val2...
        smembers key

    5.zset
        zadd key score1 val1 score2 val2 ...
        zRangeByScore key stScore edScore

飞书20210909-142615.png




小肥龙
13天前
0.快速输入输出
br=bufio.NewReader(os.Stdin)
bw=bufio.NewWriter(os.Stdout)
fmt.Fprintln(bw,x,y,z)
fmt.Fscan(br,&x,&y,&z)
1.变量
    var x int
    var x = 10
    x := 10

2.数组
    var a = [5]int{}
    var a [5]int = [5]int{}
    a := [...]int{1,2,3}
    a := [5]int{1:2,4:2}    //声明数组长度可以指定下标赋值
    f := [][]int{}
    append(f,a)     //往二维数组f中添加一维数组a
    f := [2][4]int{
        {1, 2, 3, 4},
        {5, 6, 7, 8},
    }

3.for
    for i:=0;i<n;i++ { }
    for true { }
    for { }

4.内置函数
    len()
    cap()
    unsafe.Sizeof()

5.指针
    var p *int
    var q [5]*int
    var r **int = &p    //指向指针的指针

6.结构体
    person := Person{
        age: 12,
        name: "tyl",
    }
    person := Person{12,"tyl"}
    person := new(Person)

7.切片(动态数组)
     var a []int = make([]int,len,cap)
     a = append(a,1)
     b := make([]int,len,cap)
     copy(b,a)  //把a拷贝到b中

8.range
    range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。

9.map
    var m map[int]string = make(map[int]string)    //必须要make才可以使用
    m[1] = "abc"
    v, ok := m[1]   //获取值,ok代表是否存在
    delete(m,k)     //删除元素

10.类型转换
    go:int(value)
    java:(int)value
    C++:上面两种都可以

11.channel
    ch := make(chan, int, len)
    v, ok := <-ch
    close(ch)
    有缓冲区先传值再取值
    无缓冲去先取值再传值
12.读入完整一行
    reader := bufio.NewReader(os.Stdin) // 从标准输入生成读对象
    text, _ := reader.ReadString('\n') // 读到换行
    text = strings.TrimSpace(text)
    fmt.Printf("%#v\n", text)
13.从字符串中读取数据
    Sscan()
    Sscanf()
    Sscanln()
14.time包
    now := time.Now()
    year := now.Year()     //年
    month := now.Month()   //月
    day := now.Day()       //日
    hour := now.Hour()     //小时
    minute := now.Minute() //分钟
    second := now.Second() //秒
    timestamp1 := now.Unix()     //时间戳
    timestamp2 := now.UnixNano() //纳秒时间戳
    timeObj := time.Unix(timestamp, 0) //将时间戳转为时间格式
    later := now.Add(time.Hour) // 当前时间加1小时后的时间
    Sub()       //减
    Equal()     //相等
    Before()    //是否在此时间之前
    After()     //是否在此时间之后 
15.log
    func init() {
        logFile, err := os.OpenFile("./xx.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
        if err != nil {
            fmt.Println("open log file failed, err:", err)
            return
        }
        log.SetOutput(logFile)
        log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
    }
    log.Println("这是一条很普通的日志。")
    v := "很普通的"
    log.Printf("这是一条%s日志。\n", v)
    log.Fatalln("这是一条会触发fatal的日志。")
    log.Panicln("这是一条会触发panic的日志。")
16.文件读取
    // 按照字节大小循环读取
    file, err := os.Open("./main.go")
    if err != nil {
        fmt.Println("open file failed!, err:", err)
        return
    }
    defer file.Close()
    // 循环读取文件
    var content []byte
    var tmp = make([]byte, 128)
    for {
        n, err := file.Read(tmp)
        if err == io.EOF {
            fmt.Println("文件读完了")
            break
        }
        if err != nil {
            fmt.Println("read file failed, err:", err)
            return
        }
        content = append(content, tmp[:n]...)
    }
    fmt.Println(string(content))

    // 按照一行一行的读取
    file, err := os.Open("./xx.txt")
    if err != nil {
        fmt.Println("open file failed, err:", err)
        return
    }
    defer file.Close()
    reader := bufio.NewReader(file)
    for {
        line, err := reader.ReadString('\n') //注意是字符
        if err == io.EOF {
            if len(line) != 0 {
                fmt.Println(line)
            }
            fmt.Println("文件读完了")
            break
        }
        if err != nil {
            fmt.Println("read file failed, err:", err)
            return
        }
        fmt.Print(line)
    }

    // 一次性读取整个文件
    content, err := ioutil.ReadFile("./main.go")
    if err != nil {
        fmt.Println("read file failed, err:", err)
        return
    }
    fmt.Println(string(content))

    os.O_WRONLY 只写
    os.O_CREATE 创建文件
    os.O_RDONLY 只读
    os.O_RDWR   读写
    os.O_TRUNC  清空
    os.O_APPEND 追加

    // Write和WriterString写入数据
    file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
    if err != nil {
        fmt.Println("open file failed, err:", err)
        return
    }
    defer file.Close()
    str := "hello 沙河"
    file.Write([]byte(str))       //写入字节切片数据
    file.WriteString("hello 小王子") //直接写入字符串数据

    // 输入到缓冲区再写入文件
    file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
    if err != nil {
        fmt.Println("open file failed, err:", err)
        return
    }
    defer file.Close()
    writer := bufio.NewWriter(file)
    for i := 0; i < 10; i++ {
        writer.WriteString("hello沙河\n") //将数据先写入缓存
    }
    writer.Flush() //将缓存中的内容写入文件

    // 一次性写入
    str := "hello 沙河"
    err := ioutil.WriteFile("./xx.txt", []byte(str), 0666)
    if err != nil {
        fmt.Println("write file failed, err:", err)
        return
    }
17.strconv
    strconv.Atoi()
    strvonv.Itoa()
    b, err := strconv.ParseBool("true")
    f, err := strconv.ParseFloat("3.1415", 64)
    i, err := strconv.ParseInt("-2", 10, 64)
    u, err := strconv.ParseUint("2", 10, 64)
    strconv.FormatInt(i, 10)    //int64转string
18.math
    Abs(-1)
    Max()
    Min()
19.sort
    必须实现三个函数才能排序
        Len()
        Swap()
        Less()  //比较函数
    sort.Sort(sort.IntSlice(a))
    sort.Ints(a []int)
    sort.Strings(s []string)
    sort.Reverse(sort.IntSlice(a))
    sort.Stable(sort.IntSlice(a))   //稳定排序
20.container/heap
    需要实现:
        sort.Interface
        Push()
        Pop()
    Init(h Interface)
    Push(h Interface, x interface{})
    Pop(h Interface, x interface{})
    Remove(h Interface, i int)
    Fix(h Interface, i int)
21.Strings
    Strings.Index(s string, sub string)
    Strings.Split(s, sep string)
    Strings.Join(a []string,sep strings)
    Strings.Contains(s, sub string)
22.container/list
    a := list.New()
    a.PushBack(x)
    l.Front().val
    l.Back().val
    l.len()
    l.PushFront(x)
    l.Remove(e *Element)
23.reflect
    reflect.ValueOf(interface{})    //获得接口的数值
    reflect.TypeOf(interface{})     //获得接口的类型
    reflect.DeepEqual(x, y) //slice不能直接比较,借助反射包进行比较
23.单元测试
    go test     测试所有test函数
    go test -v  测试所有test函数并显示详细信息
    go test -v -run="Func/testItem" //测试Func函数下的一个用例testItem
    go tets -cover //查看覆盖率
    go test -cover -coverprofile=c.out  //生成一个文件c.out,可通过网页查看该文件,看到哪些被覆盖
    go test -bench=Func -benchmem //显示执行次数,用时,内存消耗,申请内存次数

    func TestName(t *testing.T){...}    
    func  BenchmarkName(b *testing.B){...}    //性能测试
    func RunParallel(func(){})  //并行测试
24.生成随机数
    rand.Seed(time.Now().UnixNano())
    x := rand.Intn(10)  //生成0~9整数
25.断言
    token.Claims.(*MyClaims)    //判断token结构里里的Claims接口是不是*MyClaims结构体类型,是就返回该结构体
    x是结构体指针类型:
        x.(*y)      返回&{...}, true
        x.(y)       返回{0, "", nil}, false
    x是结构体类型:
        x.(*y)      返回{0, "", nil}, false
        x.(y)       返回{...}, true
26.get/post提取数据
    1.c.Request.FormValue           //获取post中的参数,获取布到再获取url中的
    2.c.Request.PostFormValue       //
    3.c.Query                       //get URL请求中的参数
    4.c.PostForm                    //post请求form表中的参数
    5.c.GetRawData()                //post请求body中的参数
    6.c.Param("name")               //url中的这种参数localhost:9090/user/tyl/password/123456

    参数类型        可以获取到该参数的方法
    Query Params    1  3
    form-data1      2  4  
    body json       5
27.select优先级写法:如果两个chanel同时可以执行,则先执行ch1再执行ch2
for {
    select {
    case <-stopCh:
        return
    case job1 := <-ch1:
        fmt.Println(job1)
    case job2 := <-ch2:
    priority:
        for {
            select {
            case job1 := <-ch1:
                fmt.Println(job1)
            default:
                break priority
            }
        }
        fmt.Println(job2)
    }
}



小肥龙
29天前

String

length()函数        长度
charAt()            随机访问
toCharArray()       返回字符数组
isEmpty()
replace('a','b')    将所有的字符a替换为b
split("")
substring(st,ed)
trim()              去掉空格
contains("")        是否包含某个字符串  
compareTo("") int   比较字符串是否相同
getBytes()          返回字节数组
toUpperCase()       全部替换为大写
toLowerCase()       全部替换为小写
indexOf(''/"")      从前往后看某个字符或者字符串第一次出现的下标,没有返回-1
lastIndexOf         返回下标

StringBuilder

length()函数
charAt()
setCharAt(i,x)
toString()
append()
delete(st,ed)
deleteCharAt()
replace(st,ed,str)  替换字符串
indexOf
insert(i,x)         在下标i插入x
reverse()
setLength()         截取前面一段
substring()

StringBuffer

同StringBuilder,只不过StringBuffer线程安全

char[]

length字段
clone()         深拷贝,不影响原数组
toString

Queue

底层实现类LinkedList、ArrayDeque、PriorityQueue

出错抛异常
add
remove
element

出错返回null或false
offer
poll
peek

size()
isEmpty
clear
contains

Deque

除了Queue含有的函数还有
addFirst
addLast
removeFirst
removeLast
getFirst
getLast
offerFirst
offerLast
pollFirst
pollLast
peekFirst
peekLast
pop
push

Stack

pop
peek
push
empty

List

add
get
clear
contains
size
isEmpty
remove
set
sort
subList

遍历:
List<Integer> list=new ArrayList<>()
for(int i=0;i<list.size();i++){     //LinkedList用这种方式,会每次从头遍历
    System.out.println(list.get(i));
}

for(Integer i:list){                //LinkedList用这种方式,会每次从头遍历
    System.out.println(list.get(i));
}

Iterator<Integer> i=list.iterator();
while(i.hasNext()){                 //LinkedList只能用这种方式遍历
    System.out.println(i.next());
}

list.forEach(System.out::println);//和下面的写法等价
list.forEach(i2 -> {
    System.out.println(i2);
});

set

一般用HashSet、TreeSet有序
add
size
contains
clear
remove
isEmpty

遍历:
Set<Integer> set=new HashSet<>();
Iterator<Integer> i = set.iterator();
while(i.hasNext()){
    System.out.println(i.next());
}

for(Integer i2:set){
    System.out.println(i2);
}

map

HashMap、HashTable、TreeMap、LinkedHashMap

put
isEmpty
containsKey
containsValue
get
getOrDefault(x,default)     获取如果不存在取默认值
putIfAbsent()               添加如果不存在
clear
size

遍历:
Map<Integer,Integer> map=new HashMap<>();
for(Map.Entry<Integer,Integer> entry:map.entrySet()){
    System.out.println(entry.getKey()+" "+entry.getValue());
}

for(Integer i:map.keySet()){
    System.out.println(i);
}

for(Integer i:map.values()){
    System.out.println(i);
}

Iterator<Map.Entry<Integer,Integer>> i=map.entrySet().iterator();
while(i.hasNext()){
    Map.Entry<Integer,Integer> entry=i.next();
    System.out.println(entry.getKey()+" "+entry.getValue());
}


活动打卡代码 Linux 1.0. homework_0

小肥龙
1个月前
1.ctrl c 取消命令,并且换行

2.ctrl u 清空当前行的命令

3.tab 补全当前行,如果没有补全,按两下显示提示信息

4.ls   -l long显示特别长的完整信息
       -h human显示友好的提示信息,人类能看的懂得
       -a 显示所有文件和文件夹,包括隐藏的
       -A 显示所有文件和文件夹,包括隐藏的,但不包括(. ..)
5.pwd 显示当前路径

6.cd xxx 进入某个目录
  cd ..  进入上一级目录
  以/开头的都是绝对路径,例如/home/acs/homework 第一个/为根目录
  不以/开头的都是相对路径

7.cp xxx yyy 将一个文件复制到另一个位置,可以是路径+文件,yyy如果是文件夹,自动加到该文件夹下

8.mkdir dir1 dir2 dir3 创建文件夹,可一次创建多个

9.rm xxx 删除文件
  rm yyy -r 删除文件夹,r是递归(recursion)删除

10.mv xxx yyy 将一个文件夹移动到另一个地方,xxx和yyy可以是路径,也可以用来改名

11.touch 创建一个文件

12.cat xxx 显示xxx文件的内容




小肥龙
2个月前

内推码:RXMWKBV

团队介绍:
产品研发,负责用户产品,如今日头条、抖音、西瓜视频等产品的研发维护,和各类新业务,如教育、轻颜、剪映等产品的研发工作。基础架构,支持字节跳动的基础设施构建,为字节跳动业务和中台体系提供存储、计算、研发效率体系支撑。安全与风控,负责字节跳动信息安全与业务风控的建设、规划和管理工作,努力打造一个让每位用户都能安全而自由交流的内容生态。

社招岗位
一、高级/资深测试开发工程师-业务中台-北京【社招】
二、高级/资深测试开发工程师-业务中台-深圳【社招】
三、测试开发工程师-业务中台-北京【社招】
社招同学可以直接将简历发我邮箱,会尽快为同学内推
tianyalong@bytedance.com

校招岗位
一、测试开发工程师-业务中台-北京【校招提前批】
https://jobs.bytedance.com/campus/position/6979144234423863583/detail?referral_code=RXMWKBV
二、测试开发工程师-业务中台-深圳【校招提前批】
https://jobs.bytedance.com/campus/position/6979043192935385381/detail?referral_code=RXMWKBV

校招岗位需要同学自行投递,在发送简历时可以填上内推码,增加面试机率

消息可能回复不及时,可加vx:tyl1318686278 进行咨询



活动打卡代码 AcWing 3697. 回文子序列

小肥龙
3个月前
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

const int N=5010;

int a[N];
unordered_map<int,int> cnt;

int main()
{
    int T;
    cin>>T;
    for(int i=0;i<T;i++)
    {
        int n;
        bool flag=false;
        scanf("%d",&n);
        cnt.clear();
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            cnt[a[i]]++;
            if(cnt[a[i]]>1&&a[i-1]!=a[i]||cnt[a[i]]>2)
            {
                flag=true;
            }
        }
        if(!flag)puts("NO");
        else puts("YES");
    }
    return 0;
}