golang常用标准库

  • 输入与输出-fmt包
  • 时间与日期-time包
  • 命令行参数解析-flag包
  • 日志-log包
  • IO操作-os包
  • IO操作-bufio包与ioutil包
  • strconv包
  • 模板-template包
  • http包
  • context
  • json/xml
  • reflect反射
  • 官方标准库


输入与输出-fmt包

输入与输出

  • 常用输出函数

    Print、Printf、Println:直接输出内容

    Sprint、Sprintf、Sprintln:生成内容并返回字符串

    Fprint:将内容输出到一个io.Writer接口类型的变量,经常用于写入文件

    Errorf:根据format参数生成格式化字符串并返回一个包含该字符串的错误

```go
fmt.Println("打开文件出错,err:", err)//输出带换行
s2 := fmt.Sprintf("name:%s,age:%d", name, age)//带格式生成并返回
fmt.Fprintf(fileObj, "往文件中写如信息:%s", name)//带格式写入文件
err := fmt.Errorf("这是一个错误")
```
  • 常用占位符

    占位符说明
    %v值的默认格式表示
    %+v类似%v,但输出结构体时会添加字段名
    %#v值的golang语法表示
    %T打印值的类型
    %%百分号
    %d表示10进制数
    %b表示2进制数
    %f浮点数,有小数
    %9.2f宽度9,精度2
    %e科学计数法
    %s直接输出字符串或[]byte
    %q该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示
    %p指针,表示未16进制,并加上前缀0x
  • 常用输入函数

    Scan、Scanf、Scanln:可以在程序运行过程中从标准输入获取用户的输入。

    Scanln比较常用:在终端扫描标准输入,以空格分隔,直到换行结束扫描

```go
fmt.Scanln(&name, &age, &married)
fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
```bufio.NewReader:获取完整输入内容FScan、Fscanf、Fscanln:从文件中获取输入Sscan、Sscanf、Sscanln:从字符串获取输入

