批评

真正能接受批评的人,能把“批评的事件”和“自我身份的认同”进行课题分离。 通常这样的人,也能从负面信息里提炼出值得改进的行为。(包括是否应该远离发出不当批评的人)

2025/8/20
articleCard.readMore

Milvus 入门教程

Milvus 是一个开源的向量数据库,它是为了生成式 AI 的应用设计的。它支持大规模的向量检索。 Milvus 的发音是 /ˈmil vəs/。 本文将是 Milvus 的使用入门。 (adsbygoogle = window.adsbygoogle || []).push({}); 安装 Milvus 先准备好 Python 环境,然后使用 pip 安装 Milvus: 1 pip install -U pymilvus 使用 Milvus 创建一个本地的 Milvus 文件 1 2 3 from pymilvus import MilvusClient client = MilvusClient("milvus_demo.db") 运行上面的代码,在当前目录下会生成一个名为 milvus_demo.db 的文件。 创建一个集合 Collection 我们通常把相关联的数据放在 Milvus 中的一个集合(Collection)中,我们可以把集合想象成一个传统数据库中的表。 下面的代码会创建一个集合,它存储的向量数据的的维度数是 768,这个维度数是接下来准备的向量数据的维度。 1 2 collection_name = "milvus_demo" client.create_collection(collection_name, dimension=768) 为了避免重复创建 Collection,我们可以先检查 Collection 是否存在: 1 2 3 collection_name = "milvus_demo" if not client.has_collection(collection_name): client.create_collection(collection_name, dimension=768) 准备数据 pymilvus[model] python 库中提供了一些工具函数,可以帮助我们把文本数据转换成向量,来进行 Milvus 的学习。 下面会把hello world、你好世界、milvus is great这三个文本数据转换成向量数据: 1 2 3 4 5 6 7 8 from pymilvus import model embedding_fn = model.DefaultEmbeddingFunction() docs = ["hello world", "hi", "你好世界", "milvus is great"] vectors = embedding_fn.encode_documents(docs) print ("向量数据的维度:", len(vectors[0])) 我们会得到一个向量数据的列表,每个向量数据的维度是 768。 然后我们可以把向量数据和文本数据组合成由id、vector、text组成的数据列表: 1 2 3 4 5 6 7 data = [ {"id": i, "vector": vectors[i], "text": docs[i]} for i in range(len(vectors)) ] print("数据包含", len(data), "个条目,每个条目包含字段: ", data[0].keys()) print("vector 维度:", len(data[0]["vector"])) 插入数据 使用 insert(collection_name, data) 方法把列数据插入到 Milvus 的 milvus_demo 集合中: 1 2 response = client.insert(collection_name, data) print(response) 此时我们插入了三条数据,每条数据包含了向量和原始文本。 检索数据 在 Retrieval Augmented Generation(RAG) 的应用场景中,通常要检索与输入文本最关度最高的文本数据。向量数据之间的关度可以通过计算向量之间的距离来衡量。 首先我们要把输入的数据转换成向量: 1 2 3 # 1.将要查询的数据转换为向量 query = "hi" query_vectors = embedding_fn.encode_queries([query]) 然后我们可以使用 search(collection_name, data) 方法来检索与输入文本在向量空间中最相近的数据: 1 2 3 4 5 6 7 8 # 2.向量查询 query_response = client.search( collection_name, data=query_vectors, # 查询向量 limit=2, # 返回的最大结果数 output_fields=["id", "text"], # 返回的字段 ) print(query_response) 我们会得到一个列表,列表中的每个元素包含了检索到的数据的id、distance、entity字段,其中distance字段表示检索到的数据与输入数据的距离。 1 2 3 4 5 data: ["[ {'id': 1, 'distance': 1.0, 'entity': {'text': 'hi', 'id': 1}}, {'id': 0, 'distance': 0.5280660390853882, 'entity': {'text': 'hello world', 'id': 0}}, {'id': 2, 'distance': 0.44701865315437317, 'entity': {'text': '你好世界', 'id': 2}} ]"] distance 越接近 1,表示两个向量距离越近。从上面的结果中,我们可以看到,查询结果中的 hi 的与查询的文本相同,所以 distance 值为 1 。与查询文本hi距离最近的文本依次是hi、hello world、你好世界。这意味着它们之间的相关度排序也是这样的。 删除数据 delete() 方法可以删除集合中的数据: 通过 id 删除数据: 1 client.delete(collection_name, ids=[1]) 通过条件删除数据: 1 client.delete(collection_name, filter="id == 1") 删除集合 drop_collection() 方法可以删除集合: 1 client.drop_collection(collection_name)

2024/10/10
articleCard.readMore

怎么在网页中实现自动调整视频的清晰度

HTTP Live Streaming (HLS) 是 Apple 开发的一种流媒体协议。能够根据用户的网络状况自动调整视频的清晰度。它将整个视频分成一系列小的 HTTP 文件,每个文件包含一小段视频内容。这种方式可以让视频在不同的网络环境下更加流畅地播放。 本文们将介绍如何在网页中使用实现基于 HLS 视频播放,并显示当前播放的分辨率。 使用 FFmpeg 生成 HLS 视频流 转码视频为多码率版本 使用 FFmpeg 命令行工具将原始视 input.mp4 频转码为多个分辨率(1080p、720p、480p)的 HLS 视频: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ffmpeg -i input.mp4 \ -filter_complex \ "[0:v]split=3[v1][v2][v3]; \ [v1]scale=1920:1080[v1out]; \ [v2]scale=1280:720[v2out]; \ [v3]scale=854:480[v3out]" \ -map "[v1out]" -map 0:a -c:v:0 libx264 -b:v:0 5000k -maxrate:v:0 5350k -bufsize:v:0 7500k \ -map "[v2out]" -map 0:a -c:v:1 libx264 -b:v:1 3000k -maxrate:v:1 3210k -bufsize:v:1 4500k \ -map "[v3out]" -map 0:a -c:v:2 libx264 -b:v:2 1500k -maxrate:v:2 1605k -bufsize:v:2 2250k \ -c:a aac -b:a 128k -ac 2 \ -f hls -hls_time 6 -hls_list_size 0 \ -hls_segment_filename 'stream_%v/segment_%03d.ts' \ -master_pl_name master.m3u8 \ -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \ 'stream_%v/index.m3u8' 生成的文件包括: master.m3u8: 主播放列表。 stream_0/: 1080p 版本的切片。 stream_1/: 720p 版本。 stream_2/: 480p 版本。 在网页中实现 HLS 视频的播放 使用以下 HTML 和 JavaScript 代码来播放 HLS 视频并显示当前分辨率 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>自动切换清晰度的视频示例</title> <style> /* 定义显示分辨率的样式 */ #resolution-display { position: absolute; top: 10px; left: 10px; padding: 5px 10px; background-color: rgba(0, 0, 0, 0.7); color: #fff; font-size: 14px; border-radius: 5px; } /* 确保视频容器是相对定位 */ #video-container { position: relative; display: inline-block; } video { width: 100%; height: auto; } </style> </head> <body> <!-- 视频播放器 --> <video id="video" controls></video> <!-- 分辨率显示 --> <div id="resolution-display">分辨率:未知</div> <!-- 引入 hls.js 库 --> <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> <script> // 获取视频元素 var video = document.getElementById("video"); // 获取分辨率显示元素 var resolutionDisplay = document.getElementById("resolution-display"); // HLS 视频源地址(.m3u8 文件) var videoSrc = "./video/video2/master.m3u8"; // 检查浏览器是否支持 hls.js if (Hls.isSupported()) { var hls = new Hls(); hls.loadSource(videoSrc); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, function () { video.play(); }); // 监听 LEVEL_SWITCHED 事件,当播放级别切换时触发 hls.on(Hls.Events.LEVEL_SWITCHED, function (event, data) { updateResolution(); }); // 初始获取当前分辨率 hls.on(Hls.Events.LEVEL_LOADED, function (event, data) { updateResolution(); }); // 定义更新分辨率的函数 function updateResolution() { var level = hls.levels[hls.currentLevel]; if (level) { var width = level.width; var height = level.height; resolutionDisplay.textContent = "分辨率:" + width + "x" + height; } } } // 对于支持原生 HLS 的浏览器(如 Safari) else if (video.canPlayType("application/vnd.apple.mpegurl")) { video.src = videoSrc; video.addEventListener("loadedmetadata", function () { video.play(); // 获取视频的实际分辨率 resolutionDisplay.textContent = "分辨率:" + video.videoWidth + "x" + video.videoHeight; }); } else { console.error("该浏览器不支持 HLS 播放。"); } </script> </body> </html>

2024/9/11
articleCard.readMore

什么是检索增强生成(Retrieval-Augmented Generation)?

最近在主导一个 AI 检索的项目,需要对检索增强生成(RAG)有所了解,下面是我对检索增强生成(RAG)的一个初浅的了解。 索增强生成(RAG)是指对大型语言模型输出进行优化,使其能够在生成响应之前引用训练数据来源之外的权威知识库。 检索增强生成(RAG)的原理图如下: graph TB subgraph 用户交互 Start([用户查询]):::user End([交互响应]):::user end subgraph 大语言模型 end subgraph 知识库构建 SD[(结构化知识库)] --> 向量化知识库 --> VD[(向量知识库)] end Start ==> 向量化用户查询 ==> 向量检索 ==> 相关知识 Start ==> 提示词模版 相关知识 ==> 提示词模版 提示词模版 == 组合 ==> 模型输入 模型输入 ==> 大语言模型 ==> 模型输出 ==> End 相关知识 ==> End 向量化知识库 o-.-o 大语言模型 向量化用户查询 o-.-o 大语言模型 向量检索 o-.-o VD 相关知识 o-.匹配.-o SD classDef user fill:green,color:white

2024/9/10
articleCard.readMore

Phonics 自然拼读常见规则 - 辅音字母的发音规律

