Minimal and Clean blog theme for Hugo

语义化标签


header, nav, aside, article, section footer

Read more ⟶

项目面试题


Read more ⟶

React面试题


Fragments组件中可以设置key属性,但是简写后将不支持?

Router

createMemoryHistory

createMemoryHistory主要用于服务器渲染,它创建一个内存中的history对象,不与浏览器URL互动

生命周期

getDerivedStateFromError和componentDidCatch

hook

useLayoutEffect 其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

useDebugValue,在开发者工具中展示的信息

Read more ⟶

面试题


正则表达式

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 引擎会搜集所有的变量声明,并且提前让声明生效。而剩下的语句需要等到执行阶段、等到执行到具体的某一句时才会生效。这就是变量提升背后的机制。

Read more ⟶

最近用到的技术


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 中的组件是基于字符串模板的写法。

Read more ⟶

将模板文件嵌入到可执行文件中


先安装程序

go install gitee.com/wanghsushuo/proxy@latest 

程序的代码中用到了一个模板文件,导致运行proxy时程序报错找不到模板文件,这时就可以用go embed解决这个问题。

可以使用Go 1.16引入的 //go:embed 功能来解决这个问题。//go:embed 可以将资源文件内容直接打包到二进制文件,方便部署。它可以将任何文件或者文件夹的内容打包到编译出的可执行文件中。如果要嵌入文件,变量的类型得是 string 或者 []byte,如果要嵌入一组文件,变量的类型得是 embed.FSSource 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/*"

Read more ⟶

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权限

Read more ⟶

开发一个带缓存的代理服务器


开发一个带缓存的代理服务器

背景

前端页面中经常会有很多的请求,而开发环境的服务器资源比较差,就会经常出现页面加载两三面的情况,并且开发时也经常需要刷新页面,这就是一个降低了工作效率的点。

为了解决该问题,我就打算开发一个可以缓存请求的代理服务器。

原来的工作流程是,前端启动项目时,后端服务器地址可以是线上的测试环境,或者本地的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地址。

Read more ⟶

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的回调和其他交互。

Read more ⟶

部署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。

Read more ⟶