Minimal and Clean blog theme for Hugo
语义化标签
header, nav, aside, article, section footer
…项目面试题
React面试题
Fragments组件中可以设置key属性,但是简写后将不支持?
Router
createMemoryHistory
createMemoryHistory主要用于服务器渲染,它创建一个内存中的history对象,不与浏览器URL互动
生命周期
getDerivedStateFromError和componentDidCatch
hook
useLayoutEffect 其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。
useDebugValue,在开发者工具中展示的信息
…面试题
正则表达式
exec方法
正则.exec(字符串),方法返回一个数组,比普通数组多了index、input、groups等字段
数量
?
意为 0 或 1 次
+
意为 1 次以上
*
意为 0 次以上
array
sort方法
不传参数:如果没有提供 compareFn,所有非 undefined 的数组元素都会被转换为字符串,并按照 UTF-16 码元顺序比较字符串进行排序。例如“banana”会被排列到“cherry”之前。在数值排序中,9 出现在 80 之前,但因为数字会被转换为字符串,在 Unicode 顺序中“80”排在“9”之前。所有的 undefined 元素都会被排序到数组的末尾。sort() 方法保留空槽。如果源数组是稀疏的,则空槽会被移动到数组的末尾,并始终排在所有 undefined 元素的后面。
传参数:(a,b) => number
,a-b就是升序,b-a就是降序。
变量提升
变量
console.log(num)
var num = 1
相当于
var num
console.log(num)
num = 1
函数
//函数声明式:
function foo () {}
//变量形式声明:
var fn = function () {}
fn()
var fn = function () {
console.log(1)
}
// 输出结果:Uncaught TypeError: fn is not a function
foo()
function foo () {
console.log(2)
}
// 输出结果:2
JS 引擎会搜集所有的变量声明,并且提前让声明生效。而剩下的语句需要等到执行阶段、等到执行到具体的某一句时才会生效。这就是变量提升背后的机制。
…最近用到的技术
Use htm + preact to implement build-free development pages.
example
<script src="https://unpkg.com/htm/preact/standalone.umd.js"></script>
<script>
const { html, Component, render } = window.htmPreact;
class DataSource extends Component {
constructor(props) {
super(props);
this.state = { value: 0 };
}
add(e) {
this.setState({ value: this.state.value + 1 })
}
// 事件
render(props, state) {
return html`
<div class="row">
<p>${this.state.value}</p>
<button onClick=${this.add}>add</button>
</div>
`;
}
// map
render1(props, state) {
return html`
<div class="row">
${props.tables.map((table) => {
return html` <h3>${table.name}</h3> `;
})}
</div>
`;
}
}
render(html`<${DataSource} />`, document.body);
</script>
先通过标签加载库,然后就是正常的(P)React 组件的写法,只不过 render 中的组件是基于字符串模板的写法。
…将模板文件嵌入到可执行文件中
先安装程序
go install gitee.com/wanghsushuo/proxy@latest
程序的代码中用到了一个模板文件,导致运行proxy时程序报错找不到模板文件,这时就可以用go embed解决这个问题。
可以使用Go 1.16引入的 //go:embed
功能来解决这个问题。//go:embed
可以将资源文件内容直接打包到二进制文件,方便部署。它可以将任何文件或者文件夹的内容打包到编译出的可执行文件中。如果要嵌入文件,变量的类型得是 string
或者 []byte
,如果要嵌入一组文件,变量的类型得是 embed.FS
Source 7。
假设你的模板文件位于 templates
目录下,你可以使用以下代码将其嵌入到你的程序中:
package main
import (
"embed"
"html/template"
"os"
)
//go:embed templates/*.tmpl
var tpls embed.FS
func main() {
t, err := template.ParseFS(tpls, "templates/*")
if err != nil {
panic(err)
}
// 假设有一个名为 index.tmpl 的模板
if err = t.ExecuteTemplate(os.Stdout, "index.tmpl", nil); err != nil {
panic(err)
}
}
这段代码首先使用 //go:embed
指令将 templates
目录下的所有 .tmpl
文件嵌入到 tpls
变量中,然后使用 template.ParseFS
函数从 tpls
中解析出所有的模板。最后,t.ExecuteTemplate
函数被用来执行特定的模板并将结果写入 os.Stdout
。
注意,//go:embed
指令只能用于包级别的变量,不能用于函数内部的局部变量Source 7。另外,如果你的模板文件在子目录中,你需要在解析模板时包含子目录的路径,如上述代码中的 "templates/*"
。
Autogpt
不支持windows,但支持wsl
python版本3.10以上
下面的脚本是从官网安装3.11
#!/bin/bash
# 更新源 和安装编译工具
sudo apt update
sudo apt install -y build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget pkg-config
export http_proxy=http://192.168.31.107:7890/
export https_proxy=$http_proxy
# 下载Python 3.11.6 源码
wget https://www.python.org/ftp/python/3.11.6/Python-3.11.6.tgz
# 解压
tar -zxf Python-3.11.6.tgz
# 编译安装
cd Python-3.11.6
./configure --enable-optimizations
make -j 8
sudo make altinstall
# 输出Python版本确认
python3.11 -V
在把环境变量中的python版本改掉
#!/bin/bash
# 设置变量
PY_VERSION=3.11
PY_PATH=/usr/local/bin/python$PY_VERSION
# 1. 更新alternatives
sudo update-alternatives --install /usr/bin/python python $PY_PATH 1
sudo update-alternatives --install /usr/bin/python3 python3 $PY_PATH 1
# 2. 调整软链接
sudo rm -f /usr/bin/python
sudo rm -f /usr/bin/python3
sudo ln -s $PY_PATH /usr/bin/python
sudo ln -s $PY_PATH /usr/bin/python3
# 3. 修改PATH优先级
echo "export PATH=$PY_PATH:\$PATH" >> ~/.bashrc
source ~/.bashrc
# 4. 测试版本
python --version
python3 --version
创建token要用老本的,tokens (classic),并选repo权限
…开发一个带缓存的代理服务器
开发一个带缓存的代理服务器
背景
前端页面中经常会有很多的请求,而开发环境的服务器资源比较差,就会经常出现页面加载两三面的情况,并且开发时也经常需要刷新页面,这就是一个降低了工作效率的点。
为了解决该问题,我就打算开发一个可以缓存请求的代理服务器。
原来的工作流程是,前端启动项目时,后端服务器地址可以是线上的测试环境,或者本地的Go服务器。
使用缓存服务后,就将服务器地址改为本地的缓存服务地址,比如localhost:7000。
缓存服务有web管理页面,可以配置源地址,可以设置忽略缓存的条件、清理和查看缓存。
实现
1. 服务器
先是一个普通的服务器,监听 7001 端口
// Handle the requests
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
proxyHandler(w, r, proxy)
})
log.Fatal(http.ListenAndServe("localhost:7000", nil))
3. 处理缓存
缓存保存在内存中,是一个全局唯一的结构体
type MemoryCache struct {
cache map[string]string
queue chan []string
}
缓存的主体是一个原生的map。key是由url和请求体计算而来的,value是返回体。
queue是为了解决map并发不安全的报错。
func NewMemoryCache() ICache {
ins := &MemoryCache{
cache: make(map[string]string),
queue: make(chan []string),
}
// Concurrency safe set
go func() {
for i := range ins.queue {
ins.cache[i[0]] = i[1]
}
}()
return ins
}
func (c *MemoryCache) Set(key string, value string) {
// Concurrency safe set
c.queue <- []string{key, value}
}
处理请求
如果没有命中缓存,就要发起一个请求到源。要分别处理请header、body,要根据配置设置对应的host地址。
…Wasm
package main
import (
"syscall/js"
)
// list function
func list() string {
// Your code here
return "List Result"
}
// status function
func status() string {
// Your code here
return "Status Result"
}
func main() {
js.Global().Set("list", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
return list()
}))
js.Global().Set("envStatus", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
return status()
}))
// Wait for the callbacks to be called
select {}
}
用powershell编译
$env:GOOS="js"; $env:GOARCH="wasm"; go build -o main.wasm main.go
用shell编译
GOOS=js GOARCH=wasm go build -o main.wasm main.go
<script src="src/lib/wasm_exec.js"></script>
<script>
const go = new Go(); // Defined in wasm_exec.js
WebAssembly.instantiateStreaming(fetch('src/lib/main2.wasm'), go.importObject).then((result) => {
go.run(result.instance);
console.log(window.list());
console.log(window.envStatus());
});
</script>
wasm_exec.js是Go语言工具链自带的一个文件,它提供了Go编译的WebAssembly模块与JavaScript环境之间的桥梁。当在Go中使用syscall/js包时,wasm_exec.js提供了必要的函数和方法来处理JavaScript的回调和其他交互。
…部署svelte到cloudflare
创建项目
npm create svelte@latest myapp
cd myapp
npm install
npm run dev
部署
将项目放到github上,代码push后就会自动运行pages部署。🚀
首先要修改svelte项目,安装 @sveltejs/adapter-cloudflare ,然受修改 svelte.config.js 文件
import adapter from '@sveltejs/adapter-cloudflare';
export default {
kit: {
adapter: adapter({
// See below for an explanation of these options
routes: {
include: ['/*'],
exclude: ['<all>']
}
})
}
};
cloudflare pages 创建新项目,选择github项目,选择框架是svelteKit。
…