辅音字母的读音通常是辅音字母发音的辅音部份。但是存在非常多的例外情况。 字母常见组合发音 B/b/不发音 C/k/ 和 /s//tʃ/ D/d//dʒ/ F/f//v/ G/g/ 和 /dʒ//ŋ/ H/h//θ/ /ð/ /tʃ/ /ʃ/ /w/ /f/ 不发音 J/dʒ/ K/k/ L/l/元音化 M/m/ N/n//ŋ/ P/p//f/ Q/k//kw/ R/r//r/ S/s//z//ʃ/ /ʒer/ /ʃ(ə)n/ /ʒən/ T/t//ʃ/ /tʃ/ /tr/ V/v/ W/w/元音化不发音 X/ks//gz//z/ Y/j/ /aɪ/ /ɪ/ Z/z/ 本文持续更新中… (adsbygoogle = window.adsbygoogle || []).push({}); 音节的划分对于一个单词的读音至关重要,自然拼读的规律基本上是针对单个音节的。如果你不了解什么是音节请阅读我的另一篇博客:Phonics 自然拼读常见规则 - 音节和元音字母的发音规律 什么是辅音 辅音是什么见 辅音 辅音字母的常见发音规律 B 的发音规律 B 通常读作 /b/。 B 在音结尾部的 mb 和 bt 组合中,B 通常不发音。 comb /kəʊm/ bomb /bɒm/ climb /klaɪm/ lamb /læm/ thumb /θʌm/ debt /det/ doubt /daʊt/ subtle /ˈsʌtl/ plumb /plʌm/ C 的发音规律 mindmap((C 的发音规律)) (字母发音) /k/ /s/ /ʃ/ /tʃ/ (组合发音) (sc) /sk/ /s/ (ch) /tʃ/ /k/ (ck) /k/ C 通常读作 /k/ C 在音节中后面跟 E, I, Y 时,通常读作 /s/ 在英语中它被称为 Soft C cent /sent/ city /ˈsɪti/ cycle /ˈsaɪkl/ cell /sel/ ice /aɪs/ city /ˈsɪti/ 有时候也会读作 /ʃ/,如 ocean /ˈəʊʃən/ social /ˈsəʊʃəl/ special /ˈspeʃəl/ C 在音节中后面跟 A, O, U 时,通常读作 /k/ 在英语中它被称为 Hard C cat /kæt/ car /kɑːr/ cot /kɒt/ corn /kɔːn/ cut /kʌt/ cup /kʌp/ C 与 S 组合成 sc 时,与上面类似。sc 后面跟 A, O, U 时,通常读作 /sk/,在 sc 后面跟 E, I, Y 时,读作 /s/ scan /skæn/ scent /sent/ science /ˈsaɪəns/ scythe /saɪð/ scope /skəʊp/ sculpture /ˈskʌlptʃər/ C 在音节中与 H 组合成 ch 时,通常读作 /tʃ/ chat /tʃæt/ check /tʃek/ achieve /əˈtʃiːv/ chocolate /ˈtʃɒklət/ chunk /tʃʌŋ/ C 在音节中与 H 组合成的 ch 有时读作 /k/ character /ˈkærəktər/ chemistry /ˈkemɪstri/ anchor /ˈæŋkər/ ache /eɪk/ C 在音节中与 K 组合成 ck 时,通常读作 /k/ back /bæk/ black /blæk/ clock /klɒk/ duck /dʌk/ luck /lʌk/ sock /sɒk/ D 的发音规律 D 通常读作 /d/ D 有时候会读作 /t/ advanced /ədˈvɑːnst/ 但在音节中的 dg 组合常读作 /dʒ/ edge /edʒ/ judge /dʒʌdʒ/ bridge /brɪdʒ/ badge /bædʒ/ knowledge /ˈnɒlɪdʒ/ F 的发音规律 F 通常读作 /f/。 fan /fæn/ feel /fiːl/ fish /fɪʃ/ food /fuːd/ fun /fʌn/ 极少数情况下会读作 /v/ of /ɒv/ G 的发音规律 mindmap((G 的发音规律)) (字母发音) /g/ /dʒ/ (组合发音) (dg) /dʒ/ (gn) /n/ (ng) /ŋ/ (gh) /g/ G 通常读作 /g/ gap /ɡæp/ get /ɡet/ gift /ɡɪft/ go /ɡəʊ/ gun /ɡʌn/ G 在音节中后面跟 E, I, Y 时,有时读作 /dʒ/,这被称为 Soft G age /eɪdʒ/ change /tʃeɪndʒ/ gym /dʒɪm/ giant /ˈdʒaɪənt/ imagine /ɪˈmædʒɪn/ general /ˈdʒenrəl/ gentle /ˈdʒentl/ 也有一些例外情况,称为 Hard G get /ɡet/ give /ɡɪv/ 音节中的 dg 组合常读作 /dʒ/ knowledge /ˈnɒlɪdʒ/ edge /edʒ/ judge /dʒʌdʒ/ bridge /brɪdʒ/ ng 在音节中的组合通常读作 /ŋ/ bang /bæŋ/ length /leŋθ/ sing /sɪŋ/ song /sɒŋ/ hungry /ˈhʌŋɡri/ G 在音节中与 N 组合成 gn 时,G 通常不发音 这被称为 Silent G,字母 K 也有类似的情况。 gnaw /nɔː/ gnome /nəʊm/ gnat /næt/ gnu /nuː/ sign /saɪn/ G 在音节中与 H 组合成的 gh 通常读作 /g/ ghost /ɡəʊst/ ghastly /ˈɡæstli/ ghetto /ˈɡetəʊ/ H 的发音规律 mindmap((H 的发音规律)) (字母发音) /h/ (组合发音) (th) /θ/ /ð/ (ch) /tʃ/ /k/ (gh) /f/ 不发音 (wh) /w/ /h/ (ph) /f/ (sh) /ʃ/ H 通常读作 /h/ hat /hæt/ help /help/ hit /hɪt/ hot /hɒt/ hut /hʌt/ H 在音节中的与 T 组合成 th 通常读作 /θ/ thank /θæŋk/ theory /ˈθɪəri/ think /θɪŋk/ thought /θɔːt/ thumb /θʌm/ 但上面的组合在定词、冠词、介词、连词或副词以及后面跟着 er 时,通常读作 /ð/ that /ðæt/ the /ðə/ this /ðɪs/ those /ðəʊz/ father /ˈfɑːðər/ H 在音节中与 C 组合成 ch 通常读作 /tʃ/ chat /tʃæt/ check /tʃek/ achieve /əˈtʃiːv/ chocolate /ˈtʃɒklət/ chunk /tʃʌŋ/ H 在音节中与 C 组合成的 ch 有时读作 /k/ character /ˈkærəktər/ chemistry /ˈkemɪstri/ anchor /ˈæŋkər/ ache /eɪk/ H 在音节中与 S 组合成 sh 通常读作 /ʃ/ she /ʃiː/ ship /ʃɪp/ shoe /ʃuː/ shop /ʃɒp/ shut /ʃʌt/ H 在音节中与 W 组合成 wh 通常读作 /w/ what /wɒt/ when /wen/ which /wɪtʃ/ why /waɪ/ 在上面的组合中,如果后面跟着元音字母 O,通常读作 /h/ who /huː/ whole /həʊl/ whose /huːz/ whom /huːm/ H 在音节中的组合 gh 通常读作 /f/ laugh /lɑːf/ enough /ɪˈnʌf/ rough /rʌf/ tough /tʌf/ cough /kɒf/ H 在音节中的组合 gh 也可能不发音 height /haɪt/ high /haɪ/ though /ðəʊ/ H 在音节中的组合 ph 通常读作 /f/ phase /feɪz/ phenomenon /fɪˈnɒmɪnən/ philosophy /fɪˈlɒsəfi/ physical /ˈfɪzɪkl/ photo /ˈfəʊtəʊ/ H 在音节中处于 ex 后面组成 exh 时,H 通常不发音 exhaust /ɪɡˈzɔːst/ exhibit /ɪɡˈzɪbɪt/ J 的发音规律 J 通常读作 /dʒ/ jam /dʒæm/ jet /dʒet/ jingle /ˈdʒɪŋɡl/ job /dʒɒb/ jump /dʒʌmp/ K 的发音规律 K 通常读作 /k/。 K 在音节中与 N 组合成 kn 时,K 通常不发音 这被称为 Silent K knack /næk/ knee /niː/ knife /naɪf/ know /nəʊ/ knuckle /ˈnʌkl/ L 的发音规律 L 通常读作 /l/。 在音节中位于元音后面的 l 的发音也用 /l/表示,但是一种特殊的发音方式,称为模糊 L(Dark L), 类似于呕的发音。 all /ɔːl/ well /wel/ till /tɪl/ cold /kəʊld/ bull /bʊl/ L 在音节中的处于元音 a、o、ou 和辅音 f、v、k、m 之间会产生元音化现象 talk /tɔːk/ behalf /bɪˈhɑːf/ folk /fəʊk/ walk /wɔːk/ should /ʃʊd/ would /wʊd/ calm /kɑːm/ palm /pɑːm/ M 的发音规律 M 通常读作 /m/。 N 的发音规律 mindmap((N 的发音规律)) (字母发音) /n/ (组合发音) (mn) /m/ (ng) /ŋ/ (nk) /ŋ/ N 通常读作 /n/。 N 在音节中与 M 组合成 mn 时,N 通常不发音 column /ˈkɒləm/ condemn /kənˈdem/ autumn /ˈɔːtəm/ hymn /hɪm/ N 在音节中与 G 组合成 ng 时,N 通常读作 /ŋ/ bang /bæŋ/ length /leŋθ/ sing /sɪŋ/ song /sɒŋ/ hungry /ˈhʌŋɡri/ N 在单词中后面跟着 K 时,N 通常发 /ŋ/ 的音 bank /bæŋk/ drink /drɪŋk/ donkey /ˈdɒŋki/ thunk /θʌŋk/ P 的发音规律 P 通常读作 /p/。 P 在音节中与 H 组合成 ph 时,通常读作 /f/ phase /feɪz/ phenomenon /fɪˈnɒmɪnən/ philosophy /fɪˈlɒsəfi/ physical /ˈfɪzɪkl/ photo /ˈfəʊtəʊ/ Q 的发音规律 Q 通常读作 /k/。Q 通常与 U 一起使用,读作 /kw/ quarter /ˈkwɔːtər/ queen /kwiːn/ quick /kwɪk/ quote /kwəʊt/ R 的发音规律 R 通常读作 /r/。 R 在音节中的组合 wr 通常读作 /r/ wrap /ræp/ wreck /rek/ wrist /rɪst/ wrong /rɒŋ/ wrinkle /ˈrɪŋkl/ R 在音节中的组合 rh 通常读作 /r/ rhyme /raɪm/ rhythm /ˈrɪðəm/ S 的发音规律 S 通常读作 /s/。 mindmap ((S 的发音规律)) (字母发音) /s/ /z/ (组合发音) (su) /ʃ/ (sure) /ʒər/ (sion) /ʃən/ /ʒən/ 有一些情况下,S 会发 /z/ 音 is /ɪz/ was /wɒz/ his /hɪz/ has /hæz/ S 在音节中与 U 组合成 su 时并且是重读音节时,通常读作 /ʃ/ sure /ʃʊər/ sugar /ˈʃʊɡər/ assure /əˈʃʊər/ sure 的组合通常读作 /ʒər/ measure /ˈmeʒər/ pleasure /ˈpleʒər/ treasure /ˈtreʒər/ S 在音节中与 H 组合成 sh 时,通常读作 /ʃ/ 见于 H 的发音规律 S 在音节中与 ion 组合成 sion 时,通常读作 /ʃ(ə)n/ 或 /ʒən/ vision /ˈvɪʒən/ decision /dɪˈsɪʒən/ version /ˈvɜːrʒən/ explosion /ɪkˈspləʊʒən/ confusion /kənˈfjuːʒən/ T 的发音规律 mindmap ((T 的发音规律)) (字母发音) /t/ (组合发音) (th) /θ/ /ð/ (tch) /tʃ/ (tr) /tr/ (ture) /tʃ/ (tu) /ʃ/ T 通常读作 /t/。 T 在音节中与 H 组合成 th 时,见于 H 的发音规律 thank /θæŋk/ theory /ˈθɪəri/ think /θɪŋk/ thought /θɔːt/ thumb /θʌm/ that /ðæt/ the /ðə/ this /ðɪs/ those /ðəʊz/ father /ˈfɑːðər/ T 在音节中的 ia, io 前面的 t 通常读作 /ʃ/ partial /ˈpɑːʃəl/ nation /ˈneɪʃən/ situation /ˌsɪtjʊˈeɪʃən/ action /ˈækʃən/ question /ˈkwestʃən/ T 在音节中与 U 组合成 ture 时,T 通常读作 /tʃ/ nature /ˈneɪtʃər/ picture /ˈpɪktʃər/ future /ˈfjuːtʃər/ situation /ˌsɪtʃuˈeɪʃən/ T 在音节中与 U 组合成 tu 时,T 有时读作 /ʃ/ situation /ˌsɪtʃuˈeɪʃən/ T 在音节中与 CH 组合成 tch 时,通常读作 /tʃ/ catch /kætʃ/ watch /wɒtʃ/ match /mætʃ/ stitch /stɪtʃ/ witch /wɪtʃ/ T 在音节中与 R 组合成 tr 时,通常读作 /tr/, /t/ 在这里是清音 track /træk/ train /treɪn/ tree /triː/ try /traɪ/ true /truː/ V 的发音规律 V 通常读作 /v/。 W 的发音规律 W 通常读作 /w/。 mindmap ((W 的发音规律)) (字母发音) /w/ (组合发音) (wh) /w/ (wr) /r/ (who) W 不发音 (在元音字母后面) 半元音 W 在音节中在元音后面会变成半元音(Semi-vowel)。 saw /sɔː/ nephew /ˈnɛfjuː/ cow /kaʊ/ now /naʊ/ low /ləʊ/ how /haʊ/ W 在音节中与 H 组合成 wh 时 通常读作 /w/ what /wɒt/ when /wen/ which /wɪtʃ/ why /waɪ/ W 在音节中的组合 who, W 通常不发音 who /huː/ whole /həʊl/ whose /huːz/ W 在音节中的组合 wr 时常读作 /r/,W 不发音 wrap /ræp/ wreck /rek/ wrist /rɪst/ write /raɪt/ wrong /rɒŋ/ wrinkle /ˈrɪŋkl/ X 的发音规律 X 在音节中的中间和结尾通常读作 /ks/。 box /bɒks/ six /sɪks/ mix /mɪks/ fox /fɒks/ tax /tæks/ X 在单词中与 E 组合成 xe 时,X 通常读作 /gz/。 example /ɪɡˈzɑːmpl/ exam /ɪɡˈzæm/ exact /ɪɡˈzækt/ X 在单词的起始位置通常读作 /z/。 xerox /ˈzɪərɒks/ xylophone /ˈzaɪləfəʊn/ Y 的发音规律 Y 可以作为元音字母,也可以作为辅音字母。作为元音字母时,Y 通常读作 /aɪ/ 或 /ɪ/,与 I 的发音规律类似。 作为辅音字母时,Y 通常读作 /j/。 Y 作为元音字母时并在重音节中发 /aɪ/ 的音 my /maɪ/ by /baɪ/ fly /flaɪ/ sky /skaɪ/ cry /kraɪ/ try /traɪ/ Y 作为元音字母时并在非重音节中发 /ɪ/ 的音 happy /ˈhæpi/ baby /ˈbeɪbi/ city /ˈsɪti/ family /ˈfæmɪli/ carry /ˈkæri/ Y 作为辅音字母时的发音规律 yes /jes/ yellow /ˈjeləʊ/ young /jʌŋ/ year /jɪər/ you /juː/ Z 的发音规律 Z 通常读作 /z/。 zoo /zuː/ zero /ˈzɪərəʊ/ zip /zɪp/ zone /zəʊn/ buzz /bʌz/

2024/9/9
articleCard.readMore

ESP8266EX 自动下载电路