时间与日期-time包

  • 时间与日期转换

    func timeDemo() {now := time.Now() //获取当前时间fmt.Printf("current time:%v\n", now)year := now.Year()     //年month := now.Month()   //月day := now.Day()       //日hour := now.Hour()     //小时minute := now.Minute() //分钟second := now.Second() //秒fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)timestamp1 := now.Unix()     //时间戳timestamp2 := now.UnixNano() //纳秒时间戳fmt.Printf("current timestamp1:%v\n", timestamp1)fmt.Printf("current timestamp2:%v\n", timestamp2)   timeObj := time.Unix(timestamp1, 0)//时间戳转换成时间对象,再通过类似以上当前时间转换成时间格式}
    
  • 时间间隔(单位)

    time包中时间间隔的定义:

    const (Nanosecond  Duration = 1Microsecond          = 1000 * NanosecondMillisecond          = 1000 * MicrosecondSecond               = 1000 * MillisecondMinute               = 60 * SecondHour                 = 60 * Minute
    )
    
    var _time = 10 * time.Second //10秒
    

    例如:time.Duration表示1纳秒,time.Second表示1秒。

  • 时间格式化

    golang的常用时间格式化模板并不是常见的:Y-m-d H:i:s,而是2006-01-02 15:04 ,这是24小时制,2006-01-02 03:04 PM,则是12小时制

    fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
    // 12小时制
    fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
    fmt.Println(now.Format("2006/01/02 15:04"))
    fmt.Println(now.Format("15:04 2006/01/02"))
    fmt.Println(now.Format("2006/01/02"))
    

    golang大佬,何必呢,增加跨语言语法记忆难度,虽然只是一点点,但如果其他地方也这样有'意思',累计下难度就不小了。

  • 时间操作

    golang中的时间,并不是简单的数字加减,time包提供了实践操作的方法:

    • Add:时刻+时间段

      func main() {now := time.Now()later := now.Add(time.Hour) // 当前时间加1小时后的时间beforer := now.Add(-time.Hour) // 当前时间减1小时后的时间fmt.Println(later)
      }
      
    • Sub:时刻1 - 时刻2,求两个时间的差值,注意这里并不是(时刻-时间段)的实现,(时刻-时间段)仍然可以用Add(-时间段)来实现

    • Equal:判断时间是否相等,会考虑时区

    • Before:判断是否在某个时刻之前

    • After:判断是否在某个时刻之后

  • 定时器

    定时器,本质上是一个channel,golang中使用time.Ticker(duration)来设置定时器

    • 一次性定时器(延时)

      package mainimport ("fmt""time"
      )func main() {/*用sleep实现定时器*/fmt.Println(time.Now())time.Sleep(time.Second)fmt.Println(time.Now())/*用timer实现定时器*/timer := time.NewTimer(time.Second)fmt.Println(<-timer.C)/*用after实现定时器*/fmt.Println(<-time.After(time.Second))}
      
    • 周期性定时器

      func tickDemo() {ticker := time.Tick(time.Second) //定义一个1秒间隔的定时器//ticker := time.NewTicker(time.Second)for i := range ticker {fmt.Println(i)//每秒都会执行的任务}
      }
      

命令行参数解析-flag包

flag包是的golang开发命令行工具更为简单。

看一个完整示例,我们就更清楚flag的用途了:

执行命令时要求输入4个参数,并指定了参数的类型与默认值

func main() {//定义命令行参数方式1var name stringvar age intvar married boolvar delay time.Durationflag.StringVar(&name, "name", "张三", "姓名")flag.IntVar(&age, "age", 18, "年龄")flag.BoolVar(&married, "married", false, "婚否")flag.DurationVar(&delay, "d", 0, "延迟的时间间隔")//解析命令行参数flag.Parse()fmt.Println(name, age, married, delay)//返回命令行参数后的其他参数fmt.Println(flag.Args())//返回命令行参数后的其他参数个数fmt.Println(flag.NArg())//返回使用的命令行参数个数fmt.Println(flag.NFlag())
}

首先flag提供了命令行help功能,执行命令行会给出相应提示:

    $ ./flag_demo -helpUsage of ./flag_demo:-age int年龄 (default 18)-d duration时间间隔-married婚否-name string姓名 (default "张三")

其次flag提供命令行参数parse解析能力:

注意:Args()\NArg()\NFlag()的含义

$ ./flag_demo -name pprof --age 28 -married=false -d=1h30m
pprof 28 false 1h30m0s
[]
0
4

当然如果我们仅仅只是需要简单命令行输入的参数,我们也可以简单的考虑os.Args来获取命令行参数。

os.Args是一个存储命令行参数的字符串切片,它的第一个元素是执行文件的名称,这和大部分语言命令行模式是类似的(python、php等)

日志-log包

官方标准简单log包,功能有限,更多可以实现流水账的日志记录,如果我们需要更多比如不同级别的日志记录,可以选择第三方日志库:logrus、zap等

//使用标准日志log,设置日志输出到xx.log文件,设置flags支持文件名、行号、日志前缀、时间格式
func main() {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.SetPrefix("[JM]")log.Println("这里记录一条日志。")
}
[JM]2020/01/14 15:32:45.431506 .../log_demo/main.go:13: 这里记录一条日志。

IO操作-os包

os包提供了Create、NewFile、Open、OpenFile、Remove方法

返回的文件对象,提供了读写方法,比如Write、WriteAt、WriteString、Read、ReadAt方法

  • 文件打开与关闭

    package mainimport ("fmt""os"
    )func main() {// 只读方式打开当前目录下的main.go文件file, err := os.Open("./main.go")if err != nil {fmt.Println("open file failed!, err:", err)return}// 关闭文件file.Close()
    }
    

    golang可以考虑再简化下文件的打开及异常的处理和关闭,python的with open简化了try异常和close的处理,让代码更简洁,编写者不用去关心异常处理和文件关闭处理代码,这本不属于业务逻辑代码,趋势应该是让语言或机器自动实现了

  • 写文件
```go
file.WriteString("ab\n")
file.Write([]byte("cd\n"))
```我们会更新一篇关于byte与string区别的文章
  • 读文件

    golang文件读取可以用file.Read()和file.ReadAt(),读到文件末尾会返回io.EOF的错误,EOF这是大部分语言读取结尾的标识符了

    golang的os包的读写还需要偏上层封装,不要让开发者去了解这么多读写的原理,比如读取一行、整个文件,这些是开发者更乐意用到的,不用关心读写的原理,至于性能开发者会认为是语言要解决的问题,当然当我们有足够经验以后,就可以使用更底层些的方法来实现,提高性能。如果硬件的发展更快,我们更希望大家都可以不关心底层实现的去使用更上层的方法

    package mainimport ("fmt""io""os"
    )func main() {// 打开文件file, err := os.Open("./xxx.txt")if err != nil {fmt.Println("open file err :", err)return}defer file.Close()// 定义接收文件读取的字节数组var buf [128]bytevar content []bytefor {n, err := file.Read(buf[:])if err == io.EOF {// 读取结束break}if err != nil {fmt.Println("read file err ", err)return}content = append(content, buf[:n]...)}fmt.Println(string(content))
    }
    

IO操作-bufio包与ioutil包

bufio包实现了带缓冲区的读写,是对文件读写的封装

前面说到开发者更喜欢使用更上层的读写方法,golang的bufio包除了实现带缓冲区的读写提高效率和稳定性外,还提供按行读方法,ioutil包提供了读取整个文件、写文件方法

bufio、ioutil包更多文件、目录读写详见官方标准库

strconv包

  • Atoi

    string类型转换成int类型

  • Itoa

    int转换成string

  • ParaseType系列

    将string转换成指定Type类型

    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)
    
  • FormatType系列

    将给定类型数据格式化为string类型数据的功能

    s1 := strconv.FormatBool(true)
    s2 := strconv.FormatFloat(3.1415, 'E', -1, 64)
    s3 := strconv.FormatInt(-2, 16)
    s4 := strconv.FormatUint(2, 16)
    

