${variable#pattern}
是一种字符串处理方式,其中 #
后跟着一个模式(pattern)
。这个语法的作用是从字符串变量 variable 的开头删除匹配 pattern
的最短子串,并返回删除后的结果。${variable#*@}
的含义是:● variable
是一个字符串变量,通常是一个包含文本的字符串。
● #
表示从字符串开头开始匹配。
● *@
是一个通配符模式,它匹配字符串中的任意字符序列,直到第一个 @ 字符。
所以,${variable#*@}
的作用是从变量 variable
的开头删除匹配 *@
模式的最短子串,并返回删除后的结果。通常,这种操作用于处理文本或字符串,以过滤掉或提取感兴趣的部分。
例如,如果 variable
的值是 "user@example.com"
,那么 ${variable#*@}
的结果将是 "example.com"
,因为它删除了字符串中第一个 "@"
符号及其之前的部分。
开发环境:
系统: ubuntu20.04
go版本: 1.19
编辑器: goland
sse 服务器发送事件(Server-Sent Events),服务端向客户端单向传递消息。在一些只需要接受服务端数据的需求中可以取代websocket技术,使用起来也很简单。
目前go已经有一些支持sse的库,我这里选用了:eventsource.v1
1 | go get gopkg.in/antage/eventsource.v1 |
广播模式SSE指不设置事件名,或者说是不设置通道,所有客户端接收同样的数据。
具体代码实现如下:点击查看源码
服务端
1 | package main |
前端
1 |
|
启动服务端代码:
1 | go run main |
打开浏览器访问前端代码: http://localhost:8080
服务端输出:
前端输出:
实现方式和广播模式差不多,只需做简单修改:
服务端代码只需添加事件名称:
1 | // 设置事件名称为:test-event |
前端代码修改接收方式:
1 | es.addEventListener("test-event", (e) => { |
现在项目开发基本上都是前后端分离,这样就会存在跨域问题,SSE解决跨域的方式只需要在new
方法内增加允许跨域请求头:
1 | es := eventsource.New( |
前端创建sse连接时也可添加允许跨域参数:
1 | const es = new EventSource("http://localhost:8080/events", { withCredentials: true }); |
在Chrome浏览器中sse断开后会自动重连,但firefox浏览器中断开后不会重连,解决办法是,前端js通过判断连接状态主动进行重连请求,通过判断readyState的值进行重新调用初始化操作
readyState说明:
前端代码可修改为如下:
1 |
|
开发环境:
系统: ubuntu20.04
go版本: 1.19
编辑器: goland
平时我们编写http的api接口时能够很方便的通过postman工具进行接口调试,那么grpc接口是否也有类似postman的工具可以调试呐?
当然可以,github上有一款工具grpcui,专门用来在浏览器中进行grpc接口调试。
1 | $ go install github.com/fullstorydev/grpcui/cmd/grpcui@latest |
我们以demo_1
测试代码为例进行调试。首先在项目中安装依赖:
1 | $ go get github.com/fullstorydev/grpcui |
1 | $ go run server/main.go |
另起一个终端,执行一下命令,注意这里的端口号要和grpc服务端口号保持一致。
1 | $ grpcui -plaintext 127.0.0.1:8080 |
如果你在执行以上命令的时候出现一下报错:
1 | Failed to compute set of methods to expose: server does not support the reflection API |
需要在server/main.go
文件中添加如下代码,增加反射:
1 | reflection.Register(s) |
此时再运行以上启动grpcui命令,可看到一下输出:
1 | gRPC Web UI available at http://127.0.0.1:41619/ |
浏览器打开http://127.0.0.1:41619/
,可以看到grpcui调试页面:
点击Invoke
按钮,可以看到Response
tab页有对于的相应数据:
开发环境:
系统: ubuntu20.04
go版本: 1.19
编辑器: goland
grpc
:远程过程调用,使用场景很多,也是比较流行的技术之一。使用go开发grpc服务,除了必须的go语言开发环境之外,还需要安装grpc相关命令。
1 | $ sudo apt install -y protobuf-compiler |
如果是其他系统电脑,安装protoc可参考文档:Protocol Buffer Compiler Installation
1 | $ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 |
安装完成后可以在bin目录下看到相关指令:
1 | $ ls $GOPATH/bin |
1 | ├── demo_4 |
1 | $ mkdir demo_4 && cd demo_4 |
1 | $ go get -u google.golang.org/grpc |
流式rpc
使用stream
关键字定义
1 | # helloworld/helloworld.proto |
1 | $ protoc --go_out=. --go_opt=paths=source_relative \ |
命令执行成功之后会在helloworld目录下生成两个文件: helloworld_grpc.pb.go
和helloworld.pb.go
,注意: 不要手动编辑这两个文件。
flag
用法可参考官方文档: https://pkg.go.dev/flag
1 | // server/main.go |
1 | // client/main.go |
开启两个终端,分别运行服务端代码和客户端代码,服务端代码要先运行。
服务端
1 | $ go run server/main.go |
客户端
1 | $ go run client/main.go |
下一篇将向大家介绍grpc调试工具。
]]>开发环境:
系统: ubuntu20.04
go版本: 1.19
编辑器: goland
grpc
:远程过程调用,使用场景很多,也是比较流行的技术之一。使用go开发grpc服务,除了必须的go语言开发环境之外,还需要安装grpc相关命令。
1 | $ sudo apt install -y protobuf-compiler |
如果是其他系统电脑,安装protoc可参考文档:Protocol Buffer Compiler Installation
1 | $ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 |
安装完成后可以在bin目录下看到相关指令:
1 | $ ls $GOPATH/bin |
1 | ├── demo_3 |
1 | $ mkdir demo_3 && cd demo_3 |
1 | $ go get -u google.golang.org/grpc |
流式rpc
使用stream
关键字定义
1 | # helloworld/helloworld.proto |
1 | $ protoc --go_out=. --go_opt=paths=source_relative \ |
命令执行成功之后会在helloworld目录下生成两个文件: helloworld_grpc.pb.go
和helloworld.pb.go
,注意: 不要手动编辑这两个文件。
flag
用法可参考官方文档: https://pkg.go.dev/flag
1 | // server/main.go |
1 | // client/main.go |
开启两个终端,分别运行服务端代码和客户端代码,服务端代码要先运行。
服务端
1 | $ go run server/main.go |
客户端
1 | $ go run client/main.go |
下一篇将向大家介绍双向流式rpc。
]]>开发环境:
系统: ubuntu20.04
go版本: 1.19
编辑器: goland
grpc
:远程过程调用,使用场景很多,也是比较流行的技术之一。使用go开发grpc服务,除了必须的go语言开发环境之外,还需要安装grpc相关命令。
1 | $ sudo apt install -y protobuf-compiler |
如果是其他系统电脑,安装protoc可参考文档:Protocol Buffer Compiler Installation
1 | $ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 |
安装完成后可以在bin目录下看到相关指令:
1 | $ ls $GOPATH/bin |
1 | ├── demo_2 |
1 | $ mkdir demo_2 && cd demo_2 |
1 | $ go get -u google.golang.org/grpc |
流式rpc
使用stream
关键字定义
1 | # helloworld/helloworld.proto |
1 | $ protoc --go_out=. --go_opt=paths=source_relative \ |
命令执行成功之后会在helloworld目录下生成两个文件: helloworld_grpc.pb.go
和helloworld.pb.go
,注意: 不要手动编辑这两个文件。
flag
用法可参考官方文档: https://pkg.go.dev/flag
1 | // server/main.go |
1 | // client/main.go |
开启两个终端,分别运行服务端代码和客户端代码,服务端代码要先运行。
服务端
1 | $ go run server/main.go |
客户端
1 | $ go run client/main.go |
下一篇将向大家介绍客户端流式rpc。
]]>开发环境:
系统: ubuntu20.04
go版本: 1.19
编辑器: goland
grpc
:远程过程调用,使用场景很多,也是比较流行的技术之一。使用go开发grpc服务,除了必须的go语言开发环境之外,还需要安装grpc相关命令。
1 | $ sudo apt install -y protobuf-compiler |
如果是其他系统电脑,安装protoc可参考文档:Protocol Buffer Compiler Installation
1 | $ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 |
安装完成后可以在bin目录下看到相关指令:
1 | $ ls $GOPATH/bin |
1 | ├── demo_1 |
1 | $ mkdir demo_1 && cd demo_1 |
1 | $ go get -u google.golang.org/grpc |
1 | # helloworld/helloworld.proto |
1 | $ protoc --go_out=. --go_opt=paths=source_relative \ |
命令执行成功之后会在helloworld目录下生成两个文件: helloworld_grpc.pb.go
和helloworld.pb.go
,注意: 不要手动编辑这两个文件。
flag
用法可参考官方文档: https://pkg.go.dev/flag
1 | // server/main.go |
1 | // client/main.go |
开启两个终端,分别运行服务端代码和客户端代码,服务端代码要先运行。
服务端
1 | $ go run server/main.go |
客户端
1 | $ go run client/main.go |
以上便是go实现单项rpc的所有内容,如果一切顺利,恭喜你,以及成功入门grpc,下一篇将向大家介绍服务端流式rpc。
]]>vscode,idea,golang
等编辑器的全局搜索快捷键Ctrl+Shift+F
无法使用了,经排查发现是因为搜狗输入法占用了该快捷键,是搜狗输入法的繁简体切换快捷键。打开搜狗输入法的设置页面可以在高级选项里看到。但是在设置里取消简繁切换快捷键的勾选保存之后发现无效果,快捷键依然被占用。
正确的解决方案是:
1 | $ vim ~/.config/sogoupinyin/conf/env.ini |
找到ShortCutFanJian
配置,将值改为0;默认1,等于开启;改为0表示关闭
附加组件中找到简繁转换,点击配置
将默认快捷键设置为空, 保存即可。
如果发现未生效,需要重启电脑。
]]>go环境搭建不在这里赘述。
以下内容的执行环境为:
系统:ubuntu20.04
go版本:v1.19
执行以下命令创建一个go开发安卓应用的测试目录:
1 | $ mkdir $GOPATH/src/goapp && cd $GOPATH/src/goapp |
在该目录下执行以下命令获取官方提供的示例项目:
1 | $ go get -d golang.org/x/mobile/example/basic |
1 | $ go install golang.org/x/mobile/cmd/gomobile@latest |
然后执行以下命令打包安卓应用:
1 | $ gomobile build -target=android -androidapi 19 golang.org/x/mobile/example/basic |
此时会发现以下相关错误:
gomobile: could not locate Android SDK: stat /home/test/Android/Sdk: no such file or directory; Android SDK was not found at /home/test/Android/Sdkgomobile: no usable NDK in /home/test/Android/Sdk: open /home/test/Android/Sdk/ndk: no such file or directory, open /home/test/Android/Sdk/ndk-bundle/meta/platforms.json: no such file or directory
这是因为本地没有配置安卓开发环境导致的。
访问谷歌中国开发者网站下载 Android Studio 编辑器:https://developer.android.google.cn/studio
下载完成后执行以下操作:
1 | # 将安装包移到/opt目录下,需要管理员权限 |
第一次打开android-studio需要进行一些配置,一直选择下一步设置即可,其中有两个地方需要注意:
插件安装完成之后点击Finish即可打开应用。
Android studio安装完成后并没有万事大吉,默认并没安装NDK,需要自己手工再安装。
点击ok会自动下载选择的插件。
此时继续回到之前的项目目录,执行安卓构建命令
1 | $ gomobile build -target=android -androidapi 19 golang.org/x/mobile/example/basic |
这一次没有出现报错,并且目录下多了一个basic.apk文件,该文件即为打包成功的安卓应用,可以安装一个安卓模拟器进行测试了。
模拟器我选用了Anbox
1 | $ sudo snap install --devmode --edge anbox |
安装完成之后执行以下命令启动安卓模拟器:
1 | $ anbox.appmgr |
我比较顺利没有遇到报错,如果遇到模拟器启动报错,可以参考文章:https://juejin.cn/post/7152407243974148127 解决
打开后的界面如下:
安装安卓应用还需要adb命令:
1 | $ sudo apt install android-tools-adb -y |
然后在最开始的项目目录下执行以下命令安装应用,此时安卓模拟器必须是打开的状态:
1 | $ asb install ./basic.apk |
安装成功后即可在模拟器中看到该应用
单击打开,运行效果如下:
此文章主要目的是为了帮助你了解如何使用golang开发安卓应用的流程,流程打通之后,可以结合自己的想法,做一些自己的应用。
]]>1 | golang.org/x/sys/unix |
解决办法如下:
1.运行如下命令:
1 | go get -u golang.org/x/sys |
2.运行:
1 | go mod vendor |
首先找到安装天空卫士的目录:/Library/Application Support/SkyGuard
电脑关机,长按开机键直到进入recovery模式, 点自己的用户,输入密码,点下一步,然后到左上方找到终端打开
diskutil list 查看目前的磁盘, 找到标记有synthesized
的磁盘,并找到对应的数据盘(有data关键字),这里假设为:/dev/disk3s3
执行diskutil mount /dev/disk3s3
, 可能会报 this is an encrypted and locked APFS Volume
的错,根据提示执行:diskutil apfs unlockVolume /dev/disk3s3
,然后输入密码。再次执行diskutil mount /dev/disk3s3
即可。
进入/Volumes/Macintosh HD/Library/Application Support
目录,可以看到有SkyGuard
文件。
执行rm -rf SkyGuard
删除天空位置文件目录
reboot
重启电脑,发现天空卫士已成功卸载
1 | sudo rm -fr /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin |
1 | sudo rm -rf /Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk |
1 | java -version |
最近在mac M1上构建的docker镜像,发布到ubuntu20系统的服务器上后,一直运行失败。输出以下报错信息:
1 | The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64) and no specific platform was requested |
在使用docker logs 查看docker日志的时候提示:
1 | standard_init_linux.go:228: exec user process caused: exec format error |
mac M1上设置”experimental”: true
实现跨平台打包
docker buildx build –platform linux/amd64 -t name .
在终端中,输入:
1 | arch -x86_64 zsh |
通过这个命令可以让 shell 运行在Rosetta2下。
之后你可以通过 nvm install v14
来安装低版本 Node。
在此之后,您可以不用在 Rosetta2 中就可以使用安装的可执行文件,也就是说,您可以将 Node v15与其他节点版本互换使用。
方法二就是通过 Rosetta2 来启动终端,这样通过 Rosetta2 转译到 x86 架构中执行安装,也一样可以安装成功。
nvm install v14
命令1 | X Error of failed request: BadWindow (invalid Window parameter) |
解决方案
这个问题其实和 KDE 无关, 应该是 deepin 在打包 deepin-wine 的过程中有意或者无意加入了 GNOME 依赖。
执行 /usr/lib/gnome-settings-daemon/gsd-xsettings
即可.
或者后台运行:
1 | nohup /usr/lib/gnome-settings-daemon/gsd-xsettings > /dev/null 2>&1 & |
如果 GNOME 的版本较低(比如Debian 9), 没有单独的 gsd-xsettings
可执行文件, 则执行 gnome-settings-daemon
.
然后切换到对应目录 cd /opt/deepinwine/apps/Deepin-WXWork
或者 /opt/deepinwine/apps/Deepin-WeChat
运行 ./run.sh
即可启动软件。
由于每次都执行上边的命令很繁琐,可以将其加入i3的启动项,每次开机制动设置即可。
]]>https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
1 | tar -zxvf jdk-8u171-linux-x64.tar.gz |
1 | ##将文件从下载目录 挪到/usr/local下 |
设置全局生效
修改全局配置文件,作用与所有用户: vim /etc/profile
1 | export JAVA_HOME=/usr/local/jdk1.8 |
设置当前用户生效
修改当前用户配置文件,只作用于当前用户:vim ~/.bashrc
1 | export JAVA_HOME=/usr/local/jdk1.8 |
1 | ##对应方法一: |
1 | java -version |
目前版本的 ALSA 安装后,所有声道默认是静音的,必须手动解除。
使用 alsamixer
的 ncurses
界面,配置十分简单:
1 | $ alsamixer |
此外,还可以在命令行下使用 amixer
:
1 | $ amixer sset Master unmute |
在alsamixer
中,下方标有 MM
的声道是静音的,而标有 00
的通道已经启用。
使用 ←
和 →
方向键,选中 Master
和 PCM
声道。按下 m
键解除静音。使用 ↑
方向键增加音量,直到增益值为0
。该值显示在左上方Item:
字段后。过高的增益值会导致声音失真。
要启用麦克风,切换至 Capture 选项卡,按下 F4
,按下 空格
启用其中一个声道即可。
按下 Esc
键退出 alsamixer
。
1 | F6 选择网卡 |
1 | M 静音状态切换 |
1 | cat /proc/asound/cards # 查看系统声卡 |
输出如下:
1 | 0 [PCH ]: HDA-Intel - HDA Intel PCH |
设置声音
1 | amixer -c 1 -q set Master 2dB+ unmute |
1 | -c 制定声卡id, 默认为0 |
1 | npm WARN deprecated fsevents@1.2.12: fsevents 1 will break on node v14+. Upgrade to fsevents 2 with massive improvements. |
网上查找解决方案,都是通过执行xcode-select --install
命令修复,但是执行该命令时会出现如下提示:
1 | xcode-select: error: command line tools are already installed, use "Software Update" to install updates |
最终的解决办法是先卸载之前安装的xcode-select
,并重新安装:
1 | $ sudo rm -rf $(xcode-select -print-path) |
scp
是经常使用的一个本地与远程服务器相互拷贝数据的命令,zsh
是我最喜欢的shell
,但是在zsh
下使用scp
来拷贝远程服务器的文件时,却出现这样的错误。
1 | $ scp -r test-server:/etc/nginx/conf.d/* . |
同样地命令,在bash
下确实可以执行的,这个原因是什么呢?
由于zsh
不会按照远程地址上的文件去扩展参数,当你使用test-server:/etc/nginx/conf.d/*
,因为本地当前目录中,是不存在test-server:/etc/nginx/conf.d/*
,所以匹配失败。默认情况下,bash
在匹配失败时就使用原来的内容,zsh
则报告一个no matches
的错误。
在zsh
中执行setopt nonomatch
,告诉它不要报告no matches
的错误,而是当匹配失败时直接使用原来的内容。
实际上,不管是 bash
还是 zsh
,不管设置了什么选项,只要把test-server:/etc/nginx/conf.d/*
加上引号,如"test-server:/etc/nginx/conf.d/*"
,就可解决问题。
当然根本的解决办法还是告诉zsh
不要报告no matches
错误。
执行下面的命令可以一劳永逸:
1 | $ echo "setopt nonomatch" >> ~/.zshrc |