go语言基础-gozero

2023-05-16

go基础

go 文档
在这里插入图片描述
Go语言的并发是基于 goroutine 的,goroutine 类似于线程,但并非线程。可以将 goroutine 理解为一种虚拟线程。Go 语言运行时会参与调度 goroutine,并将 goroutine 合理地分配到每个 CPU 中,最大限度地使用CPU性能。开启一个goroutine的消耗非常小(大约2KB的内存),你可以轻松创建数百万个goroutine。

封装、继承、多态

  • 继承 子类继承
  • 一、什么是多态

面向对象的三大特性:封装、继承、多态
多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
多态的作用:消除类型之间的耦合关系。
现实中,关于多态的例子不胜枚举。比方说按下 F1键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
下面是多态存在的三个必要条件,要求大家做梦时都能背出来!

多态存在的三个必要条件
一、要有继承;
二、要有重写;
三、父类引用指向子类对象。

go语言特性

高效的性能
简洁的语法
广泛验证的工程效率
极致的部署体验
极低的服务端资源成本

go常用命令

go env 
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GO111MODULE=on
再没有 GO111MODULE时, go编译程序的查找依赖的顺序 go path > goroot , 有了GO111MODULE后,会读取当前项目的go.mod.文件, 在go.mod文件中会记录有哪些依赖

goroutine 协程的特点:
1.goroutine具有可增长的分段堆栈。这意味着它们只在需要时才会使用更多内存。
2.goroutine的启动时间比线程快。
3.goroutine原生支持利用channel安全地进行通信。
4.goroutine共享数据结构时无需使用互斥锁。
代码风格统一 一套格式化工具——go fmt
天生支持并发,完美契合当下高并发的互联网生态

go下载地址

官网地址:https://golang.google.cn/dl/
中文地址:https://studygolang.com/dl
1.18

goland 下载地址

https://www.jetbrains.com/go/download/#section=mac
帮助文档
https://www.jetbrains.com/help/go/2022.2/getting-started.html

go 升级参考文章

1.20
将旧版本备份
cd /usr/local
mv go go1.18.4

配置goproxy

设置

go env -w GOPROXY=https://goproxy.cn,direct
com + , -> go ->go Modules ->environment:
GOPROXY=https://goproxy.cn,direct

在这里插入图片描述

go教程

https://golang.google.cn/doc/
https://topgoer.com/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/%E7%AC%AC%E4%B8%80%E4%B8%AAgo%E7%A8%8B%E5%BA%8F.html

go 安装

window安装配置参考
建立Go的工作空间(workspace,也就是GOPATH环境变量指向的目录)
GO代码必须在工作空间内。工作空间是一个目录,其中包含三个子目录:
src ---- 里面每一个子目录,就是一个包。包内是Go的源码文件
pkg ---- 编译后生成的,包的目标文件
bin ---- 生成的可执行文件
添加PATH环境变量and设置GOPATH环境变量

vi /etc/profile
export GOROOT=/usr/local/go        ##Golang安装目录
export PATH=$GOROOT/bin:$PATH
export GOPATH=/home/go  ##Golang项目目录
go
go env

gopath :GOPATH是一个环境变量,用来表明你写的go项目的存放路径

GOPATH路径最好只设置一个,所有的项目代码都放到GOPATH的src目录下
https://topgoer.com/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/%E9%85%8D%E7%BD%AEgopath.html

在进行Go语言开发的时候,我们的代码总是会保存在GOPATH/src目录下。在工程经过go build、go install或go get等指令后,会将下载的第三方包源代码文件放在$GOPATH/src目录下, 产生的二进制可执行文件放在 $GOPATH/bin目录下,生成的中间缓存文件会被保存在 $GOPATH/pkg 下

  • go env
  • go env -w GOPROXY=https://goproxy.cn 修改配置源
安装
go get gocv.io/x/gocv

第一个go

package main  // 声明 main 包,表明当前是一个可执行程序

import "fmt"  // 导入内置 fmt 

func main(){  // main函数,是程序执行的入口
    fmt.Println("Hello World!")  // 在终端打印 Hello World!
}

go语法