ESP-12F 是一款集成了 ESP8266EX 芯片的模块,在 ESP-12F 上 GPIO0 引脚 在 EN 引脚上升沿(从低电平到高电平)时,如果 GPIO0 引脚为低电平,ESP-12F 将进入下载模式。 在电子设备中,EN 引脚(Enable Pin),也称为使能引脚,是一个控制信号引脚,用于控制芯片或模块的使能状态。当 EN 引脚为高电平时,芯片或模块处于工作状态;当 EN 引脚为低电平时,芯片或模块处于待机或关断状态。 所以可以用 USB 转 TTL 串口芯片通过控制 GPIO0 和 EN 引脚的电平,来实现自动下载固件和进入运行模式,而不需要增加一个下载按键。 USB 转 TTL 串口芯片 USB 转 TTL 串口芯片通常有 DTR, RTS, TXD, RXD 等引脚,其中 DTR 和 RTS 引脚则可以用来控制 ESP12F 的 GPIO0 和 EN 引脚。TXD 和 RXD 用于串口通信,下载固件时传输固件数据。 DTR: Data Terminal Ready,数据终端就绪,用于控制数据终端设备是否准备好接收数据,当 DTR 为高电平时,表示数据终端设备准备好接收数据。 RTS: Request To Send,请求发送,用于控制数据终端设备发送数据的请求,当 RTS 为高电平时,表示数据终端设备请求发送数据。 TXD: Transmit Data,发送数据,用于发送数据。 RXD: Receive Data,接收数据,用于接收数据。 自动下载电路 以 USB 转 TTL 串口芯片 CH340C 为例 GPIO0 和 EN 与 DTR 和 RTS 的连接方式如下: EN 和 GPIO0 通过两个上拉电阻连接到 VCC,默认为高电平 EN 连接一个电容,让 EN 引脚在电平变化时有一个延时 EN 连接到 NPN 三极管 Q1 的发射极 DTR 连接到 Q1 的基极 RTS 连接到 Q1 的发射极,和 DTR 共同控制 EN 的电平 GPIO0 连接到 NPN 三极管 Q2 的发射极 RTS 连接到 Q2 的基极 DTR 连接到 Q2 的发射极,和 RTS 共同控制 GPIO0 的电平 自动下载过程中电路的状态变化 初始状态 DTR 和 RTS、EN 和 GPIO0 均为高电平 Q1 和 Q2 导通 ESP-12F 处于运行模式 当我们用 esptool 开时下载固件时,esptool 会先拉低串口芯片的 RTS Q1: 维持导通 EN: 通过 Q1 连接到低电平的 RTS,被拉为低电平 Q2: 因为连接到 Q2 的基极的 RTS 为低电平,不导通 GPIO0: 维持高电平 EN 会在电容放完电之后被拉低,ESP-12F 停止工作。 然后 esptool 会拉低 DTR, 拉高 RTS Q1: 不导通 Q2: 导通 GPIO0: 通过 Q2 连接到低电平的 DTR,被拉为低电平 EN: 通过 Q1 连接到高电平的 RTS,给电容充电的同时,逐渐拉为高电平 此时 ESP-12F 进入下载模式 esptool 会让串口芯片发送固件 参考 ESP8266EX 技术规格书 CH340C 说明书 广告 本文由我在制作 E-ink Todo List 墨水屏待办 DIY 的 PCB 板时总结的,我还写了一篇《墨水屏 Todo List 制作教程》。 👋 E-ink Todo List 墨水屏待办 DIY 的 PCB 现已上架售卖 😇,此 PCB 板可代替教程中的开发板和屏幕转接板。爱好 DIY 的朋友们可以下单购买制作。 E-ink Todo List 墨水屏待办的成品正在起来的路上!!! 下面是 PCB 板的购买途径。 EsonWong 的微信小店

2024/7/7
articleCard.readMore

浅聊 esp8266

最近在做 E-ink Todo List 项目,用到了 ESP8266,所以就简单的聊一下 ESP8266。 ESP8266EX ESP8266 是由乐鑫科技推出的一个芯片系列,ESP8266EX 是其中的一款。 ESP8266EX 提供了完整 TCP/IP 协议栈和 WiFi 功能,一个 10 位 ADC,支持 SPI、I2C、UART、PWM 等接口。是一个非常适合用于做一些需要无线联网且由电池供电的项目的芯片。 ESP-12F 模组 为了快速创造我想要的东西,我使用了安可信的 ESP-12F 模组。使用 SMD 封装方式。它集成了 ESP8266EX 芯片,WiFi 天线和外部闪存的模组。 SMD 是 Surface-Mounted Device(表面贴装设备)的缩写。起源于 1960 年代,最初由美国 IBM 公司进行技术研发,之后于 1980 年代后期渐趋成熟。它的特点是元件直接贴装在电路板的表面,而不需要通过电路板的孔进行焊接。这种封装方式使得元件可以更小,更轻,而且可以在电路板的两面进行贴装。SMD0805 和 SMD0603 是常见的 SMD 封装规格,0805 封装的尺寸是 0.08 英寸 x 0.05 英寸( 2.0mm x 1.25mm),0603 封装的尺寸是 0.06 英寸 x 0.03 英寸(1.6mm x 0.8mm)。 ESP-12F 是特殊尺寸的 SMD 封装。 固件下载 项目中用了 USB 转 TTL 串口芯片 CH340C 通过下面的引脚来实现自动下载固件和进入运行模式。 ENABLE 使能引脚,当使能引脚为高电平时,芯片或模块处于工作状态;当使能引脚为低电平时,芯片或模块处于待机或关断状态。 GPIO0(FLASH) 用于控制 ESP8266EX 进入下载模式。当 GPIO0 为低电平时, 让 ENABLE 引脚上升沿(从低电平到高电平)时,ESP8266EX 将进入下载模式。当 ESP8266EX 处于运行模式时,GPIO0 引脚可作为普通的输入输出引脚使用。 GPIO1(TX) UART 通用串口通讯的接收引脚 GPIO3(RX) UART 通用串口通讯的接收引脚 我会单独写一篇文章详细介绍自动下载电路的原理。 SPI 电路 SPI(Serial Peripheral Interface) 是一种芯片与芯片的外围设备通信协议。需要用到 4 条线路,分别是: SCK(Serial Clock) 串行时钟信号,由主设备产生,用于对齐数据传输的间隔。 MOSI(Master Out Slave In) 主设备输出,从设备输入,主设备发送数据到从设备。 MISO(Master In Slave Out) 主设备输入,从设备输出,从设备发送数据到主设备。 SS(Slave Select) 或 CS(Chip Select) 从设备选择信号,由主设备产生,用于选择从设备。 我在项目中使用 SPI 通信方式与 E-ink 屏幕通信。除了上面的 4 条线路外,还用要控制 E-ink 屏幕的复位,以及读取 E-ink 屏幕是否忙碌的状态。 我在 ESP-12F 上使用了下面的引脚: ESP-12FE-ink 驱动电路功能 GPIO2RST控制屏幕复位的引脚,低电平复位屏幕 GPIO4DC控制引脚屏幕的数据和命令模式,高电平表示数据,低电平表示命令 GPIO5BUSY屏幕忙碌状态输出引脚,高电平表示屏幕忙碌,低电平表示屏幕空闲 GPIO13(MOSI)DINSPI 通信 MOSI 引脚 GPIO14(SCK)CLKSPI 通信 SCK 引脚 GPIO15(CS)CSSPI 片选引脚 ADC 引脚 ESP-12F 有一个 10 位 ADC,可以用来读取模拟量信号。我将会用这个引脚来读取电池电压。ADC0 引脚可读取 0-1V 的电压。需要使用一个电阻分压电路将电池电压分压到 0-1V 范围内再通过 ADC0 引脚读取。 编程平台 ESP8266EX 的开发环境有很多,我选择了 PlatformIO。一开始我是使用 Arduino IDE 来开发的,但是 Arduino IDE 的功能太过简单,不适合太复杂的项目。 我使用 VSCode 安装了 PlatformIO 插件,通过 PlatformIO 的 CLI 工具来编译和下载固件。 参考 ESP8266EX ESP-12F 广告 本文由我在制作 E-ink Todo List 墨水屏待办 DIY 的 PCB 板时总结的,我还写了一篇《墨水屏 Todo List 制作教程》。 👋 E-ink Todo List 墨水屏待办 DIY 的 PCB 现已上架售卖 😇,此 PCB 板可代替教程中的开发板和屏幕转接板。爱好 DIY 的朋友们可以下单购买制作。 E-ink Todo List 墨水屏待办的成品正在起来的路上!!! 下面是 PCB 板的购买途径。 EsonWong 的微信小店

2024/6/2
articleCard.readMore

墨水屏 Todo List 制作教程

.post-body img { max-height: 800px;} window.difyChatbotConfig = { token: 'gc7zMgtbwd6BAygx', baseUrl: 'https://dify.esonwong.com' } #dify-chatbot-bubble-button { background-color: #1C64F2 !important; } #dify-chatbot-bubble-window { width: 24rem !important; height: 40rem !important; } 我在 Twitter 发布的一条 tweet,写了我使用了墨水屏制作了一个 Todo List,可以同步苹果提醒的全家待办列表。收到了很多推友的关注,所以我决定写一个教程,帮助大家制作一个墨水屏 Todo List。 同步服务由我开发的 einktodo.com 提供。 同步苹果提醒的全家待办列表 创造真的令人感到愉快 https://t.co/guVXon73n5 pic.twitter.com/Rb9Fg3fUP7 — Eson Wong (@eson000) January 15, 2024 更新记录 2024-04 支持了滴答清单的同步 对成品感兴趣吗? 我正在尝试将墨水屏 Todo List 制作成产品,如果你对这个产品感兴趣,可以在前往 einktodo.com 加入行等待邮件列表,你将会收到产品制作的最新进度信息。 如果你对 E-ink Todo List DIY 也有兴趣和有意购买 DIY 电路板、DIY 套件、3D 打印版原型机,欢迎加入交流微信群。添加 EsonWong_ 微信号,备注E-ink Todo List 加入。也可以关注我的 X(Twitter) @eson000 。 广告 Eson 的淘宝小店 E-ink Todo List 3D 打印版已经上架 售卖 😇 E-ink Todo List 墨水屏待办 DIY 的 PCB 现已在 Eson 的淘宝小店 上架售卖 😇 E-ink Todo List 墨水屏待办 DIY 的外壳也已经在 Eson 的淘宝小店 开始售卖 Eson 的闲鱼小店 👋 E-ink Todo List 墨水屏待办 DIY 的 PCB 现已在 Eson 的闲鱼小店 上架售卖 😇,此 PCB 板可代替教程中的开发板和屏幕转接板。爱好 DIY 的朋友们可以下单购买制作。 👋 E-ink Todo List 墨水屏待办 DIY 的外壳也已经在 Eson 的闲鱼小店 开始售卖 👋 E-ink Todo List 墨水屏待办的成品 3D 打印版也已经在 Eson 的闲鱼小店 开始售卖 下面开始制作墨水屏 Todo List 的教程。 必要材料和工具 材料 ESP8266/ESP32 开发板 24 pin 墨水屏驱动板 微雪 7.5 寸 800*480 分辨率墨水屏 注意: 开源固件已经放弃对 ESP32 的支持。 微雪 7.5 寸墨水屏可以在网上找到拆机屏,也可以买新的。注意要买 800x480 分辨率的。 墨水屏驱动板在闲鱼搜索墨水屏驱动板,买 24 pin 的通用驱动板。 或者 上文中售卖的 E-ink Todo List 墨水屏待办 DIY PCB 微雪 7.5 寸 800*480 分辨率墨水屏 E-ink Todo List 墨水屏待办 DIY PCB 可以代替开发板和墨水屏驱动板。 工具 电烙铁 电脑 注:如果你购买了 E-ink Todo List 墨水屏待办 DIY 的 PCB,则不需要电烙铁来焊接。 制作步骤 1. 焊接转接板和 ESP8266 开发板 将墨水屏驱动板按下面的表格对应的脚位连接到 ESP8266 开发板上。 墨水屏驱动板ESP8266 开发板 VCC3.3V GNDGND SDAPin 14 SCKPin 13 CSPin 15 DCPin 4 RSTPin 2 BUSYPin 5 将墨水屏的 FPC 排线连接到墨水屏驱动板。 注意:排线的正反面。这个 FPC 排线端子的触点是在上面的,所以排线的触点朝上。我在第一次尝试点亮墨水屏的时候,就因为排线插反了,当时信心受到了极大的打击。 2. 安装固件编译和刷写环境 下载 VSCode,并安装。 安装好 VSCode 后,打开 VSCode,点击左侧的扩展按钮,搜索 PlatformIO,点击安装。 3. 下载代码 然后从 E-ink Todo List 固件代码开源仓库 下载固件代码。 点击右上角的绿色按钮,选择Download ZIP。下载完成后解压得到固件代码文件夹。 4. 编译和烧录固件 用 VSCode 打开固件代码文件夹。 选择固件代码文件夹, PlatformIO 插件会自动安装编译固件所需依赖。 将开发板用 USB 线连接到电脑。 编译和烧录固件到开发板。 在 VSCode 上点击蚂蚁头形状的PlatformIO菜单来打开 PlatformIO 的面板。 如果你用的是 E-ink Todo List 墨水屏待办 DIY 的 PCB,选择 Einktodo-开头的环境下的 General -> Upload and Monitor 具体选哪个根据你的屏幕的型号来选择。比如是微雪 7.5 寸 800x480 分辨率的屏幕,选择 E-inktodo-Waveshare-750-W800 -> General -> Upload and Monitor 如果你使用的是 ESP8266 开发板,选择 esp8266 -> General -> Upload and Monitor 等待烧录完成。 墨水屏 Todo List 设置 在 einktodo.com 获取 API Token 登录 einktodo.com。 在 API Key 页面 创建 API Key。 设置墨水屏 Todo List 固件编译和烧录完成,墨水屏上会提示你连接墨水屏的热点和热点密码,接下来要连接热点进行设置。 连接墨水屏 Todo List 的 Wi-Fi: E-ink Todo List AP,密码: einktodo.com。 打开浏览器,进入墨水屏上显示的设置页面。 设置墨水屏要连接的 Wi-Fi 网络和要使用的 API Token。 点击Configure WiFi按钮进入设置页面。然后选择你想要让默水屏连接的 Wi-Fi 或在 SSID 输入框里输入 Wi-Fi 名。在 Password 输入框里输入这个 Wi-Fi 的密码。在 API Key 输入框里输入刚刚在 einktodo.com 获取的 API Key。 点击Save按钮。 墨水屏 Todo List 会自动重启并尝试连接 Wi-Fi。如果没有开始连接,你可以按 Reset 按钮重启 ESP32 开发板来触发连接。注意保持 Wi-Fi 信号良好。 如果尝试连接 3 次没有成功,墨水屏将会重新打开 Wi-Fi 热点,你可以重新连接 Wi-Fi 进行设置。 如果你使用 E-ink Todo List 墨水屏待办 DIY 的 PCB,长按靠近 USB 接口的按键也可以重新进入设置页面。 使用 E-ink Todo 同步助手同步苹果提醒 E-ink Todo 同步助手 beta 版已经发布,可以在 TestFlight 下载 E-ink Todo 同步助手 下载。 使用快捷指令同步苹果提醒 推荐使用 E-ink Todo 同步助手替代快捷指令来同步苹果提醒。 同步的 Todo List 目前支持苹果的提醒事项应用。其它常用的待办应用将来会逐步集成到 einktodo.com。 安装和配制快捷指令 点击下面的链接在 iPhone 上安装Sync Einktodo.com快捷指令。 Sync Einktodo.com 快捷指令 在 Safari 中打开上面的链接,点击获取捷径。 点击添加快捷指令。 添加完之后,找到 Sync Einktodo.com 快捷指令,点击它上面的...按钮,进入编辑界面。 在Sync Einktodo.com快捷指令中的文本块中输入刚刚在 einktodo.com 获取的 API Key。 按完成保存快捷指令。 设置快捷指令自动化 在快捷指令自动化中,设置打开或关闭“提醒事项”应用时运行此快捷指令来同步待办。 打开快捷指令应用,点击自动化 Tab 点击+按钮创建自动化, 选择App,点击下一步。 设置为打开或关闭 提醒事项应用时运行快捷指令 App 那一项选择提醒事项,勾选打开或关闭,并选择立即执行,然后点击下一步。 选择Sync Einktodo.com快捷指令。 这样设置后,当你打开或关闭提醒事项应用时,快捷指令会自动同步待办到墨水屏 Todo List。 允许快捷指令访问提醒事项 当你第一次触发这个自动化时,系统会提示你允许快捷指令将提醒事项应用的数据发送到 einktodo.com,点击始终允许