strconv包中还有Append系列、Quote系列等函数。详细见官方标准库

模板-template包

html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出。

  • 模板语法

    {{.}}
    

    模板语法都包含在{{和}}中间,其中{{.}}中的点表示当前对象。

    当我们传入一个结构体对象时,我们可以根据.来访问结构体的对应字段。例如:

    type UserInfo struct {
    Name   string
    Gender string
    Age    int
    }func sayHello(w http.ResponseWriter, r *http.Request) {// 解析指定文件生成模板对象tmpl, err := template.ParseFiles("./hello.html")if err != nil {fmt.Println("create template failed, err:", err)return}user := UserInfo{Name:   "枯藤",Gender: "男",Age:    18,}// 利用给定数据渲染模板,并将结果写入wtmpl.Execute(w, user)
    }
    

    .表示当前对象/结构体user(w只是服务端的一个变量,也保存了user这个结构体而已)

    <body>
    <p>Hello {{.Name}}</p>
    <p>性别:{{.Gender}}</p>
    <p>年龄:{{.Name}}</p>
    </body>
    
  • 模板注释

    {{/* a comment */}}
    注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止。
    
  • 管道pipeline

    Go的模板语法中支持使用管道符号|链接多个命令,用法和unix下的管道类似:|前面的命令会将运算结果(或返回值)传递给后一个命令的最后一个位置。

  • Actions

    以下这些动作基本包含golang模板中常用的动作与含义说明

    {{/* a comment */}}
    注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止,就像这里表示的一样。
    {{pipeline}}pipeline的值的默认文本表示会被拷贝到输出里。
    {{if pipeline}} T1 {{end}}如果pipeline的值为empty,不产生输出,否则输出T1执行结果。不改变dot的值。Empty值包括false、0、任意nil指针或者nil接口,任意长度为0的数组、切片、字典。
    {{if pipeline}} T1 {{else}} T0 {{end}}如果pipeline的值为empty,输出T0执行结果,否则输出T1执行结果。不改变dot的值。
    {{if pipeline}} T1 {{else if pipeline}} T0 {{end}}用于简化if-else链条,else action可以直接包含另一个if;等价于:{{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}
    {{range pipeline}} T1 {{end}}pipeline的值必须是数组、切片、字典或者通道。如果pipeline的值其长度为0,不会有任何输出;否则dot依次设为数组、切片、字典或者通道的每一个成员元素并执行T1;如果pipeline的值为字典,且键可排序的基本类型,元素也会按键的顺序排序。
    {{range pipeline}} T1 {{else}} T0 {{end}}pipeline的值必须是数组、切片、字典或者通道。如果pipeline的值其长度为0,不改变dot的值并执行T0;否则会修改dot并执行T1。
    {{template "name"}}执行名为name的模板,提供给模板的参数为nil,如模板不存在输出为""
    {{template "name" pipeline}}执行名为name的模板,提供给模板的参数为pipeline的值。
    {{with pipeline}} T1 {{end}}如果pipeline为empty不产生输出,否则将dot设为pipeline的值并执行T1。不修改外面的dot。
    {{with pipeline}} T1 {{else}} T0 {{end}}如果pipeline为empty,不改变dot并执行T0,否则dot设为pipeline的值并执行T1。
    
  • 比较

    eq      如果arg1 == arg2则返回真
    ne      如果arg1 != arg2则返回真
    lt      如果arg1 < arg2则返回真
    le      如果arg1 <= arg2则返回真
    gt      如果arg1 > arg2则返回真
    ge      如果arg1 >= arg2则返回真
    
     {{eq arg1 arg2 arg3}}
    
  • 嵌套模板

    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>tmpl test</title>
    </head>
    <body><h1>测试嵌套template语法</h1><hr>{{template "ul.html"}}<hr>{{template "ol.html"}}
    </body>
    </html>{{ define "ol.html"}}
    <h1>这是ol.html</h1>
    <ol><li>AA</li><li>BB</li><li>CC</li>
    </ol>
    {{end}}
    

    ul.html模板 不在当前html文档内,需要通过服务端template.ParseFiles指定加载的模板页,才能使用(有点耦合,要是都由前端模板文件去include包含模板可能会更自然些)

    func tmplDemo(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles("./t.html", "./ul.html")
    if err != nil {fmt.Println("create template failed, err:", err)return
    }
    user := UserInfo{Name:   "枯藤",Gender: "男",Age:    18,
    }
    tmpl.Execute(w, user)
    

}
```

http包

Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现

  • 客户端

    resp, err := http.Get("http://www.baidu.com/")resp, err := http.Post("http://www.9ong.com/post", "image/jpeg", &buf)resp, err := http.PostForm("http://www.9ong.com/form",url.Values{"key": {"Value"}, "id": {"123"}})if err != nil {// handle error
    }
    //使用完response后必须关闭回复的主体
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    

    使用完response后必须关闭回复的主体,总是会有不完美的地方存在哈,还需要自己关闭Body,从编码的角度看。

  • 带参数的请求

    带参数get请求

    apiUrl := "http://127.0.0.1:9090/get"
    // URL param
    data := url.Values{}
    data.Set("name", "枯藤")
    data.Set("age", "18")
    u, err := url.ParseRequestURI(apiUrl)
    if err != nil {fmt.Printf("parse url requestUrl failed,err:%v\n", err)
    }
    u.RawQuery = data.Encode() // URL encode
    fmt.Println(u.String())
    resp, err := http.Get(u.String())
    if err != nil {fmt.Println("post failed, err:%v\n", err)return
    }
    

    带参数post请求

    // 表单数据
    //contentType := "application/x-www-form-urlencoded"
    //data := "name=jm&age=20"
    // json
    contentType := "application/json"
    data := `{"name":"jm","age":20}`
    resp, err := http.Post(url, contentType, strings.NewReader(data))
    

    看完以下的编写方式,我们觉得应该有更舒适第三方http库,只需要:

    http.Get(url,json对象参数|结构体参数)
    http.Post(url,options,data) //options负责设置http头等信息,data是参数json对象或结构体
    
  • 服务端

```go
// http serverfunc sayHello(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Hello world")
}func main() {http.HandleFunc("/", sayHello)err := http.ListenAndServe(":9527", nil)if err != nil {fmt.Printf("http server failed, err:%v\n", err)return}
}
```自定义server```go
s := &http.Server{Addr:           ":9527",Handler:        myHandler,ReadTimeout:    10 * time.Second,WriteTimeout:   10 * time.Second,MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())
```

context

在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理。请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库和RPC服务。用来处理一个请求的 goroutine 通常需要访问一些与请求特定的数据,比如终端用户的身份认证信息、验证相关的token、请求的截止时间。 当一个请求被取消或超时时,所有用来处理该请求的 goroutine 都应该迅速退出,然后系统才能释放这些 goroutine 占用的资源。

介绍goroutine时,我们看到范例并没有在main函数里使用context,goroutine也会自动退出。原因是只有一种情况正在运行的goroutine会因为其他goroutine的结束被终止,就是main函数的退出或程序停止执行.

sync.WaitGroup解决了协程协同同步完成问题,context主要为了解决协程协同取消问题

  • Context接口

    context.Context是一个接口,该接口定义了四个需要实现的方法

    type Context interface {Deadline() (deadline time.Time, ok bool) //返回当前Context被取消的时间,也就是完成工作的截止时间Done() <-chan struct{} //返回一个Channel,这个Channel会在当前工作完成或者上下文被取消之后关闭,多次调用Done方法会返回同一个ChannelErr() error //返回当前Context结束的原因Value(key interface{}) interface{} //从Context中返回键对应的值,对于同一个上下文来说,多次调用Value 并传入相同的Key会返回相同的结果,该方法仅用于传递跨API和进程间跟请求域的数据
    }
    

注意:以下介绍的都是函数,并不是创建后context上下问对像的方法,而是context包的函数

  • context.Background函数

  • context.TODO函数

    Go内置两个函数:Background()和TODO(),这两个函数分别返回一个实现了Context接口的background和todo。我们代码中最开始都是以这两个内置的上下文对象作为最顶层的partent context,衍生出更多的子上下文对象。

    Background()主要用于main函数、初始化以及测试代码中,作为Context这个树结构的最顶层的Context,也就是根Context。

    TODO(),它目前还不知道具体的使用场景,如果我们不知道该使用什么Context的时候,可以使用这个。

    background和todo本质上都是emptyCtx结构体类型,是一个不可取消,没有设置截止时间,没有携带任何值的Context。

  • context.withCancel函数

    WithCancel返回带有新Done通道的父节点的副本。当调用返回的cancel函数或当关闭父上下文的Done通道时,将关闭返回上下文的Done通道,无论先发生什么情况。

    func gen(ctx context.Context) <-chan int {dst := make(chan int)n := 1go func() {for {select {case <-ctx.Done():return // return结束该goroutine,防止泄露case dst <- n:n++}}}()return dst
    }
    func main() {ctx, cancel := context.WithCancel(context.Background())defer cancel() // 当我们取完需要的整数后调用cancelfor n := range gen(ctx) {fmt.Println(n)if n == 5 {break}}
    }
    
  • context.withDeadline函数

    返回父上下文的副本,并将deadline调整为不迟于d。如果父上下文的deadline已经早于d,则WithDeadline(parent, d)在语义上等同于父上下文。当截止日过期时,当调用返回的cancel函数时,或者当父上下文的Done通道关闭时,返回上下文的Done通道将被关闭,以最先发生的情况为准。

    func main() {d := time.Now().Add(50 * time.Millisecond)ctx, cancel := context.WithDeadline(context.Background(), d)// 尽管ctx会过期,但在任何情况下调用它的cancel函数都是很好的实践。// 如果不这样做,可能会使上下文及其父类存活的时间超过必要的时间。defer cancel()select {case <-time.After(1 * time.Second):fmt.Println("overslept")case <-ctx.Done():fmt.Println(ctx.Err())}
    }
    
  • context.WithTimeout函数

    func main() {// 设置一个50毫秒的超时ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)wg.Add(1)go worker(ctx)time.Sleep(time.Second * 5)cancel() // 通知子goroutine结束wg.Wait()fmt.Println("over")
    }
    
  • context.WithValue函数

    WithValue返回父节点的副本,其中与key关联的值为val。

    仅对API和进程间传递请求域的数据使用上下文值,而不是使用它来传递可选参数给函数。

    type TraceCode stringfunc worker(){...key := TraceCode("TRACE_CODE")traceCode, ok := ctx.Value(key).(string) // 在子goroutine中获取trace code        ...
    }
    func main(){...// 在系统的入口中设置trace code传递给后续启动的goroutine实现日志数据聚合ctx = context.WithValue(ctx, TraceCode("TRACE_CODE"), "2009")wg.Add(1)go worker(ctx)...
    }
    
  • 关于cancel()函数

    以上范例中的cancel函数,是通过context.With*系列函数返回得到的第二个值,用于通知同一个context下的所有goroutine结束/取消。

golang的context设计,让我们明白一个道理,能简单处理好一个问题,就是好的解决方案,没有高贵之分。

json/xml

  • json

    json可以和map、struct、interface相互转换

    // 将struct、map转换成json 字符串
    json.Marshal(struct|map)//将json字符串转换成Person结构体
    type Person struct{...
    }
    jsonStr := []byte(`{"age":"18","name":"5lmh.com","marry":false}`)
    var p Person
    json.Unmarshal(jsonStr,&p)
    

    弱类型的js、php可以随时动态自由的转换json字符串,这个确实舒服太多,怪不得php开发者总说数组强大。

  • xml

    与json包的方法是一样,只是数据源不一样

    xml.Marshal(struct|map)
    xml.Unmarshal(xmlStr,&p)
    
  • msgpack

MSGPack是二进制的json,性能更快,更省空间

需要安装第三方包:go get -u github.com/vmihailenco/msgpack

```go
msgpack.Marshal(struct|map)
msgpack.Unmarshal(msgpackbinary,&p)
```

reflect反射

反射是指在程序运行期对程序本身进行访问和修改的能力

reflect包封装了反射相关的方法:

获取类型信息:reflect.TypeOf,是静态的

获取值信息:reflect.ValueOf,是动态的

反射可以获取interface类型信息、获取值信息、修改值信息

反射可以查看结构体字段、类型、方法,修改结构体的值,调用方法

  • 空接口结合反射

    可以通过 空接口 可以表示任何参数,利用反射判断参数类型

官方标准库

官方标准库


转载请标注来源:golang常用标准库.html - 9ong.com



喜欢的朋友记得点赞、收藏、关注哦!!!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【物联网原理与运用】知识点总结(上)

目录 名词解释汇总 第一章 物联网概述 1.1物联网的基本概念及演进 1.2 物联网的内涵 1.3 物联网的特性——泛在性 1.4 物联网的基本特征与属性&#xff08;五大功能域&#xff09; 1.5 物联网的体系结构 1.6 物联网的关键技术 1.7 物联网的应用领域 第二章 感知与识别技术 2.1 …

macOS 安装tomcat9

macOS 安装tomcat9 URL&#xff1a;https://tomcat.apache.org/download-90.cgi 解压之后放到指定目录 /Users/lanren/install/tomcat-9 自己取个名字就行 给权限&#xff1a; ① 先进行权限修改&#xff1a;终端输入sudo chmod 755 /Users/lanren/install/tomcat-9/bin/…

基于STM32的智能家居蓝牙系统(论文+源码)

1总体方案设计 本次基于STM32的智能家居蓝牙系统&#xff0c;其系统总体架构如图2.1所示&#xff0c;采用STM32f103单片机作为控制器&#xff0c;通过DHT11传感器实现温湿度检测&#xff0c;MQ-2烟雾传感器实现烟雾检测&#xff0c;光敏电阻实现光照检测&#xff0c;同时将数据…

Ubuntu 磁盘修复

Ubuntu 磁盘修复 在 ubuntu 文件系统变成只读模式&#xff0c;该处理呢&#xff1f; 文件系统内部的错误&#xff0c;如索引错误、元数据损坏等&#xff0c;也可能导致系统进入只读状态。磁盘坏道或硬件故障也可能引发文件系统只读的问题。/etc/fstab配置错误&#xff0c;可能…

Android系统定制APP开发_如何对应用进行系统签名

前言 当项目开发需要使用系统级别权限或frame层某些api时&#xff0c;普通应用是无法使用的&#xff0c;需要在AndroidManifest中配置sharedUserId&#xff1a; AndroidManifest.xml中的android:sharedUserId“android.uid.system”&#xff0c;代表的意思是和系统相同的uid&a…

【MySQL】DATEDIFF()函数使用

DATEDIFF 函数用于计算两个日期之间的差值&#xff0c;以天为单位 DATEDIFF 函数返回一个整数&#xff0c;表示 date1 和 date2 之间的天数。如果 date1 在 date2 之前&#xff0c;结果为负数&#xff1b;如果在 date2 之后&#xff0c;结果为正数&#xff1b;如果相等&#xf…

yum系统报错:SyntaxError: multiple exception types must be parenthesized

执行yum相关步骤报错如下&#xff1a; File "/usr/bin/yum", line 30except KeyboardInterrupt, e:^^^^^^^^^^^^^^^^^^^^ SyntaxError: multiple exception types must be parenthesized原因&#xff1a;python解释器版本错误&#xff0c;yum运行版本为python 2.7&am…

MapReduce完整工作流程

1、mapreduce工作流程(终极版) 0. 任务提交 1. 拆-split逻辑切片--任务切分。 FileInputFormat--split切片计算工具 FileSplit--单个计算任务的数据范围。 2. 获得split信息和个数。 MapTask阶段 1. 读取split范围内的数据。k(偏移量)-v(行数据) 关键API&#xff1a;TextI…

毕业项目推荐:基于yolov8/yolov5/yolo11的动物检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式&#xff09;功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…

了解Node.js

Node.js是一个基于V8引擎的JavaScript运行时环境&#xff0c;它允许JavaScript代码在服务器端运行&#xff0c;从而实现后端开发。Node.js的出现&#xff0c;使得前端开发人员可以利用他们已经掌握的JavaScript技能&#xff0c;扩展技能树并成为全栈开发人员。本文将深入浅出地…

MAC上安装Octave

1. 当前最新版Octave是9.3版本&#xff0c;需要把mac os系统升级到14版本&#xff08;本人之前的版本是10版本&#xff09; https://wiki.octave.org/Octave_for_macOS octave的历史版本参考此文档&#xff1a;Octave for macOS (outdated) - Octavehttps://wiki.octave.org/Oc…

矩阵求逆的几种方式

矩阵求逆的几种方式&#xff08;以二阶为例&#xff09; 矩阵求逆的方法有多种&#xff0c;以下是常用的几种方式总结&#xff1a; 1. 行列式公式法 这是最常见的方法&#xff0c;适用于 2 2 2 \times 2 22矩阵。 对于矩阵&#xff1a; Φ [ a b c d ] , \Phi \begin{bma…

【优选算法篇】:深入浅出位运算--性能优化的利器

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;优选算法篇–CSDN博客 文章目录 一.位运算一.位运算概述二.常见的位运算操作符三.常见的位运…

每日十题八股-2025年1月12日

1.为什么四次挥手之后要等2MSL? 2.服务端出现大量的timewait有哪些原因? 3.TCP和UDP区别是什么&#xff1f; 4.TCP为什么可靠传输 5.怎么用udp实现http&#xff1f; 6.tcp粘包怎么解决&#xff1f; 7.TCP的拥塞控制介绍一下&#xff1f; 8.描述一下打开百度首页后发生的网络过…

微信小程序——创建滑动颜色条

在微信小程序中&#xff0c;你可以使用 slider 组件来创建一个颜色滑动条。以下是一个简单的示例&#xff0c;展示了如何实现一个颜色滑动条&#xff0c;该滑动条会根据滑动位置改变背景颜色。 步骤一&#xff1a;创建小程序项目 首先&#xff0c;使用微信开发者工具创建一个新…

嵌入式Linux之文件IO

一、标准IO库 1.1 打开/关闭文件 fopen 新建 fopen_test.c&#xff0c;写入以下内容&#xff1a; #include <stdio.h> int main() {/* 打开文件函数&#xff1a;FILE *fopen (const char *__restrict __filename,const char *__restrict __modes)参数&#xff1a;c…

HTML5实现好看的端午节网页源码

HTML5实现好看的端午节网页源码 前言一、设计来源1.1 网站首页界面1.2 登录注册界面1.3 端午节由来界面1.4 端午节习俗界面1.5 端午节文化界面1.6 端午节美食界面1.7 端午节故事界面1.8 端午节民谣界面1.9 联系我们界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 H…

【2024年华为OD机试】(A卷,100分)- 单词倒序(Java JS PythonC/C++)

一、问题描述 题目描述 输入单行英文句子&#xff0c;里面包含英文字母&#xff0c;空格以及,.?三种标点符号&#xff0c;请将句子内每个单词进行倒序&#xff0c;并输出倒序后的语句。 输入描述 输入字符串S&#xff0c;S的长度 1 ≤ N ≤ 100 输出描述 输出倒序后的字…

插入实体自增主键太长,mybatis-plaus自增主键

1、问题 spring-boot整合mybtais执行insert语句时&#xff0c;主键id为长文本数据。 2、分析问题 1)数据库主键是否自增 2&#xff09;数据库主键的种子值设置的多少 3、解决问题 1&#xff09;数据库主键设置的时自增 3&#xff09;种子值是1 所以排查是数据库的问题 4、继…

Java高频面试之SE-11

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; Java中是引用传递还是值传递&#xff1f; 在 Java 中&#xff0c;方法参数传递是通过 值传递 的方式实现的&#xff0c;但这可能会引起一…