声明
strName string
变量名   类型
函数
函数名大小写 表示包是否导出
函数多个形参 ... 三个点
func Test(a ...interface{}) (n int, err error)
任意类型 ...interface{}

构造函数 
func newFunc()	不需要被导出
func NewFunc()  需要被导出
映射
map[string]string
结构体

type hao struct {
	x,y float64
	z int
}
结构体定义方法
func (h hao) demo() float64 {
	return h.x+1.0
}

结构体初始化:
area := hao{1.0,2.0,5}

定义复合结构体: 可以分割独立可复用的结构当中
type  hao struct {
	hao1 hao1
	hao2 hao2
	hao3    //自动转发,不指定变量名, 会自动生成同名字段
}
h1 := hao1{}
h2 := hao2{}
h = hao{hao1:h1,hao2:h2, hao3:hao3{}}
h.hao3.value3
h.value3  //是相同字段

接口
类型必须满足一组方法的声明
type hao interface {
	demo() string
}
type hao1 int
func (h1 hao1) demo() string{
	return  strings.Repeat("oyes",int(h1))
}
hao = hao1(3)
fmt.Println(hoa.talk())
指针

指针存储的内存地址
&调用传参内存地址 *解引用函数定义具体值
空指针解引用

hao := 666
fmt.Println(&hao) //变量的内存地址  0x1010c101
解引用
hao1 = &hao
// go语言不允许类似于c语言的hao1++这样的内存操作
fmt.Println(*hao1)  //解引用

hao1 = "oyes"
var hao2 *string 
hao2 := &hao1
fmt.Println(*hao2)
// *星号放在类型前面表示声明指针类型,*星号放在变量前面表示解引用该变量指向的值
解引用改变其值
*hao2 = "hao oyes"
hao3 := *hao2 //解引用,是拷贝的数据副本

// 内部指针:指向结构内部字段的指针  地址操作符&
type hao1 struct {
	hao2
}
&hao1.hao2
func haof(h *hao2) string {}

指针没有赋值默认 为nil

空指针处理
func hoaf(h *hao) {
	if h == nil {
		return
	}
	h.page++
}
异常
demo,err := hao()
// 异常不等于空,有报错
if err != nil {
	fmt.Println(err)
	os.Exit(1)
}
for _,str := range demo{
}

func hao() []string,error{
	return err
	defer f.Close() //函数返回前执行
}

优雅的错误处理
type safeWriter struct {
	w io.Writer
	err Error
}
func (sw *safeWriter) writeln(s string){
	if sw.err != nil {
		return
	}
	_,sw.err = fmt.Fprintln(sw.w,s)
}
类型断言

err := g()
if err != nil {
	if errs,ok :=err.(SudokuError); ok {
		//具体的逻辑
	}
	os.Exit(1)
}
Go语言的错误值机制促使开发者考虑错误,而不是处理异常默认将其忽略。而且不需要用到特殊关键字,简单而灵活

recover() 被延迟的方法使用

defer func(){
	if e:=recover(); e!=nil {
		fmt.Pringln(e)
	}
}()
panic("o no !!!")
并发

通过 goroutine并发执行,并通过channel实现多个goroutine之间的通信和协同

go hao() //goroutine
c := make(chan int)  //channel 管道
c <- 99
r := c

func main(){
	c := make(chan int)
	for i := 0; i < 5; i++{
		go sleepyGoher(i,c)
	}
	for i :=0; i<5; i++{
		goherID := <-c
		fmt.Pringln("goherId:",goherId)
	}
}

func sleepyGoher(id int, c chan in ){
	time.Sleep(3*time.Second)
	fmt.Println("...",id,"snore ...")
	c<-id
}
当 多通道,或等待超时时自动中断 time.After
timeout := time.After(2*time.Second)
for i:=0;i<5;i++{
	select {
	case gopherId:=<=c:
		fmt.Println(gopherId)
	case <-timeout:  //等待耗尽
		fmt.Println("time out")
		return
	}
}

阻塞和死锁

阻塞:goroutine在等待通道的发送或者接收,其被阻塞了
死锁: 一个或多个goroutine因某些永远不会发生的事情而被阻塞时,称这种情况为死锁, 死锁并不消耗资源