2024/3/9
articleCard.readMore

2023 年我买过的最好用的商品

我在 2022 的年末写了一篇文章 2022 年我买过的最好用的商品,介绍了我 2022 年购入的我觉得最好用的商品。 在这个中文互联网自媒体觉大多数都依赖厂家推广费存活的时代,看到真实的商品评价越来越难。所以我打算每年年末都写一篇这样的文章,介绍我买过的那些我觉得好用或者每天者在使用的商品。让中文互联网上多一丝丝真实消费者的声音。 这是我 2023 年购入的值得推荐的产品: Aqara 人体存在传感器 FP2 淘宝的 Apple Watch 高山回环 表带 iPad 通勤包 田宫 1 比 10 比例的电动越野车 BBX Aqara 人体存在传感器 FP2 买了房子之后我就加大了智能家居的折腾力度。在 2022 年我买过的最好用的商品 中我推荐了 Aqara 的窗帘伴侣。今年他们家的毫米波人体传感器发布了第二代,我买了一个试了水。 在使用它之前我用了 4 个红外人体传动作传感器。红外动作人体传感器的缺点是,如果你在房间里不动它就会认为房间里没人。我以前用它们用它们控制灯的开关,在上厕所和其它动作幅度不大的场景下会关灯,导致我常被我家人吐槽。红外人体传感器不适合在家居场景下使用。 购入 Aqara 人体存在传感器 FP2 是我认为毫米波人体传感器经过了几年的发展也差不多成熟了。体验下来它有超出我预期的地方,也有让我对 Aqara 的做法及其失望的地方。 超出预期的地方有: 它可以在 Aqara App 里去给监测空间划分区域并同步到 HomeKit 里。 可以多长时间某个区域有人或无人时触发 Aqara App 内的自动化。 缺点: Aqara 有意的让他们家的设备无法在其它智能家居平台上触发自动化。 表面上看 Aqara 表现的很开放,几乎所有的设备都支持 HomeKit。但实际上 FP2 上的包含时间限制的触发自动化功能只能在 Aqara App 里使用。Aqara 既不开放 API(无法通过 HomeBridge 接入 HomeKit),也不能通过什么场景控制等其它方式绕过限制。 安装问题 毫米波人体传感器设备不是低功耗设备,所以它需要接入电源。所以只能选择安装在有电源的地方或者为它拉电源线。而且安装的高度也有要求,不能太高也不能太低。安放它有些麻烦。 识别准确度 识别不能达到 100% 的准确度,有时候会有误判。之前我把它安装在电风扇附近,电风扇的转动会让它误判有人在房间里,我不得不把它移到其它地方。更新的 AI 预测干扰在一定程度上优化了这个问题。但是最近我并没有使用风扇,灯到天所热一些之后才能再次验证这个问题是否解决。 综合考虑对智能家居的自动化提升程度和可接受的准确度,我又买了 3 个 FP2,分别安装在两个卧室和洗手间。目前家中大多数的灯都可以在合适的时候自动打开和关闭了。 我的购买渠道是咸鱼,因为 Aqara 对线上渠道的价格有保护,所以在咸鱼上才能以正常价格买到。 淘宝的 Apple Watch 高山回环 表带 去年买了 Apple Watch Series 7,到现在使用了原装运动表带,淘宝上买的海洋回环、高山回环、和野径回环表带。最后高山回环表带是我最常用的表带。 它的优点是:弹性效适中,带着不晃动。透气,不会让手腕潮湿。比较薄,让我可以在晚上睡觉的时候戴着 Apple Watch,在穿长袖厚衣服的时候也最小限度的影响到了 Apple Watch 的佩戴。 这个表带不耐脏,最好买深色的。 iPad 通勤包 我使用的是 11 寸的 iPad,日常通勤的时候我会带着它在地铁上看书学习英语。为了方便拿取,以及在过地铁安检的时候不用过安检,我找了很久才找到这个包。它刚好能装下我的 iPad,不会感到太累赘。带有磁吸扣的设计,让我在进地铁的可以方便的打开给安检人员看,避免过安检机。使用 iPad 的时候也也以快速的拿出来。 但是价格在我看来略贵。 还有一个非常让人不爽的问题是挂带子的金属件容易掉漆,我要想办法把它们换掉。 田宫 1 比 10 比例的电动越野车 BBX 今年入手的玩具车,和我以前喜欢玩的游戏 PUBG《绝地求生》中的越野车“蹦蹦”同款。它的对地形的要求很低,哪里都可以玩。 不过价格有点贵,组装也有点麻烦。如果手残的话建议闲鱼上买成品车。

2024/1/29
articleCard.readMore

转变自我的密码:《Atomic Habits》读后感

在我们的生活里,习惯就像是无声的指挥官,默默地引导着我们的行动和选择。在《Atomic Habits》这本书中,詹姆斯·克利尔(James Clear)用他洞见卓识的笔触,展现了如何通过习惯的力量来雕塑更好的自我。这本书不仅是养成好习惯的指南,更是一部自我改革的宝典,它教会我们将小变化累加成巨大的成果。 作者简介 作者詹姆斯·克利尔,一个以自己的转变故事激励人们追求强大个人习惯的灵魂导师。通过在个人发展领域中的不懈努力和深刻的思考,他不仅在书籍的篇章中分享了他的智慧,也在他的网站和各类讲座中,持续地影响着那些渴望改变的灵魂。 习惯为什么如此重要 书中明示,习惯是我们日常决策的结果,它们定义了我们的效能和最终能达到的高度。我们之所以被困在不满的迷宫,很大程度源于那些未经意识审视的自动行为。因为习惯一旦养成,在无意识的驱动下,就会反复执行而不易察觉。 培养习惯的三层追求 克利尔在书中提出,培养习惯不仅是为了达成目标,更是为了雕塑身份。那种“我是谁”的信念,影响着我们的选择和行为。比如我自身的经历,将发布 iOS 应用视为过程而非一次性目标,还有每天阅读 15 分钟的习惯,正是这种理念的反映。 习惯的四大定律 书里提到的四大定律,为我们提供了改变习惯的明确路径。 让期望的习惯变得更加看得见、难以忽视 我们的大脑趋向于自动反应日常环境中的线索。通过创建显眼的触发器,如备好健身包放在门口,我们就构筑了迈向健身房的第一步。类似方法可以用于任何我们想要建立的习惯。 让习惯变得更有吸引力 积极的感觉是维持习惯的关键因素。我们可以把习惯与自己喜爱的活动关联起来,比如在跑步机上听喜爱的播客,以此增强坚持的动力。 让习惯变得更简单 降低好习惯的入门门槛至关重要。比如要养成早起的习惯,可以先从调早闹钟五分钟做起。而同时,增加不良习惯的难度,就像删除手机上的社交媒体应用,以避免不必要的干扰。 让习惯变得更有满足感 适当的即时奖励可以巩固好习惯。每当完成一项任务后给予自己奖励,无论是一杯咖啡还是一个小时的电视时间,都能够加强我们的积极反馈回路。 行动指南 书籍最终落脚在如何实践。制定一个鲜明的计划,如何每天写博客、读书、运动,然后根据习惯的四大定律将计划付诸行动。重要的是,要让这些活动符合你的身份认同,让自己真正相信“我是一个写作者”,“我是一个爱读书的人”,“我是一个健身者”。 结语 《Atomic Habits》不仅是一本关于习惯的书,它是一张改变生活的地图。詹姆斯·克利尔回答了我们在寻求进步路上的那些困惑,他用科学的方法和真实的故事,指引我们向着更好的自己前进。现在,是时候把这些理念应用于实践,开始自我改革的旅程了!

2023/11/30
articleCard.readMore

Phonics 自然拼读常见规则 - 音节和元音字母的发音规律

自然拼读法是通过英语中的音节和音素之间的关系,根据这些规则正确地发音和拼写单词的方法。通过自然拼读法,学习者可以更轻松地理解和记忆英语单词的发音,提高阅读流畅性和拼写准确性。 重读开音节重读闭音节非重读音节 A/eɪ//æ//ə/ E/iː//e//ə/ or /ɪ/ I/aɪ//ɪ//ə/ or /ɪ/ O/əʊ//ɒ//ə/ U/juː//ʌ//ə/ 辅音字母的拼读规则见我的另一篇博客 Phonics 自然拼读常见规则 - 辅音字母的发音规律。 音节 什么是音节 音节是发音的基本单位,是一个发音的完整单位。音节的划分对于一个单词的读音至关重要,自然拼读的规律基本上是针对单个音节的。 一个音节,只会包含一次出气,出气时的声带的振动被称为元音;牙齿、舌头、嘴唇等部位的阻碍气流发出的声音被称为辅音。 音节由一个元音或一个元音加一个或几个辅音组成。中文里每个字都是一个音节。英文里每个单词会有一个或多个音节。 (adsbygoogle = window.adsbygoogle || []).push({}); 元音 元音是发音时,舌头不接触上下牙齿,不接触嘴唇的音。通常元音发音时,气流从喉咙出来,通过口腔或鼻腔,不受阻碍,形成的音。 比如:cat /kæt/ 中的 /æ/ 是一个元音。 短元音:/æ/、/e/、/ɪ/、/ɒ/、/ʌ/、/ʊ/、/ə/ 长元音:/iː/、/ɑː/、/ɔː/、/ɜː/、/uː/、/ɔɪ/、/aɪ/、/eɪ/、/aʊ/、/əʊ/、/ɪə/、/eə/、/ʊə/ 辅音 辅音是发音时,舌头接触上下牙齿,接触嘴唇的音。通常辅音发音时,气流在口腔、鼻腔或咽头受阻碍而形成的音。 比如:cat /kæt/ 中的 /k/ 和 /t/ 是辅音。 辅音:/b/、/d/、/f/、/g/、/h/、/j/、/k/、/l/、/m/、/n/、/ŋ/、/p/、/r/、/s/、/ʃ/、/t/、/tʃ/、/θ/、/ð/、/v/、/w/、/z/、/ʒ/ 一个音节中,必须有一个元音,可以有一个辅音或几个辅音,但是不能有一个以上的元音。 音节类型 开音节 开音节(open syllable)是一种音节类型。在开音节中,音节的末尾是一个元音字母,即元音字母后面没有紧跟的辅音字母。 开音节的特征: 音节末尾是元音字母。 元音字母后面没有紧跟的辅音字母。 元音字母通常发字母本身的发音。 开音节单词的例子: go /goʊ/ me /mi:/ hi /haɪ/ so /soʊ/ flu /flu:/ 词内开音节的例子: table /ˈteɪ.bəl/ 中的 ta /teɪ/ open /ˈoʊ.pən/ 中的 o /oʊ/ remote /rɪˈmoʊt/ 中的 re /rɪ/ tiger /ˈtaɪ.ɡɚ/ 中的 ti /taɪ/ baby /ˈbeɪbi/ 中的 ba /beɪ/ 和 bi /biː/ computer /kəmˈpjuːtər/ 中的 pu /pjuː/ 相对开音节 音节后面是一个辅音字母加上不发音的 e,前面这个音节叫做相对开音节。 如: bite /baɪt/ 中的 bi /baɪ/ cake /keɪk/ 中的 ca /keɪ/ cute /kjuːt/ 中的 cu /kjuː/ fine /faɪn/ 中的 fi /faɪ/ remote /rɪˈmoʊt/ 中的 mo /moʊ/ 闭音节 闭音节(closed syllable)是由辅音结尾的音节。 如: cat /kæt/ bed /bed/ big /bɪɡ/ fish /fɪʃ/ seven /ˈsevən/ 中的 ven /vən/ 重读音节 一个单词中重读的音节,音标中用'表示 比如: about /əˈbaʊt/ 中的 bout /‘baʊt/ again /əˈɡen/ 中的 gain /‘ɡen/ banana /bəˈnɑːnə/ 中的 na /‘nɑː/ 次重读音节 一个单词中次重读的音节,音标中用ˌ表示 比如: chinese /ˌtʃaɪˈniːz/ 中的 chi /ˌtʃaɪ/ information /ˌɪnfərˈmeɪʃn/ 中的 in /ˌɪn/ understand /ˌʌndərˈstænd/ 中的 un /ˌʌn/ 字母的发音常见规则 下面是自然拼读的常见规则,并不是所有的单词都符合这些规律,仅列出常见的规律。 元音字母的发音 重读重读重读重读重读非重读 单个元音单个元音单个元音与 re 组合与 er 组合单个元音 开音节相对开音节闭音节 A/eɪ/ baby/eɪ/ make/æ/ cat/ɑː/ arm/eə/ care/ə/ about E/iː/ be/iː/ theme/e/ bed/ɜː/ her/ɪə/ here/ə/ the /ɪ/ basket I/aɪ/ hi/aɪ/ bite/ɪ/ sit/ɜː/ bird/aɪə/ fire/ə/ pencil /ɪ/ rabbit O/əʊ/ go/əʊ/ home/ɒ/ hot/ɔː/ born/ɔː/ bore/ə/ today/ U/juː/ july/juː/ cube/ʌ/ cup/ɜː/ burn/jʊə/ cure/ə/ until 字母 Y 有时候等同于元音字母 I。 单个元音字母在重读开音节中的发音 单个元音字母在重读音节里读字母本身的发音。 AEIOU /eɪ//iː//aɪ//əʊ//juː/ 如: baby /ˈbeɪbi/ be /biː/ hi /haɪ/ my /maɪ/ go /gəʊ/ july /dʒuːlaɪ/ 单个元音字母在重读相对开音节中的发音 相对开音节中的元音字母也是字母本身的发音。 比如: A bate /beɪt/ cake /keɪk/ date /deɪt/ face /feɪs/ gate /geɪt/ hate /heɪt/ lake /leɪk/ make /meɪk/ name /neɪm/ E these /ðiːz/ theme /θiːm/ scene /siːn/ gene /dʒiːn/ I bike /baɪk/ bite /baɪt/ file /faɪl/ fine /faɪn/ hide /haɪd/ like /laɪk/ mile /maɪl/ mine /maɪn/ nine /naɪn/ pipe /paɪp/ ride /raɪd/ rice /raɪs/ side /saɪd/ site /saɪt/ time /taɪm/ wide /waɪd/ wife /waɪf/ wine /waɪn/ Y byte /baɪt/ type /taɪp/ style /staɪl/ rhyme /raɪm/ O bone /bəʊn/ code /kəʊd/ hole /həʊl/ home /həʊm/ hope /həʊp/ joke /dʒəʊk/ note /nəʊt/ pole /pəʊl/ role /rəʊl/ rose /rəʊz/ rope /rəʊp/ vote /vəʊt/ U cute /kjuːt/ cube /kjuːb/ huge /hjuːdʒ/ June /dʒuːn/ mute /mjuːt/ tube /tjuːb/ 单个元音字母在重读闭音节中的常见发音 AEIOU /æ//e//ɪ//ɒ//ʌ/ A /æ/ bad /bæd/ bag /bæg/ bat /bæt/ black /blæk/ back /bæk/ cap /kæp/ cat /kæt/ dad /dæd/ fat /fæt/ flag /flæg/ glad /glæd/ hat /hæt/ jam /dʒæm/ lap /læp/ mad /mæd/ map /mæp/ pack /pæk/ pan /pæn/ pat /pæt/ plan /plæn/ sad /sæd/ sack /sæk/ tag /tæg/ tan /tæn/ tap /tæp/ E /e/ bed /bed/ bell /bel/ check /tʃek/ deck /dek/ egg /eg/ end /end/ fell /fel/ fed /fed/ get /get/ help /help/ jet /dʒet/ kept /kept/ I /ɪ/ big /bɪg/ bin /bɪn/ bit /bɪt/ bill /bɪl/ chip /tʃɪp/ dig /dɪg/ fill /fɪl/ fit /fɪt/ hill /hɪl/ hit /hɪt/ ill /ɪl/ kid /kɪd/ kit /kɪt/ lip /lɪp/ list /lɪst/ mill /mɪl/ mix /mɪks/ pick /pɪk/ pig /pɪg/ pill /pɪl/ pin /pɪn/ pit /pɪt/ ship /ʃɪp/ sick /sɪk/ sit /sɪt/ skill /skɪl/ skin /skɪn/ slip /slɪp/ spin /spɪn/ stick /stɪk/ still /stɪl/ swim /swɪm/ thin /θɪn/ tick /tɪk/ tip /tɪp/ trip /trɪp/ twin /twɪn/ win /wɪn/ will /wɪl/ O /ɒ/ box /bɒks/ clock /klɒk/ dog /dɒg/ doll /dɒl/ dot /dɒt/ fog /fɒg/ fox /fɒks/ got /gɒt/ hot /hɒt/ job /dʒɒb/ lock /lɒk/ lot /lɒt/ mom /mɒm/ mop /mɒp/ not /nɒt/ odd /ɒd/ off /ɒf/ on /ɒn/ ox /ɒks/ pot /pɒt/ rock /rɒk/ rod /rɒd/ sock /sɒk/ stop /stɒp/ top /tɒp/ U /ʌ/ bush /bʊʃ/ bug /bʌg/ bun /bʌn/ bus /bʌs/ but /bʌt/ cup /kʌp/ cut /kʌt/ duck /dʌk/ dull /dʌl/ fun /fʌn/ 元音字母与 r 组合在重读音节中的常见发音 arerirorur /ɑː//ɜː//ɜː//ɔː//ɜː/ ar /ɑː/ arm /ɑːm/ art /ɑːt/ car /kɑː/ er /ɜː/ her /hɜː/ term /tɜːm/ verb /vɜːb/ ir /ɜː/ bird /bɜːd/ dirt /dɜːt/ shirt /ʃɜːt/ or /ɔː/ born /bɔːn/ corn /kɔːn/ fork /fɔːk/ form /fɔːm/ horn /hɔːn/ north /nɔːθ/ pork /pɔːk/ short /ʃɔːt/ sort /sɔːt/ storm /stɔːm/ torn /tɔːn/ worn /wɔːn/ ur /ɜː/ burn /bɜːn/ burst /bɜːst/ church /tʃɜːtʃ/ fur /fɜː/ hurt /hɜːt/ nurse /nɜːs/ purse /pɜːs/ turn /tɜːn/ turtle /tɜːtl/ urge /ɜːdʒ/ 元音字母与 re 组合在重读音节中的常见发音 areereireoreure /eə//ɪə//aɪə//ɔː//jʊə/ are /eə/ care /keə/ share /ʃeə/ ere /ɪə/ here /hɪə/ mere /mɪə/ sphere /sfɪə/ ire /aɪə/ fire /faɪə/ hire /haɪə/ wire /waɪə/ ore /ɔː/ core /kɔː/ more /mɔː/ store /stɔː/ ure /jʊə/ cure /kjʊə/ pure /pjʊə 单个元音字母在非重读音节中的发音 AEIOU /ə//ə/ or /ɪ//ə/ or /ɪ//ə//ə/ A /ə/ about /əˈbaʊt/ again /əˈɡen/ ago /əˈɡəʊ/ alone /əˈləʊn/ along /əˈlɒŋ/ among /əˈmʌŋ/ around /əˈraʊnd/ away /əˈweɪ/ banana /bəˈnɑːnə/ E /ə/ or /ɪ/ the /ðə/ basket /ˈbɑːskɪt/ blanket /ˈblæŋkɪt/ I /ə/ or /ɪ/ animal /ˈænɪməl/ pencil /ˈpensəl/ possible /ˈpɒsəbl/ rabbit /ˈræbɪt/ ticket /ˈtɪkɪt/ visit /ˈvɪzɪt/ O /ə/ bottom /ˈbɒtəm/ today /təˈdeɪ/ tomorrow /təˈmɒrəʊ/ U /ə/ until /ənˈtɪl/ upon /əˈpɒn/ suppose /səˈpəʊz/ support /səˈpɔːt/ supply /səˈplaɪ/ 常见元音字母组合的发音 字母 A 的元音组合 ai ay /eɪ/ ai ay /eɪ/ aim /eɪm/ aid /eɪd/ daily /ˈdeɪli/ day /deɪ/ fail /feɪl/ gain /ɡeɪn/ mail /meɪl/ pain /peɪn/ rain /reɪn/ sail /seɪl/ tail /teɪl/ wait /weɪt/ way /weɪ/ 字母 E 的元音组合 eaeeey eiereir /iː/ \ /e//iː//eɪ//ɜː//eə/ ea /iː/ beach /biːtʃ/ bean /biːn/ beat /biːt/ cheap /tʃiːp/ clean /kliːn/ cream /kriːm/ dream /driːm/ ea /e/ (在重读闭音节中) bread /bred/ dead /ded/ head /hed/ lead /led/ read /red/ spread /spred/ ee /iː/ bee /biː/ beef /biːf/ deep /diːp/ feel /fiːl/ feet /fiːt/ free /friː/ green /ɡriːn/ keep /kiːp/ meet /miːt/ need /niːd/ queen /kwiːn/ see /siː/ seed /siːd/ sleep /sliːp/ speed /spiːd/ street /striːt/ sweet /swiːt/ tree /triː/ week /wiːk/ wheel /wiːl/ ei ey /eɪ/ beige /beɪʒ/ eight /eɪt/ they /ðeɪ/ grey /ɡreɪ/ hey /heɪ/ obey /əˈbeɪ/ er /ɜː/ her /hɜː/ verb /vɜːb/ eir /eə/ or /ɪə/ heir /eə/ their /ðeə/ there /ðeə/ weird /wɪəd/ 字母 I 的元音组合 ie /iː/ ie /iː/ chief /tʃiːf/ field /fiːld/ piece /piːs/ thief /θiːf/ yield /jiːld/ 字母 O 的元音组合 oaoeoi oyooou /əʊ//əʊ//ɔɪ//uː//aʊ/ oa /əʊ/ boat /bəʊt/ coat /kəʊt/ goat /ɡəʊt/ load /ləʊd/ road /rəʊd/ soap /səʊp/ toad /təʊd/ toast /təʊst/ throat /θrəʊt/ oe /əʊ/ doe /dəʊ/ foe /fəʊ/ hoe /həʊ/ toe /təʊ/ woe /wəʊ/ oi oy /ɔɪ/ boy /bɔɪ/ boil /bɔɪl/ coin /kɔɪn/ join /dʒɔɪn/ noise /nɔɪz/ point /pɔɪnt/ soil /sɔɪl/ toy /tɔɪ/ voice /vɔɪs/ oo /uː/ or /ʊ/ boot /buːt/ cool /kuːl/ food /fuːd/ fool /fuːl/ good /ɡʊd/ hood /hʊd/ hook /hʊk/ look /lʊk/ moon /muːn/ noon /nuːn/ pool /puːl/ root /ruːt/ soon /suːn/ stood /stʊd/ took /tʊk/ tool /tuːl/ wood /wʊd/ wool /wʊl/ ou /aʊ/ about /əˈbaʊt/ cloud /klaʊd/ count /kaʊnt/ doubt /daʊt/ found /faʊnd/ ground /ɡraʊnd/ house /haʊs/ loud /laʊd/ mouth /maʊθ/ mouse /maʊs/ out /aʊt/ pound /paʊnd/ round /raʊnd/ shout /ʃaʊt/ south /saʊθ/ sound /saʊnd/ town /taʊn/ trout /traʊt/ vowel /ˈvaʊəl/ wound /wuːnd/ 字母 U 的元音组合 ueui /uː//uː/ ue /uː/ blue /bluː/ clue /kluː/ due /duː/ glue /ɡluː/ true /truː/ ui /u:/ fruit /fruːt/ juice /dʒuːs/ suit /suːt/ 辅音字母的常见发音 见 Phonics 自然拼读常见规则 - 辅音字母的发音规律。

2023/10/28
articleCard.readMore

怎么用 Github Actions 部署 Next.js 项目到服务器

最近开发一个项目 Next.js,部署到 Vercel 上在国内访问速度和稳定性都不太好,所以想部署到自己的服务器上。经过实践后,分享一下怎么用 Github Actions 部署 Next.js 项目到 Linux 服务器上。 服务器环境配置 在服务器要安装 Node.js 和 PM2,然后配置 Nginx。 安装 Node.js 推荐使用 fnm 来安装 Node.js,以后可以方便的使用不同版本的 Node.js。 1 curl -fsSL https://fnm.vercel.app/install | bash 安装好后重新 SSH 连接到服务器终端,用 fnm 安装 Node.js。 1 fnm install 18 安装 PM2 我们使用 PM2 来管理 Node.js 进程。以便在服务器重启后自动启动项目。 用 npm 安装 PM2: 1 npm install pm2 -g Nginx 配置 Node.js 项目默认运行在 3000 端口,我们使用 Nginx 来反向代理到 3000 端口。这样就可以使用 80 或 443 端口来访问项目。 在 nginx 配置文件夹 /etc/nginx/sites-available 中创建一个配置文件 example.com: 1 2 3 4 5 6 7 8 9 10 11 12 server { listen 80; server_name example.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } } 然后在 sites-enabled 文件夹中创建一个软链接。 1 sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com 然后重新加载 Nginx 配置文件: 1 sudo nginx -s reload 生成 SSL 证书 安装 certbot 来生成证书并修改 Nginx 配置文件以使用证书。 生成证书: 1 sudo certbot --nginx 命令执行后会提示输入邮箱,然后选择同意条款,最后选择要生成证书的域名,然后就会自动的生成证书并修改 Nginx 配置文件和重新加载。 代码拉取 SSH 密钥配置 生成 SSH 密钥 把公钥添加到 Github 仓库的 Deploy keys 中 把私钥到放到服务器的用于发布项目的用户的 ~/.ssh/id_rsa 路径,以便 Github Actions 用 SSH 连接服务器拉取 Github 上的代码。 1 echo "private-key" >> ~/.ssh/id_rsa Github Actions 配置 我们使用 appleboy/ssh-action@master 这个 Github Action 用 ssh 来连接服务器,然后执行命令来部署项目。为了安全起见,我们把服务器 host 和端口,还有 ssh 密钥都配置到 Github 仓库的 Secrets 中,这样就不会把服务器的信息暴露到配置文件中。 准备部署 SSH 密钥 再生成 SSH 密钥对用于发布项目 把公钥添加到服务器的 ~/.ssh/authorized_keys 文件中 1 echo "public-key" >> ~/.ssh/authorized_keys 在 Github 仓库的 Settings -> Secrets -> Actions 中添加名为 key 的 secret,值为私钥。 设置 host 和端口 同样在 Github 仓库的 Settings -> Secrets -> Actions 中添加 host 和 port。 创建 Github Actions 配置文件 在仓库的根目录中创建文件夹 .github/workflows。在此文件夹中创建一个 .yml 后缀的文件。 在配置文件中指定main分支在 push 时触发 Github Actions,然后指定一个 job 名为 deploy,在这个 job 中使用 appleboy/ssh-action@master 这个 Github Action 来连接服务器,然后执行部署脚本。在 Github Actions 中可以使用 Secrets 中的变量,这样就不会把服务器的信息暴露到配制文件中。 部署脚本首先用 git clone 拉取代码, 然后安装依赖,最后使用 PM2 启动项目。最后用 pm2 save 保存项目配置,以便在服务器重启后自动启动项目。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Deploy uses: appleboy/ssh-action@master with: host: ${{ secrets.host }} username: ${{ secrets.username }} key: ${{ secrets.key }} port: ${{ secrets.port }} script: | git clone ${{ github.repository }} /home/username/project cd /home/username/project npm install pm2 start npm --name "project" -- start pm2 save 此后每次 push 到 main 分支时,Github Actions 就会自动部署项目到服务器上。 参考 GitHub Actions Documentation actions 市场 Workflow syntax for GitHub Actions 生成 SSH 密钥 安装 certbot