func main(){
	c := make(chan int)
	<- c
}

装配流水线
func source( down chan string){
	for _,v :=range []string{"a","b","c"}
	{
		down <-v
	}
	down <- ""
	close(donw) // 用close 代替空字符表示通道关闭
}

func filter(up,down chan string){
	for {
		item := <- up
		v,ok := <- up // 获得状态 ok表示通道是否被关闭
		if !ok {
			close(down)
			return 
		}
		if item == ""{
			down <- ""
			return
		}
		if !strings.Contains(item,"bad"){
			down <-item
		}
	}
}
优化后:
func filter(up,down chan string){
	for item:= range up {
		if !string.Contains(item,"bad"){
			down<-item
		}
	}
	close(down)
}

func printG(up chan string){
	for{
		v := up
		if v != ""{
			return 
		}
		fmt.Println(v)
	}
}

func main(){
	up := make(chan string)
	down := make(chan string)
	go source(up)
	go fileter(up,down)
	printGopher(down)
}
并发状态 互斥锁

使用共享值为 竞态条件
互斥锁,组织多个goroutine操作同一值
死锁 :拥有互斥锁的goroutine,所动同一互斥锁,就会发生死锁
为了保证互斥锁的安全:
1、尽可能简化互斥锁的保护代码
2、对一份共享状态只使用一个互斥锁

var mu sync.Mutex   //声明互斥锁
mu.Lock()  //上锁
mu.Unlock() //解锁
defer mu.Unlock()  //确保退出前一定解锁

死锁

go高级

并发

进程和线程

    A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。
    B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
    C.一个进程可以创建和撤销多个线程;同一个进程中的多个线程之间可以并发执行

并发和并行

    A. 多线程程序在一个核的cpu上运行,就是并发。
    B. 多线程程序在多个核的cpu上运行,就是并行。

协程和线程

协程:独立的栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级线程,这些用户级线程的调度也是自己实现的。
线程:一个线程上可以跑多个协程,协程是轻量级的线程。

goroutine 只是由官方实现的超级"线程池"
每个实例4~5KB的栈内存占用和由于实现机制而大幅减少的创建和销毁开销是go高并发的根本原因。
并发主要由切换时间片来实现"同时"运行,并行则是直接利用多核实现多线程的运行,go可以设置使用核数,以发挥多核计算机的能力。
goroutine 奉行通过通信来共享内存,而不是共享内存来通信。

goroutine

https://topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html

goroutine原理

要实现并发编程的时候,我们通常需要自己维护一个线程池,并且需要自己去包装一个又一个的任务,同时需要自己去调度线程执行任务并维护上下文切换,这一切通常会耗费程序员大量的心智。那么能不能有一种机制,程序员只需要定义很多个任务,让系统去帮助我们把这些任务分配到CPU上实现并发执行呢?

Go语言中的goroutine就是这样一种机制,goroutine的概念类似于线程,但 goroutine是由Go的运行时(runtime)调度和管理的。Go程序会智能地将 goroutine 中的任务合理地分配给每个CPU。Go语言之所以被称为现代化的编程语言,就是因为它在语言层面已经内置了调度和上下文切换的机制。

在Go语言编程中你不需要去自己写进程、线程、协程,你的技能包里只有一个技能–goroutine,当你需要让某个任务并发执行的时候,你只需要把这个任务包装成一个函数,开启一个goroutine去执行这个函数就可以了,就是这么简单粗暴。
GPM是Go语言运行时(runtime)层面的实现,是go语言自己实现的一套调度系统。区别于操作系统调度OS线程

1.G很好理解,就是个goroutine的,里面除了存放本goroutine信息外 还有与所在P的绑定等信息。
2.P管理着一组goroutine队列,P里面会存储当前goroutine运行的上下文环境(函数指针,堆栈地址及地址边界),P会对自己管理的goroutine队列做一些调度(比如把占用CPU时间较长的goroutine暂停、运行后续的goroutine等等)当自己的队列消费完了就去全局队列里取,如果全局队列里也消费完了会去其他P的队列里抢任务。
3.M(machine)是Go运行时(runtime)对操作系统内核线程的虚拟, M与内核线程一般是一一映射的关系, 一个groutine最终是要放到M上执行的;
P与M一般也是一一对应的。他们关系是: P管理着一组G挂载在M上运行。当一个G长久阻塞在一个M上时,runtime会新建一个M,阻塞G所在的P会把其他的G 挂载在新建的M上。当旧的G阻塞完成或者认为其已经死掉时 回收旧的M。

P的个数是通过runtime.GOMAXPROCS设定(最大256),Go1.5版本之后默认为物理线程数。 在并发量大的时候会增加一些P和M,但不会太多,切换太频繁的话得不偿失。

单从线程调度讲,Go语言相比起其他语言的优势在于OS线程是由OS内核来调度的,goroutine则是由Go运行时(runtime)自己的调度器调度的,这个调度器使用一个称为m:n调度的技术(复用/调度m个goroutine到n个OS线程)。 其一大特点是goroutine的调度是在用户态下完成的, 不涉及内核态与用户态之间的频繁切换,包括内存的分配与释放,都是在用户态维护着一块大的内存池, 不直接调用系统的malloc函数(除非内存池需要改变),成本比调度OS线程低很多。 另一方面充分利用了多核的硬件资源,近似的把若干goroutine均分在物理线程上, 再加上本身goroutine的超轻量,以上种种保证了go调度方面的性能。

goroutine竞争状态

https://blog.csdn.net/qq_27449067/article/details/103882823
goroutine在没有相互同步状态的情况下同时访问某个资源,并且同时对这个资源进行读写的时候,对于这个资源就处于相互竞争状态(race candition)

var number int
var wait sync.WaitGroup
func main()  {
    wait.Add(2)
    go updateNumber(20000)//加20000
    go updateNumber(30000)//加30000
    wait.Wait()
    fmt.Println(number)
}
func updateNumber(addNumber int)  {
    for i:=0;i<addNumber ;i    {
        number   
    }
    wait.Done()
}

原子函数 atomic能够以很底层的加锁机制来同步访问整型变量和指针,我们可以使用原子函数来处理竞争问题

var number int32
var wait sync.WaitGroup
func main()  {
    wait.Add(2)
    go updateNumber(20000)
    go updateNumber(30000)
    wait.Wait()
    fmt.Println(number)
}
func updateNumber(addNumber int)  {
    defer wait.Done()
    for i:=0;i<addNumber ;i    {
        atomic.AddInt32(&number,1)
    }

}

这个函数会同步整型值的加法,方法是强制同一时刻只能有一个goroutine 运行并完成这个加法操作

互斥锁 mutex另一种方式是创建一个互斥锁来锁住一个区域,来保证同一个资源不会被同时修改或者使用。保证当前只有一个goroutine在执行当前区域的代码。

var (
    number int32
    wait sync.WaitGroup
    mutex sync.Mutex
    )
func main()  {
    wait.Add(2)
    go updateNumber(20000)
    go updateNumber(30000)
    wait.Wait()
    fmt.Println(number)
}
func updateNumber(addNumber int)  {
    defer wait.Done()
    for i:=0;i<addNumber ;i    {
        mutex.Lock() // 加锁
        number  ;
        mutex.Unlock() //释放锁
    }
}

在Number改变的前后对当前区域加锁,最后也能得到我们的目的,但是这样的会话,每次在number变更的时候,都会创建锁与释放锁,会对性能产生很大的影响。其实我们可以在for循环区域来加锁
后面这种形式的效率明显是要比第一种高很多的。所以我们程序有使用互斥锁的话,需要考虑加锁的粒度问题
虽然上面上面两种方式也可以解决竞争问题,但是在go中有一种更好的方式来解决这个问题,那就是goroutine的好兄弟channel

go汇总

八股文

https://www.topgoer.cn/docs/gomianshiti/gomianshiti-1dd225t6esqld

go 爬虫

goquery
https://www.bbsmax.com/A/gVdngBm8zW/

爬虫小例子
https://topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/%E7%88%AC%E8%99%AB%E5%B0%8F%E6%A1%88%E4%BE%8B.html