2023/10/9
articleCard.readMore

使用 v4l 采集摄像头

FFmpeg 是一个非常强大的视频处理工具。大多数应用都会使用 FFmpeg 来处理视频。我的 Network RC 项目也使用了 FFmpeg 来处理视频。 Video4Linux2 Video4Linux2(v4l2) 是 Linux 上的一个视频采集框架,它提供了一套统一的接口,可以方便的接入视频设备的输入和输出。FFmpeg 也可以通过 Video4Linux2 接口来采集摄像头的视频。 v4l2-ctl v4l2-ctl 是 Video4Linux2 的一个命令行工具,可以用来查看和设置视频设备的参数。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 # 查看视频输入设备 v4l2-ctl -n # or v4l2-ctl --list-inputs # 设置视频输入设备 v4l2-ctl -i 0 # 设置 index 为 0 的视频输入设备作为当前视频输入设备 # or v4l2-ctl --set-input 0 # 查看支持的输出的格式 v4l2-ctl --list-formats # 查看支持的分辨率 v4l2-ctl --list-framesizes=YUYV # 查看支持的帧率 v4l2-ctl --list-frameintervals width=1920,height=1080,pixelformat=YUYV # 查看视频输入设备的控制参数 v4l2-ctl --list-ctrls # 查看视频输入设备的控制参数的值 v4l2-ctl --get-ctrl=iso_sensitivity # 设置视频输入设备的控制参数的值 v4l2-ctl --set-ctrl=iso_sensitivity=100 FFmpeg 使用 Video4Linux2 采集摄像头 输入设备 在 ffmpeg 命令中,使用 -f v4l2 或 -f video4linux2 指定视频输入接口为 Video4Linux2。 使用 -i /dev/video0 指定视频输入设备路径为。 1 ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -preset ultrafast -f mp4 camera-test.mp4 采集格式 使用 -input_format 指定视频输入格式。 1 ffmpeg -f v4l2 -i /dev/video0 -input_format yuyv422 -c:v libx264 -preset ultrafast -f mp4 camera-test.mp4 分辨率 使用 -video_size 指定视频分辨率。 1 2 3 ffmpeg -f v4l2 -i /dev/video0 -video_size 1920x1080 -c:v libx264 -preset ultrafast -f mp4 camera-test.mp4 # or ffmpeg -f v4l2 -i /dev/video0 -s 1920x1080 -c:v libx264 -preset ultrafast -f mp4 camera-test.mp4 帧率 使用 -framerate 指定视频帧率。 1 ffmpeg -f v4l2 -i /dev/video0 -framerate 30 -c:v libx264 -preset ultrafast -f mp4 camera-test.mp4

2023/9/28
articleCard.readMore

怎么解决 Prettier 和 ESLint 在 VSCode 里的冲突?

Prettier 是一个代码格式化工具。ESLint 是一个代码检查工具,它可以检查你的代码是否遵循了规范。他们通常会在项目中一起使用。前端开发过程中,我们通常会使用 Prettier 和 ESLint 来保持代码的可读性和统一代码风格和规范。项目脚手架工具和代码编辑器都可以引入 Prettier 和 ESLint 工具。 Prettier 和 ESlint 配置不当,会导致代码格式化和代码检查的冲突。项目脚手架工具和代码编辑器的配置不统一也会导致格式自动修复的冲突。 下面是配制 Prettier 和 ESLint 的方法: 安装 eslint-config-prettier 1 yarn add --dev eslint-config-prettier 在 ESLint 配置文件中添加配置 在 .eslintrc.json 文件中的 extends 的最后中添加 "prettier"; 1 2 3 { "extends": ["eslint:recommended", "prettier"] } 这样 VSCode 使用 Prettier 插件来格式化代码就不会冲突了。

2023/9/18
articleCard.readMore

《微习惯》 - 读书笔记

这本书我是与《自控力》一起读的。都是基于相同的目的而读:学习和运用其中实际可操作的方法,为我开发的 App 设计功能帮用户能够改变自己。 这本书讲了什么 前三章探讨习惯建立过程、大脑、意志力、动力以及这些因素之间是如何相互关联的。接下来的两个章节将探讨合理、科学的途径。最后两章是行动指南和原则。 习惯是什么 一个微习惯,是坚持做一件感知不到困难、不会消耗意志的事情。它是潜意识行为。 重复就是(潜意识)大脑使用的语言。 大脑的有两种工作模式,通过重复行为识别模式;抑制模式,改进行为。”模式识别”由基底神经节完成。效率高,消耗能量少。它很稳定,不易改变。 前额皮层可以抑制模式识别,改进已经形成习惯的行为,但能耗较大。 压力会促进习惯性行为,无论这种习惯是好是坏。 因为在压力下,大脑会倾向于使用能耗较少的”模式识别”。 大脑中习惯的样子 一个习惯在大脑中,是很多条件触发一系列动作的不断的强化结果。也许是某些条件触发某些动作的神经通路在不断重复的过程当中,神经细胞们自发的生长出信号越来越强烈和畅通的连接。 神经通路是大脑里的沟通渠道,这些通路就是习惯在身体里的“长相”。 一旦某个习惯指定的神经通路被一个想法或外部信号触发,脑中就会有一个电荷沿着这条通路放电,然后你就会有一股想进行这项习惯行为的强烈欲望。 在特定条件下总是重复的触发一系列动作,我们要让大脑执行这个过程要消耗的能量越来越少,来获得竞争优势。这就是习惯的生理学和演化学上的意义。 潜意识大脑喜欢效率,这就是我们能养成习惯的原因。当你重复某个行为一段时间后,大脑就能自动完成这个过程了。比起每次都要有意识地进行权衡和选择再决定以同样的方式行动,这种做法更节能。 习惯对人的影响比人们预想的要大得多 相比某一天做很多事,每天做一点儿事的影响力会更大。 哪怕是一点点行动,也比毫不作为强无数倍(在数学意义上如此,实际生活中也是如此) 杜克大学的一项研究表明:我们的行为中大约有 45% 源于习惯。 而且大部分每天都在重复,长远看,这种不断的重复叠加起来,要么收益颇丰,要么贻害无穷。 行动指南 一、选择微习惯的策略和目标 第一步选择微习惯的策略,使用一周弹性计划来确定自己使用单一微计划,还是多项微计划。当自控力较弱时应选选择单一微计划来改善自控力。如果把微习惯当作一项技能来说的话,初学者应该从单一微计划开始尝试。微习惯的每一次任务要到小不会让你在精力疲备的时候也不会产生抵抗,既使会感到它小到很荒唐。 微步骤之小会让我们感到荒唐,这可能是社会标准、更高更大的思维习惯以及自尊心导致的。 在习惯没有连续完成时,进行分解操作。把分解出来的第一步作为微习惯。 二、挖掘微习惯的内在价值 想知道习惯是否值得我们付出努力的最佳方法是先认清来源。 列好习惯后,看看你为什么想要实现它们,但别在这一步就停止。再问问为什么,不断地问下去,直到形成循环和重复为止,因为这时候你已经找到了核心。 习惯的的价值要来自于自身的追求。而不是来自于外界的压力。 来自同龄人的压力和别人对你的期待并不是我们要寻找的想法来源。 三、明确微习惯的依据,将其纳入日程 习惯行为不是主动的思维触发的,而是潜意识能感受到的条件触发的。比如时间、环境、事件、情绪等等。通勤坐地铁会触发我的多邻国打卡习惯,周末则是饭后。当然,饭后也会触发我抽烟的环习惯。 培养习惯的常见依据有两种,时间和行为方式 一个有固定依据习惯会形成得更快,没有依据的习惯会更灵活,触发习惯的概率更高。因为没有依据的习惯通常有多个不同的触发条件,模式更复杂,在大脑中形成得更慢。 只凭借一个依据行事会让你难以获得社会机遇和发挥自主性。 我们可以从简单的做起。培养好习惯让它有固定的时间、环境或事件来触发。然后再逐渐增加触发条件。 四、建立回报机制,以奖励提升成就感 习惯需要回报反馈来刺激大脑形成它,大脑会自动把与行为不相关的回报关联起来。 我们能做的是将行为与完全不相关的回报建立关联,一段时间过后,大脑就会把这个行为和回报联系起来,这就是我们想要的!之后,大脑就不再需要这个(硬性建立起关联的)回报来促进行动了。 建立习惯的诀窍就是把它想象成教孩子骑自行车。刚开始,你一边让孩子蹬自行车一边向他保证你在稳稳地扶着他。可是在某个时候你把手松开后,孩子没有你的扶持也能继续骑车了。 回报可以恢复意志力。 通常我们会把回报看作因为做了一件好事而得到的报偿,但回报也能给你回报。 超额完成的满足感本身是一种回报。去学会感受到这种满足,会让你的动力满满。 你在超额完成很多工作后,可能会想奖励自己,以鼓励该行为。 完成习惯后对更大回报的期待又是一种回报形式。 注意,不要在这个时候冲动的增加习惯的大小。 我应该为超额完成习惯设计一个奖励机制。比如在我的应用里超额完成时给出更高的爆击率反馈。 五、记录与追踪完成情况 记录自己完成一件事情,也会产生“自我效能感”。我们都感受过这种感觉,记录下来会让这种感觉更具象化,大脑会更容易形成习惯。 不管你选择什么策略,我建议你到睡前再检查自己是否成功。如果你在白天就早早地检查完毕,完成任务的感觉会降低你继续进行额外工作的动力。 我用 Streaks 来记录我的习惯,它可以把每个习惯的日历放在手机、电脑、平板和手表的主屏幕上(苹果生态)。 记录习惯的完成情况,可以让你对习惯的完成情况有更好的了解。及时缩小习惯,防止意志力的过多消耗。 所以在我想开发的的应用中让记录完成情况要很方便,还要有缩小习惯的功能,以及完成情况的日历视图。 六、微量开始,超额完成 真正让微习惯策略脱颖而出的是,你绝不会有失败的借口,绝不会害怕失败,而且绝不会感到内疚。即使你的意志力已经耗尽,微习惯的任务要求是如此之低,你总能找到方法完成。 让习惯行为来激发动力,不要依赖动力来产成行动。前者积攒意志,后者消耗意志。如果前者遇到阻碍就缩小习惯 微习惯绝不会阻碍你进步,就好像火花绝不可能阻碍一场大火的蔓延一样。 超额完成让人产生的满足很愉悦,你可以在每次产生充足的动力时超额完成习惯来感受这种“自我效能感”。 虽然我们完成这些微习惯时依赖的完全是意志力,但我们选择在达到目标后继续努力时,动力就会起作用了。 七、服从计划安排,摆脱高期待值 下意识会追求你过于困难的目标,这会扼杀你的动力。切记,不要在习惯形成之前就想着要扩大习惯的规模。 最大的障碍是耐心。你不想成为那个每天写 50 字的人——你想让自己迅速变成每天能写出 4000 字的人,尽快实现梦想。 急于求成是很常产生的念头。你需要等待习惯的形成,而不能急于求成。 从潜意识层面看,超额完成目标后,大脑会设定一个新的期待值,它承载了你以前设定过的典型目标(你懂的,那些无效目标)带来的负担和压力。 打游戏的时候我常期望一些不可能的胜利(当游戏匹配机制给你分配了不在同一水平的对手时),只少数时候它可以成功。但在游戏中并没关系,我动力充足。现实中应该运用更理性的策略,期待值要合理。 坚持每天进步一点点,比只能坚持做几次就放弃对你的未来更有帮助。 所以,一定要提醒自己,你每天的目标并没有改变,这一点极为重要。 我们要把期待值和精力放到坚持目标上,而不要对任务量抱有较高的期待。 八、留意习惯养成的标志 如果一个习惯已经形成,你会发现你不再抵触它;你会产生一种身份认同感;你不需为开始该行为寻找理由;你不再担心你不会完成它;开始行动时是非情绪化的;它很无聊。已经形成的习惯,不会让你高兴,但它对你有好处。 代表行为已成为习惯的信号有: 没有抵触情绪:该行为似乎做起来容易,不做反而更难。 身份:现在你认同该行为,而且可以信心十足地说“我常看书”或“我是个作家”。 行动时无须考虑:你不需要做出执行的决定就能开始该行为。 你不再担心了:刚开始时,你也许会担心自己漏掉一天或者早早放弃,可当行为变成习惯后,你知道你会一直做这件事,除非出现紧急情况。 常态化:习惯是非情绪化的。 它很无聊:好的习惯并不会让人兴奋,它们只是对你有好处而已。 看书 15 分钟,这是我已经养成的习惯。我每天都会看书,我会说我经常看书。每天到了看书的时候不仅会抵触,还会有一丝期待,虽然可能是因为我看的书是我想看的书。 还有多邻国打卡,累的时候一天过一次关卡。比较闲或没给事可做就会多过几个关卡。 不要一次培养过多的习惯。要培养的习惯越多,失败的风险越大。失败会消弱意志。 微习惯策略效果很好,可是如果你在一个行为真正成为习惯之前就停止,继续添加下一组习惯,那么你可能会像个手法拙劣的杂耍艺人一样冒着让手里的橘子全部落地的风险。 让长远对你有用的事情变成你无聊时会去做的一种习惯。养成习惯后,你不会感受到焦虑。让你的生活平淡的向着积极的方向发展。 微习惯的原则 经常回报自己,尤其在完成微习惯之后. 保持头脑清醒。当你精力充沛时,就容易冲动,错误的估计自己的能力,增加自己的目标大小。 你需要特别注意避免这么做,因为你每对自己提高一点要求,就需要更多意志力才能达到要求,而且就算你应付得了额外的意志力负担,也许还有同时培养多个习惯的目标。 感到强烈抵触时,后退并缩小目标。在执行习惯时,不要让自己的精力过度消耗。这样会让你的意志力耗尽,导致习惯培养的失败。 只要遇到抵触,我就会把任务缩小,问题就解决了。 满意每一个进步。 李小龙有一句名言能很好地总结这一点:“要满意,但别满足。” 用多余精力超额完成任务,而不是制定更大目标。 大目标在纸面上看着漂亮,但只有行动才算数。目标渺小、结果丰硕的状态比反过来好多了。 我们想要确保成功,而不是听成功和失败发号施令。 人们在设定目标时经常犯的一个错误就是没有把动力和精力水平的剧烈波动考虑在内,而是假定到了实施行动的时候,他们能维持或重新激活当前的精神和精力状态。 绝不要小看微步骤。 微习惯策略的核心是一个很简单的大脑错觉,但同时也是一种重视开始的生活哲理,一种认为行动优于动力的生活哲理,一种相信将每一小步积累起来便能让量变转为质变的生活哲理。 反馈是大脑形成习惯路径的关键。通常我们训练的的习惯有着更复杂的条件和动作,形成时间较长。 不要企图用冲动来坚持一件事情,不掺杂情绪的习惯更可靠。 冷静的头脑是建立习惯的最佳思维模式,因为它很稳定,而且可以预见。在不断取得进步的过程中,你可能会兴奋起来,但别让这种兴奋变成你实施行动的原动力。变得依赖动力或情绪正是许多个人成长计划最终失败的原因。 绝不要自欺欺人。 常识告诉我们,一定要突破强烈抵触情绪的阻碍,但我得说,这种做法很愚蠢。 有关习惯的其它想法 想要戒掉坏习惯,应该用好习惯去代替它。 微习惯也是一个让人向外迈出一小步,来突破舒适圈的过程。 自主权能促进行动,反过来失去自主权则会抑制行动。 星星之火,可以燎原。