goquery 百度热搜
https://zhuanlan.zhihu.com/p/264823205

package main

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"log"
	"net/http"
	"os"
)

func BaiduHotSearch() {
	res, err := http.Get("http://www.baidu.com")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
	}

	doc, err := goquery.NewDocumentFromReader(res.Body)
	if err != nil {
		log.Fatal(err)
	}

	doc.Find(".s-hotsearch-content .hotsearch-item").Each(func(i int, s *goquery.Selection) {
		content := s.Find(".title-content-title").Text()
		fmt.Printf("%d: %s\n", i, content)
	})
}

func brickowl() {
	var url string
	//url = "https://www.brickowl.com/catalog/lego-sets"
	url = "https://www.baidu.com/sugrec?prod=pc_his&from=pc_web&json=1&sid=36558_36625_36255_36822_36973_36413_36954_36166_36917_36919_36746_26350_36931&hisdata=%5B%7B%22time%22%3A1659258458%2C%22kw%22%3A%22rsync%20%E8%BF%9C%E7%A8%8B%E5%90%8C%E6%AD%A5%E5%88%B0%E6%9C%AC%E5%9C%B0%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22python%20logging%20%E5%A4%9A%E6%96%87%E4%BB%B6%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22python%20%E4%B8%89%E5%85%83%E8%A1%A8%E8%BE%BE%E5%BC%8F%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22%E5%A5%A5%E7%89%B9%E6%9B%BC%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22%E8%B6%85%E6%97%B6%E7%A9%BA%E5%A4%A7%E5%86%B3%E6%88%98%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22request%20%E8%8E%B7%E5%8F%96%20https%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22request%20%E8%8E%B7%E5%8F%96%20443%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22python3%20%E4%B8%8B%E8%BD%BDhttps%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22%E6%9C%AC%E5%9C%B0%E6%9C%8D%E5%8A%A1app%20%E7%9F%A5%E4%B9%8E%22%7D%2C%7B%22time%22%3A1659258458%2C%22kw%22%3A%22%E4%B8%93%E4%B8%9A%E9%A2%86%E5%9F%9F%E7%9F%A5%E8%AF%86%E5%9B%BE%E8%B0%B1%22%7D%5D&_t=1659258457505&req=2&bs=goland%20%E5%88%87%E6%8D%A2%E7%AA%97%E5%8F%A3%E5%BF%AB%E6%8D%B7%E9%94%AE&csor=0"
	request, err := http.NewRequest("GET", url, nil)
	fmt.Println(err)
	request.AddCookie(&http.Cookie{Name: "SSESS96636da61f62e4e8dc28f1bac0edf597", Value: "EDilyyzHY_b5PNhdazL_d_mGIaCzAYcmdRChrKwyd9c"})
	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(0)
	}
	defer response.Body.Close()
	doc, err := goquery.NewDocumentFromReader(response.Body)
	fmt.Println(doc.Text(), err)
}

func main() {
	BaiduHotSearch()
}

思考

怎么理解 工具大于约定和文档?

怎么理解 约束做一件事只有一种方式?

怎么理解 面向故障编程?

链路跟踪?

持续

go官方文档

go 学习文档

八股文

每日一库

为什么说做好微服务很难

gozero项目示例

gitee文档
官网文档快速开始

gozero商城

gozero

教程视频

安装

go-zero
goctl 命令行工具
protoc protobuf 编辑器
安装文档参考
https://github.com/Mikaelemmmm/go-zero-looklook/blob/main/deploy/script/gencode/gen.sh

go install github.com/zeromicro/go-zero/tools/goctl@latest
查看gopath下
/Users/chenhaohao/go/bin/goctl

加入环境变量
vi ~/.bash_profile  # mac还需配置 vi ~/.zshrc 添加 source ~/.bash_profile 才会生效
export PATH=$PATH:/Users/chenhaohao/go/bin
source ~/.bash_profile

protoc
https://github.com/protocolbuffers/protobuf/releases
https://github.com/protocolbuffers/protobuf/releases/tag/v21.4
mac
protoc-21.4-osx-x86_64.zip