2023/9/16
articleCard.readMore

在 iPad 使用 VS Code 写代码

VS Code 推出了 tunnel 插件和服务,现在终于可以方便的在 iPad 的浏览器上打开 VS Code 了。 VS Code 可以在一台电脑上运行 VS Code Server ,并通过 Github 账号登录开启一个 tunnel 隧道生成一个网址,然后在其他设备上打开这个网址就可以使用 VS Code 了。 在服务器上也可以使用 VS Code CLI 命令行工具来启动 VS Code Server。 1 code tunnel 网页上使用 VS Code 的体验相当完整。我使用的插件基本上都可以使用。本址端口也可以方便的转换成一个公网地址,可以在 iPad 上访问。对于前端开发来说,可以完全在 iPad 上完成开发。 唯一的问题是 tunnel 隧道的网络延迟会不稳定,影响开发体验。 ESC 键 我在 VS Code 上使用 Vim 插件,需要使用 ESC 键切换模式。但是在 iPad 大部份键盘上没有 ESC 键,command + . 可以代替。也可以修改修饰键映射来解决。 添加到主屏幕 在 Safari 的分享菜单中,可以添加到主屏幕,这样就可以像一个 App 一样使用了。也能得到全屏幕的体验。

2023/8/29
articleCard.readMore

在 Macbook 上运行 ChatGLM-6B

我有一台 32G 内存 Macbook Pro,想要运行大语言模型看能不能替代 OpenAI 的 API。下面是我在 Macbook 上运行 ChatGLM-6B 的步骤。 克隆 ChatGLM-6B 仓库 1 git clone https://github.com/THUDM/ChatGLM-6B 创建虚拟环境 1 2 cd ChatGLM-6B python3 -m venv .venv 激活虚拟环境 1 source .venv/bin/activate 安装依赖 1 2 3 4 pip install -r requirements.txt # 安装 PyTorch, 使用 MPS 后端来在 Mac 的 GPU 上运行 pip install --pre torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/nightly/cpu 下载模型 1 2 cd .. git clone https://huggingface.co/THUDM/chatglm-6b chatgml-6b-model 修改代码使用 MPS 后端和下载的好的模型 修改 webapp.py 文件。 将 .cuda() 改为 .to("mps") 将模型和 tokenizer 的路径改为 huggingface 上克隆下来的 chatglm-6b 仓库本地路径。下面我的例子中,本地路径为 /Users/eson/git/chatgml-6b-model。 1 2 3 4 5 6 7 8 9 10 11 12 -tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True) -model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).half().cuda() +tokenizer = AutoTokenizer.from_pretrained( + "/Users/eson/git/chatgml-6b-model", trust_remote_code=True +) +model = ( + AutoModel.from_pretrained( + "/Users/eson/git/chatgml-6b-model", trust_remote_code=True + ) + .half() + .to("mps") +) 运行 1 python webapp.py 这将会在本地启动一个 web 服务,会自动打开浏览器。

2023/8/13
articleCard.readMore

《自控力》 - 读书笔记