wget https://github.com/protocolbuffers/protobuf/releases/download/v21.4/protoc-21.4-osx-x86_64.zip
cd 
mv protoc  ~/go/bin/s
chmod 777 protoc 
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

快速开始

$ mkdir go-zero-demo
$ cd go-zero-demo
$ go mod init go-zero-demo
$ goctl api new greet
$ go mod tidy
vim greet/internal/logic/greetlogic.go 

func (l *GreetLogic) Greet(req *types.Request) (*types.Response, error) {
    return &types.Response{
        Message: "Hello go-zero",
    }, nil
}

$ cd greet
$ go run greet.go -f etc/greet-api.yaml

http://localhost:8888/from/you
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go语言基础-gozero 的相关文章

  • C语言基础----流程控制

    流程控制是C语言中比较基础的 它分为三种状态 xff1a 1是顺序结构 2是选择结构 3是循环结构 我要说明后两种结构 xff0c 选择机构和循环结构 首先先说 xff1a 选择结构 选择结构是指 xff1a 当一个条件成立则执 xff08
  • go语言基础(二):切片

    切片的定义 切片的基本定义初始化如下 xff1a span class token comment 定义空切片 span a span class token operator 61 span span class token punctu
  • Rust 中的基本数据类型——Rust语言基础06

    文章目录 1 前言2 标量类型 xff08 Scalar xff09 2 1 整型 xff08 Integer xff09 2 2 Rust 的整数形式2 3 奇怪的问题 xff08 整数的溢出 xff09 2 4 浮点类型 xff08 F
  • c语言基础——一维数组的应用

    C语言基础 一维数组的应用 例如 在一个学校的班级中会有很多学生 此时就可以使用数组来保存这些学生的姓名 以便进行管理 eg xff1a 用数组保存学生姓名 本示例每一个元素都应该是可以保存字符串的类型 这里使用字符指针类型 span cl
  • python 语言基础 - 你不得不知道的字符串常用函数之isalpha

    前言 小伙伴们大家好 xff0c 每天一个小知识 xff0c 一起学python每天进步一点点 不知道小伙伴们在开发的时候有没有遇到这样一种场景 xff0c 有时候一些业务需要 xff0c 想要判断一个字符串是不是由纯字符组成 xff0c
  • python 语言基础 - 你不得不知道的字符串常用函数之isdigit

    前言 小伙伴们大家好 xff0c 每天一个小知识 xff0c 一起学python每天进步一点点 上一篇文章中为大家分享了关于判断字符串是否全都是由字符组成的函数isalpha xff0c 今天要给大家分享的依然是判断字符串组成的函数isdi
  • C语言基础----流程控制

    流程控制是C语言中比较基础的 它分为三种状态 xff1a 1是顺序结构 2是选择结构 3是循环结构 我要说明后两种结构 xff0c 选择机构和循环结构 首先先说 xff1a 选择结构 选择结构是指 xff1a 当一个条件成立则执 xff08
  • 献给面试学生 关键字const是什么意思 ESP(译者:Embedded Systems Programming) --Dan Saks概括了const的所有用法

    关键字const是什么含意 答 我只要一听到被面试者说 const意味着常数 我就知道我正在和一个业余者打交道 去年Dan Saks已经在他的文章里完全概括了const的所有用法 因此ESP 译者 Embedded Systems Prog
  • go-zero&go web集成redis实战

    前言 上一篇 go zero go web集成JWT和cobra命令行工具实战 从零开始基于go zero搭建go web项目实战 03集成redis实战 源码仓库地址 源码 https gitee com li zheng treasur
  • Chapter Two : Python 语言基础、运算符与表达式、程序的控制结构合集

    目录 一 Python 语言基础 1 Python 语法规则 2 关键字与标识符 3 变量 4 基本数据类型 5 输入与输出 二 运算符与表达式 1 算术运算符 2 赋值运算符 3 比较 关系 运算符 4 逻辑运算符 5 位运算符 6 赋值
  • Go单体服务开发最佳实践

    单体最佳实践的由来 对于很多初创公司来说 业务的早期我们更应该关注于业务价值的交付 并且此时用户体量也很小 QPS 也非常低 我们应该使用更简单的技术架构来加速业务价值的交付 此时单体的优势就体现出来了 正如我直播分享时经常提到 我们在使用
  • IDEA-常用配置

    一 Appearance Behavior 1 1 设置主题 1 2 设置窗体及菜单的字体及大小 二 Editor General 2 1 设置自动导包的功能 Add unambiguous imports on the fly 自动导入不
  • Go 服务自动收集线上问题现场

    前言 对于 pprof 相信熟悉 Go 语言的程序员基本都不陌生 一般线上的问题都是靠它可以快速定位 但是实际项目中 很多时候我们为了性能都不会开启它 但是出了问题又要靠它来分析 好在 go zero 已经帮我们很好的集成进来了 我们只需要
  • shell 脚本命令太长,如何换行?

    再加ENTER
  • go-zero使用Etcd进行服务注册代码分析

    代码分析 github com tal tech go zero v1 2 3 core discov publisher go package discov import github com tal tech go zero core
  • go-zero 开发入门-加法客服端示例

    定义 RPC 接口文件 接口文件 add proto 的内容如下 syntax proto3 package add 当 protoc gen go 版本大于 1 4 0 时需加上 go package 否则编译报错 unable to d
  • go-zero 开发之安装 etcd

    本文只涉及 Linux 上的安装 二进制安装 下载二进制安装包 ETCD VER v3 4 28 ETCD VER v3 5 10 DOWNLOAD URL https github com etcd io etcd releases do
  • go-zero开发入门之网关往rpc服务传递数据1

    go zero 的网关往 rpc 服务传递数据时 可以使用 headers 但需要注意前缀规则 否则会发现数据传递不过去 或者对方取不到数据 go zero 的网关对服务的调用使用了第三方库 grpcurl 入口函数为 InvokeRPC
  • go-zero 的 etcd 配置

    实现代码在 core discov config go 文件中 type EtcdConf struct Hosts string Key string ID int64 json optional User string json opt
  • go-zero开发入门-API网关鉴权开发示例

    本文是 go zero开发入门 API网关开发示例 一文的延伸 继续之前请先阅读此文 在项目根目录下创建子目录 middleware 在此目录下创建文件 auth go 内容如下 鉴权中间件 package middleware impor

随机推荐

  • 到底什么是数据架构,如何管理,谁来负责?

    理解概念是理解数据管理的第一步 xff0c 很多概念我们知道 xff0c 但内涵却不清楚 xff0c 或者你以为清楚 xff0c 这类澄清概念的文章可以很好的帮到你 xff01 源于数据治理周周谈 xff0c 作者徐康 随着数据治理工作的深
  • linux下安装yum步骤

    一 安装yum前下介绍以下知识 1 yum介绍 Yum xff08 全称为 Yellow dog Updater Modified xff09 是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器 基于RPM包管
  • C++工程的CMakeLists.txt文件编写

    最简单的demo工程如下 xff1a include lt iostream gt include lt string gt int main int argc char argv std cout lt lt 34 hello world
  • windows/linux下Qt可执行程序打包,linux桌面双击运行程序sh脚本

    1 windows下Qt打包 windows下Qt的可执行文件打包简单的来说就是利用Qt自带依赖的打包工具windeployqt进行打包 xff0c 该工具存在Qt安装目录下 xff0c 执行命令为 xff1a windeployqt na
  • opengl、opengl es、webgl介绍与opengl开发入门

    1 OpenGL OpenGL xff08 英语 xff1a Open Graphics Library xff0c 译名 xff1a 开放图形库或者 开放式图形库 xff09 常用于CAD 虚拟现实 科学可视化程序和电子游戏开发 Open
  • linux代码检测工具valgrind之内存检测memcheck

    1 安装命令 xff1a sudo apt get install valgrind 安装成功如下 xff1a 检测版本命令 xff1a valgrind version 2 valgrind检测工具tool介绍 xff08 1 xff09
  • 摄影成像原理

    转载 xff1a https www sohu com a 191146657 690175 摄影成像原理 照相机是个什么样的仪器 xff1f 为什么可以把外界景物浓缩到一张小小的照片上 xff1f 观察手中的照相机 xff0c 就会感到这
  • cmake, make, CMakeLists.txt, Makefile简介

    文章目录 cmake make CMakeList txt Makefile之间的关系参考文章链接 xff1a 转自个人博客 在各种开源项目中 xff0c 经常会发现项目中除了代码源文件 xff0c 还包含了 CMakeList txt M
  • 相机畸变校正详解

    转 xff1a https blog csdn net humanking7 article details 45037239 1 摄像机成像原理简述 成像的过程实质上是几个坐标系的转换 首先空间中的一点由 世界坐标系 转换到 摄像机坐标系
  • java错误:需要《标识符》

    出现如下错误 xff1a 上面的第一 第二 xff0c 第三个错误的原因是 xff1a 没有加函数返回值类型void 最后一个原因是 xff1a 关键字static错误 总之 xff0c 出现标识符错误 xff0c 就是说程序里的不是缺少标
  • Java的throws Exception

    转 xff1a https www cnblogs com feichengwulai articles 3793261 html 1 终极解释 xff01 xff01 xff01 throws Exception放在方法后边 xff0c
  • TX2从入门到放弃学习笔记(1)-基础

    一 资源简介 TX2作为TX1的改进版 xff0c 资源配置相当强劲 1 模组配置 256 core NVIDIA Pascal GPU ARMv8 64 bit Multi Processor CPU Complex Advanced H
  • 弹窗问题 Android Detected problems with API compatibility visit g.co/dev/appcompat for more info dialog

    原因是Android P之后Google限制了开发者调用非公开的API方法 xff0c 例如使用反射去调用SDK内部的非公开方法 xff0c 这样启动app的时候就会弹窗提示 xff0c 不过我们还是可以通过反射把他干掉 手动狗头 解决方法
  • 进程创建和替换——fork和exec

    fork fork是UNIX系统中产生新进程的唯一办法 fork的作用是复制当前进程 xff0c 生成子进程 xff0c 子进程从fork的位置继续执行 fork函数的特点概括起来就是 调用一次 xff0c 返回两次 xff0c 在父进程中
  • ROS(2)工作空间与包

    2 创建工作空间与功能包 ros的工作空间是我们开发ros项目的一个工作目录 src 代码空间 xff0c 包含代码 lanuch文件 配置文件等等 xff0c 是源码所在的目录 xff1b build 编译空间 xff0c 包含编译过程中
  • Invalid bound statement (not found)错误的可能原因

    今天在执行sql的时候遇到这个问题 xff0c 按说非常简单 xff0c 但是出现问题的原因却不是唯一的 xff0c 所以总一下 xff1a 1 检查xml文件所在package名称是否和Mapper interface所在的包名 lt m
  • 组合导航+多传感器融合算法

    1 INS GPS的组合导航系统可以输出高频率的导航参数信息 xff08 位置 速度 姿态 xff09 xff0c 并且在长 短期的导航过程中均能具备较高精度 xff08 输出数据的意义什么 xff0c PDR是步长 43 航向 xff09
  • 记录一次阿里云服务器被入侵处理经过

    本人自己的阿里云服务器 xff0c 纯个人使用 xff0c 除了提供小爱音箱开关家中esp8266灯带使用 xff0c 没什么特别的重要服务 直到有一天 xff0c 小爱平台的哥们告诉我 xff0c 我的应用响应超时 xff0c 才开始关注
  • 使用阿里云搭建自用大数据集群(3台),含计费方式描述

    1 背景 自学大数据相关课程 xff0c 需要3台虚拟机 xff0c 之前是使用本地克隆虚拟机的方式 xff0c 但是现在用mac比较多 xff0c 而且需要上班 xff0c 无法一直坐在开着虚拟机的win前进行操作学习 xff0c 所以考
  • go语言基础-gozero

    go基础 go 文档 Go语言的并发是基于 goroutine 的 xff0c goroutine 类似于线程 xff0c 但并非线程 可以将 goroutine 理解为一种虚拟线程 Go 语言运行时会参与调度 goroutine xff0