它的作者是凯利•麦格尼格尔(Kelly McGonigal)。她为斯坦福大学继续教育学院开设包括《自控力科学》(The Science of Willpower)和《在压力下好好生活》(Living Well With Stress)两门课程。 她有一个双胞胎姐妹珍妮·麦高尼格,职业是游戏设计师。我想她在开她的课程和写这本书的时候,一定和她的姐妹有过很多的交流。游戏设计通常会用到一些手段来让玩家上瘾,这些手段也可以用在自控力上。 这本书的内容大体上是作者把她在坦福大学继续教育学院开设的课程的内容整理出来的。讲的是自控力的生理机制、提升方法。 我读这本书是想学习和运用其中实际可操作的方法,来增加对自身的时间的分配和撑控能力。还想要为自己开发的,给有同样需求的人使用的 App 乐办(Recreation),做一些更有科学依据的特性。 读书笔记 第一和第二章 这一章初略的概括了大脑控制不同行为的几个部份,自控力演化出来的原因。 前额皮质左边和右边以及前额皮质后面靠下的部份,决定的人类的意志力。一些不健康的活动会削弱这些区域的能力。菲尼亚斯·盖奇(Phineas Gage)的前额皮质受损的经典案例证明了这个事实. 原始人类需应激反应来在突发危机前保障生存,但是现代社会更多的是需要自控力来应对未来的挑战。为了适应人类社会的发展,人类需要越来越多的自控力来协调人际关系。在人类的社会环境下,有更多自控力的人,生育的机会越大。 自控力和压力的关系。压力和自控的生理反应是有冲突的,管理压力是提身自控力的重要部分。心率变异率可以反应自控力,越高自控力越强。 摘录 自知之明是自控的基础。认识到自己的意志力存在问题,则是自控的关键。 前额皮质并非始终可靠,醉酒、缺觉、分心等都会影响到它,使我们无法控制自己的冲动。 在作决定的时候,你必须意识到自己此刻需要意志力。否则,大脑总会默认选择最简单的。 前额皮质正是大脑中控制冲动的区域。 你自控的时候,大脑的能量供应会增加,从而帮助前额皮质发挥意志力。 应激反应会让你面对最原始的欲望,而这正是你当下最不愿看到的。 当人们感到压力时,交感神经系统会控制身体。这种生理学现象让你能够战斗或者逃跑。心率升高,心率变异度就会降低。 相反,当人们成功自控的时候,副交感神经系统会发挥主要作用,缓解压力,控制冲动行为。心率降低,心率变异度便会升高。 任何给你的身心带来压力的东西都会影响自控力的生理基础,甚至会摧毁你的意志力。焦虑、愤怒、抑郁和孤独都与较低的心率变异度和较差的自控力有关。慢性疼痛和慢性疾病则会消耗身体和大脑的意志力储备 放慢呼吸能激活前额皮质、提高心率变异度,有助于你的身心从压力状态调整到自控力状态 压力和自控的生理学基础是互相排斥的。 一项针对 10 个不同研究的分析发现,改善心情、缓解压力的最有效的锻炼是每次 5 分钟。 放慢呼吸能激活前额皮质、提高心率变异度,有助于你的身心从压力状态调整到自控力状态。 第三和第四章 介绍自控力的有限性和“道德许可”现像对自控力的影响。 道德许可效应:是指当人们做出善举后,感到可以为此得到赞同或者批准,从而产生一种道德放松的现象。这种现象会导致人们对道德标准的降低或改变,甚至变得不再尊重这些标准。例如,一个人如果曾经捐款给了慈善机构,他可能会认为自己已经做出了一个善良的行为,而不再认为自己有义务去做出其他的善举,这就是道德许可效应在行为方面的一种表现。 自控时大脑消耗的能量比依照习惯和条件反射行事时多。血液中能量下降时,大脑会首先限制消耗较大的活动。所以当你感到疲惫时,你的自控力会下降。自控和和非自控时,相当于慢思考和快思考,我们不能时刻进行慢思考。 自控力就像肌肉一样有极限 自控可能比大脑处理其他问题时所用的能量多,但远远低于身体运动时所需的能量 因为,自控是所有大脑活动中耗能最高的一项。为了保存能量,大脑不愿意给你充足的能量去抵抗诱惑、集中注意力、控制情绪 重要的是,能预测被试者选择结果的并不完全是血糖含量,而是血糖的变化方向 资源不足时,大脑会选择满足当下的需求;资源充足时,大脑则会转向选择长期的投资 当你的血糖含量降低时,你的大脑仍旧会考虑短期的感受” 自控消耗了身体的能量,而能量的消耗又削弱了意志力。” 他把人们带进实验室,布置了一系列自控力任务,比如集中注意力和控制自己的情绪。他在做每个任务前后分别测量人们的血糖含量。被试者在完成任务后血糖含量降得越多,他们在下一个任务中表现得就越差。看起来,自控消耗了身体的能量,而能量的消耗又削弱了意志力。” 喝到含糖柠檬水的被试者表现出了更强的意志力,而喝到“安慰柠檬水”的人意志力继续减弱。” 现代人在饥饿的时候更愿意冒险。比如,人们饥饿的时候会作出更冒险的投资,在节食后会更愿意“尝试多种交配策略”(这是进化心理学家的术语,实际上指的是背着自己的伴侣偷情)。” 这就意味着,股票经纪人可能在午餐前买进错误的股票,节食者更容易去“投资”彩票,不吃早餐的政客可能觉得实习生魅力难挡 简单说来,只要我们的思想中存在正反两方,好的行为就总是允许我们做一点坏事。 学生们因为驳斥了性别歧视和种族歧视的言论而感觉良好,因此放松了警惕,更容易作出有歧视色彩的决定。他们更可能根据直觉的偏好作出判断,而不去考虑这个决定和他们“追求公平”的目标是否一致 记住我们为什么会拒绝诱惑,这是个很有效的办法。 第五章 这一章主要是讲,多巴胺不是认人们感受到快乐的物质,它产生的感觉是期待,它会让你行动起来。 在有压力时,多巴安会让我们去寻找快乐。真正能缓解压力的不是释放多巴胺或依赖奖励的承诺,而是增加大脑中改善情绪的化学物质,如血清素、γ-氨基丁酸和让人感觉良好的催产素。这些物质还会让大脑不再对压力产生反应,减少身体里的压力荷尔蒙,产生有治愈效果的放松反应。 我在开发 App 时多巴胺让我不段追加功能,对 App 发布上线的事情却不顾。应对方法:感受什么期待产生多巴胺,思考当前的行动是否是自己的长期目标。 摘录 当大脑发现获得奖励的机会时,它就释放出叫做多巴胺的神经递质 大量的多巴胺并不能产生快乐的感觉,那种感觉更像是一种激励 但有一件事很清楚——这不是喜欢、满足、快乐或真正的奖励会带来的感觉 多巴胺控制的是行动,而不是快乐 大脑正是靠对快乐的承诺让你不停地去狩猎、采集野果、工作和求爱,而不是让你直接感受快乐。 当多巴胺给我们的大脑安排寻找奖励的任务时,我们就展现了自己最敢于冒险、最冲动、最失控的一面。 和有保证的小奖励相比,我们的奖励系统面对可能获得的大奖会更加兴奋 美国杜兰大学的罗伯特·希斯(Robert Heath)在病人的大脑中植入电极,并交给他们一个控制盒。控制盒能让他们刺激自己这个新发现的快感中心。希斯的病人表现得和奥尔兹的小白鼠如出一辙。他们可以自己选择刺激的频率,结果他们平均每分钟会电击自己 40 次。休息的时候,研究人员给他们端来了食物,病人们虽然承认自己已经很饿了,但仍然不愿意停下电击去吃点东西。在实验人员提出终止这个实验或切断电极的时候,有一个病人提出了强烈的抗议。另外一个被试者在电流切断后仍然按了 200 多下按钮,直到实验人员要求他停下来为止 研究表明,即便你摘除了小白鼠大脑中的多巴胺系统,它们仍会在吃到糖果时露出傻傻的笑容。它们不会为了奖励而付出努力。它们喜欢糖,但在吃到糖之前不会想要糖 2001 年,斯坦福神经科学家布莱恩·克努森(Brian Knutson)发表了一份具有决定意义的实验报告,证明了多巴胺会促使人们期待得到奖励,但不能感觉到获得奖励时的快乐 在人类历史的大部分时间里,除非你真的有机会和别人交配,否则你很难看到一个裸体的异性摆出诱惑的姿势。如果你想把你的基因延续下去,这时候最好还是给自己一点动力 2005 年,28 岁的韩国锅炉修理工李承生在连续 50 个小时奋战“星际争霸”之后死于心血管衰竭。他不吃不睡,只想继续玩游戏。听到这件事的时候,我们很难不联想到奥尔兹和米尔纳实验中力竭而亡的小白鼠。 第六章 这一章更详细解释了在压力时的大脑动作对人的影响,以及如何应对压力。但我觉得她说应对得方法不实用(《微习惯》一书提畅的方法更有操作性)。 压力状态下,大脑前额能力被消弱。 当我们情绪低落时,大脑更容易受到诱惑 当你感到压力时,你的大脑就会指引着你,让你去做它认为能带给你快乐的事情” 所以你不会想要再消耗意志。 当暴饮暴食的人为体重增加或缺乏自控力感到羞愧的时候,他们会怎么做呢?他们会吃更多的东西来抚慰自己的情绪。当拖延症患者想到自己已经远远落后于进度的时候,他们会万分焦虑,这反而让他们继续拖延下去,不去面对落后于进度的事实。在每个案例中,“想要更快乐”这个目标总是战胜了自控力的目标。 一个目标让自己感到有压力,应当改变目标来减少压力,而不是对抗。 “虚假希望综合征”, 不切实际的目标最终会让你放弃目标。 “虚假希望综合征”:不切实际的乐观可能给我们一时的快乐,但接下来我们就会感到失落。作出改变的决定是最典型的即时满足感——在什么都没做之前,你就感觉良好了。但真正作出改变时面临的挑战却会给你当头一棒,奖励并不像我们想象的那么容易获得。(“我丢了 5 英镑,还做着一份糟糕的工作!”)当我们第一次面对挫折时,失望就会取代最初决定改变时的良好感觉。没能达到预期目标会再度引发曾经的罪恶感、抑郁和自我怀疑,而承诺改变的情绪慰藉作用也消失了。这时,大多数人会彻底放弃努力。只有当我们感觉失控,需要再次拥有希望的时候,我们才会再次发誓作出改变。于是,这个循环又开始了。 缓解压力的活动: 最有效的解压方法包括:锻炼或参加体育活动、祈祷或参加宗教活动、阅读、听音乐、与家人朋友相处、按摩、外出散步、冥想或做瑜伽,以及培养有创意的爱好 真正能缓解压力的不是释放多巴胺或依赖奖励的承诺,而是增加大脑中改善情绪的化学物质,如血清素、γ-氨基丁酸和让人感觉良好的催产素。这些物质还会让大脑不再对压力产生反应,减少身体里的压力荷尔蒙,产生有治愈效果的放松反应 面对压力的方法应该是不要让压力存在,就如《微习惯》中说的一样,让你的目标变得更小,让你的行动变得更小,让你的压力不存在。这需要有足够的耐心和远见来让你能够接受自己缓慢的进步。而不是一下子就想要达到目标,那会让你感到压力袭来。 我们必须避免常见的意志力陷阱,即用“改变的承诺”而不是“改变”来改善我们的心情 第七章 这一章讲我们对眼的诱惑更敏感,对未来的自己是麻木的。 看不到直接的奖励会让奖励变得抽象起来,对奖励系统的刺激作用也会减少 我们会把未来的自己想象成完全不同的一个人 脑成像研究发现,我们在考虑现在的自己和未来的自己时,运用的是大脑中不同的区域 当我们考虑未来的自己时,大脑的活动和我们考虑别人的特征时如出一辙 对待眼前的诱惑,我们要让自己和它产生距离(大多数情况下基本无效)。 想获得一个冷静明智的头脑,我们就需要在所有诱惑面前安排 10 分钟的等待时间。如果 10 分钟后你仍旧想要,你就可以拥有它。但在 10 分钟之内,你一定要时刻想着长远的奖励,以此抵抗诱惑。如果可以的话,你也可以创造一些物理上(或视觉上)的距离。 自己做每周计划的时候,对未来的任务只是罗列,没有深刻的思考实施细节。 想像自己的未来在接受挑战的场景。想像得越生动,现在做的决定就越不会后悔。给未来的自己发信息,让你和未来的自己联系越紧密。 我喜欢甘特图,它能让自己更连续的感受未来的自己和更清晰的感受未来自己的状态。 增加“未来自我的连续性”不仅会增加你的存款,还能帮助你应对各种意志力挑战。较高的“未来自我的连续性”会让人现在就做到最好 创造一个未来的记忆 给未来的自己发条信息 想象一下未来的自己 你也可以利用这个特性操控它人. 如果是让其他人承诺奉献他们的金钱、时间或努力,你可以利用他们对未来的想象,让他们提前作出承诺。 第八章 这一章讲了人的社会属性包括“羊群效应”、社会认同现象,对人的意志力的影响。 “羊群效应”是由”镜像神经元“的系统来控制的(现在的脑科学实在是太含糊了,因为它过于复杂)。 人生来就要和其他人产生联系。我们的大脑已经找到了一种巧妙的方法,确保我们能产生这样的联系。我们有专门的脑细胞管这件事,它名叫“镜像神经元”。 这种无意识的身体镜像似乎能帮助人们更好地了解彼此,同时带来相互联系、关系密切的感觉。 大脑让我们误入迷途的第二种形式是传染情绪。我们发现,自己的镜像神经元会对别人的疼痛产生反应,也会对别人的情绪产生反应。 最后,当我们看到别人屈服于诱惑时,我们的大脑也可能受到诱惑。 同时,你和优秀的人社交也会让你变得优秀。 但是,这种自动读心术也有一种自控的副作用:它会激活我们心中的共同目标。心理学家称之为“目标传染病”。 目标传染在两个方向上都会起作用——你既可以感染自控,也可能感染自我放纵。但是,我们好像更容易感染上诱惑。 你对一个人越有好感,你就越容易被他影响。 社会传染病在人际网络中传播,那里面都是互相尊重、互相欣赏的人 我们的日常行为受到“社会认同”的巨大影响。 自豪、羞愧等直接了当的控制人的行为。 预想自己实现目标(比如戒烟或献血)后会非常自豪的人,更有可能坚持到底并获得成功,预想自己的行为会受到谴责也很有效 与讨论长期成本和收益的理性论证比起来,自豪、羞愧等社会情感能更迅速、更直接地影响我们的选择。德斯丹诺把这称为“激情的自控 第九章 这一章主要解释了“讽刺性反弹”这一现象的的作用和原理。 当人们试着不去想某件事时,反而会比没有控制自己的思维时想得更多,比自己有意去想的时候还要多 压抑人的本能时,就会产生这种讽刺性反弹效应” “讽刺性反弹” 是由韦格纳提出,大脑的一部分负责监控,另一部分负责操作。监控的那一部份也会让你做出你想避免做出的行动。 韦格纳认为,这和大脑如何处理“不要去想”这个指令有关。大脑把这个指令分为两部分,分别由两个不同系统去执行。 ”大脑的一部分负责将人的注意力从被禁止的想法那里引开”,韦格纳将这个过程称为“操作” “大脑的另一部分则负责寻找证据,证明你没有去想、去感觉、去做你不该去想、去感觉、去做的事”,“韦格纳将这个过程称为“监控” 人们相信的事物会受记忆的强度影响。 “人们会根据想起事情的难易程度来判断它的可能性或真实性。” “大脑的潜意识不断想到被禁止的内容。这么做的结果是,你会想到、感觉到或去做自己正在努力避免的事” “当人们试图摆脱一种想法,它却不断回到脑海中时,人们很可能认为它一定是真的。” 书中跟据这一现象提出的应对方法我自己尝试很难达到效果,我觉得更好的方法是让自己的注意力转移在其他事情上,而不是让自己不去想。 “冲动就像渴望一样,只要你不依照其行事,它就会自行消亡” “放弃控制内心感受,反而能让我们更好地控制外在行为。” “他们既不需要从冲动上转移注意力,也不需要寄希望于它自己消失,只需好好地观察自己,看看当时自己在想什么,有什么样的冲动,自己的肚子、肺部、喉咙会不会感觉不适” 尾巴 总体来说,前两章有一点含糊,实践部分不太接地气。担是书中的下面这些知识可以让我更好的理解自己的行为,从而更好的控制自己: 自控力消耗能量 多巴胺的机制 道德许可心理现象 压力状态下大脑的状态 对待未来的自己像陌生人 人的社会属性的两个现象对控制力的影响 讽刺性反弹 所以大体上还是值得一读的,如果想要更直接的方法,可以看看《微习惯》这本书。

2023/7/20
articleCard.readMore

Next.js 中的日期属性问题

在 Next.js 的 React 组件 props 中,日期类型应当被存储为字符串,而不是日期对象。这是因为 Next.js 的 getStaticProps 和 getServerSideProps 函数要求返回的数据必须是 JSON 可序列化的,而日期对象无法直接序列化为 JSON。 转换日期对象 为了在 Next.js 的 props 中使用日期类型,你可以将日期对象转换为字符串。在 JavaScript 中,可以使用 toISOString() 方法将日期对象转换为 ISO 8601 格式的字符串。这样,日期数据就可以被 Next.js 处理,并在组件中使用。 维基百科:国际标准 ISO 8601,是国际标准化组织的日期和时间的表示方法. 例如,在 getStaticProps 中将日期对象转换为字符串: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 export async function getStaticProps() { const res = await fetch("https://.../posts"); const posts = await res.json(); return { props: { posts: posts.map((post) => { return { ...post, date: post.date.toISOString(), }; }), }, }; } 在组件中,你可以将字符串格式的日期转换回日期对象,然后用 Intl.DateTimeFormat 将其格式化为所需的样式。 格式化日期 1 2 3 4 5 6 7 function formatDate(dateString) { const date = new Date(dateString); return new Intl.DateTimeFormat("zh-CN", { dateStyle: "full", timeStyle: "short", }).format(date); } 在组件中使用 1 2 3 4 5 6 7 8 9 10 11 export default function Blog({ posts }) { return ( <ul> {posts.map((post) => ( <li key={post.id}> {post.title} <span>{formatDate(post.date)}</span> </li> ))} </ul> ); }

2023/4/10
articleCard.readMore

使用 Google Colab 训练 Stable Diffusion LoRA 模型教程

最近在玩 Stabl Diffusion ,想用老婆的照片来训练一个 LoRA 模型。因为 Mac 上无法调用 GPU 进行 fp16 运算, LoRa 的模型训练无法在 Mac 上运行,所以我用了 Google Colab 来训练 LoRa 模型。下面介绍如何在 Google Colab 上训练 LoRa 模型。 Colab 在空闲时会自动断开连接,释放资源。所以在操作时要尽量保持 Colab 页面不要关闭,并且不要把这个页面放在后台。如果 Colab 页面被关闭,需要重新打开页面,然后从 1.1 开始执行。 安装 LoRA 模型训练环境 访问 https://github.com/esonwong/learning-python/blob/main/kohya-LoRA-dreambooth.ipynb 点击 “Open in Colab” 按钮。 选择 “代码执行程序” -> “更改运行时类型”,在硬件加速器选项中选择 “GPU”,然后点击 “保存”。 运行 1.1 安装依赖。如果出现错误,请重复第 2 步。训练好的 LoRA 模型将保存到 Google Drive,因此需要授权访问 Google Drive。 完成后执行按钮旁边会出现绿色的对勾,大约等待 3 分钟。 准备基础模型(底模,Checkpoint) LoRA 模型需要搭配基础模型才能发挥预期效果。可以通过执行 2.1 选择一个基础模型 下载,或执行 2.2 指定模型 URL 来下载基础模型。 可以从 https://civitai.com 下载模型按钮上复制模型 URL。 以 ChilloutMix 为例:在 2.2 的 modeUrl 输入框中输入 https://civitai.com/api/download/models/11745,然后执行 2.2。 在 2.3 中选择 none,然后执行。 模型会下载到 pretrained_model 目录下。 准备训练数据 执行 3.1。 准备 15 至 25 张 512x512 分辨率的人像图片作为训练数据。 将图片上传至 Colab 页面左侧的 /LoRA/train_data 文件夹。 图片处理 在 4.1 中勾选 convert。 执行 4.1 以处理图片。 执行 4.2.1 或 4.2.2 为图片生成 prompts。 对于一般图像,请使用 BLIP 生成 对于动漫和漫画风格的图像,请使用 Waifu Diffusion 1.4 Tagger V2 训练 在 5.1 的 project_name 输入框中填入 将要创建的 LoRA 模型名称。 下面示范中填的是 test-lora: 在 pretrained_model 目录下复制底模的路径粘贴到 pretrained_model_name_or_path 输入框 执行 5.1 执行 5.2 执行 5.3 执行 5.4 执行 5.5 开始训练模型。 训练好的模型存放在 Google Drive 的 MyDrive/LoRA/output 目录,示范的文件名为 test-lora.safetensors。

2023/4/6
articleCard.readMore