[Vim] 常見 Vim Commands

Vim Cmds Mode Change 進入編輯模式: i, a, o, R(取代) 存檔: :w + Enter 存檔且離開: :wq + Enter 回到一般模式: Esc Function Keys 離開: :q! + Enter 回到當前行的最前/後: 0, $ 移動 n 格/列: 數字 + ↑ || ↓ || → || ← || Enter(向下) || Space(向右) 移動到第幾行: 數字 + g 到首行: [[ 到末行: ]] 上一頁/下一頁: fn + ↑ || ↓ Search and Replace 查找: /(downward) || ?(upward) 移動到下一個: n, N 預覽且取代: /word + Enter + ciw(change inner word) + {內容} + Esc + loop(n, .) Delete del 跟 backspace: x, X 刪除 n 個字: 數字 + x 刪除整行: dd 刪除 n 行: 數字 + dd Copy & Paste 複製當行: yy 先 v 移動,再 y 貼上: p Redo 復原前一動: u 重做上一動: Ctrl + r 重複上一動: .

October 8, 2025 · 1 分鐘 · Rain Hu
Oh! You closed up the window, so you cannot see raining

[Docker] Docker 指令 以 NATS 為例

Docker NATS Server 指令大全 1. 容器生命週期管理 創建並啟動容器 # 基本啟動(無配置文件) docker run -d \ --name nats-server \ -p 4222:4222 \ -p 8222:8222 \ nats:latest # 使用配置文件 docker run -d \ --name nats-server \ -p 4222:4222 \ -p 8222:8222 \ -v $(pwd)/nats-server.conf:/nats-server.conf \ nats:latest \ --config /nats-server.conf # 啟用 JetStream docker run -d \ --name nats-server \ -p 4222:4222 \ -p 8222:8222 \ nats:latest \ -js # 完整配置(JetStream + 持久化 + 配置文件) docker run -d \ --name nats-server \ -p 4222:4222 \ -p 8222:8222 \ -p 6222:6222 \ -v $(pwd)/nats-data:/data \ -v $(pwd)/nats-server.conf:/nats-server.conf \ nats:latest \ -js -sd /data --config /nats-server.conf 參數說明: ...

October 5, 2025 · 5 分鐘 · Rain Hu
Oh! You closed up the window, so you cannot see raining

EdgeSync ServiceFramework AspNetCore.Mvc

EdgeSync ServiceFramework AspNetCore.Mvc 概覽 EdgeSync ServiceFramework AspNetCore.Mvc 提供了一個強大的框架,用於在 ASP.NET Core 應用程式中自動化 NATS 通訊模式的配置。框架支援兩種主要的通訊模式:Request/Response 和 Pub/Sub,並可搭配 NATS JetStream 或 Classic NATS 使用。 核心架構 1. 自動模式決策機制 框架使用 ConventionDecisionMaker 根據決策樹自動選擇最適合的通訊模式: flowchart TD A["方法是否有返回值"] --> B["有"] A --> C["無"] B --> B1["檢查 JetStreamPullAttribute"] B1 --> B2["有 → 錯誤"] B1 --> B3["無 → Request/Response"] C --> E["參數是否為 Collection"] E --> F["是 → Pub/Sub Push"] E --> G["否"] G --> H["檢查 JetStreamPullAttribute"] H --> I["有 → Pub/Sub Pull"] H --> J["無 → Pub/Sub Push"] 2. 支援的通訊模式 模式 說明 使用場景 RequestResponse 請求-回應模式 API 呼叫、資料查詢 PubSubPushJetStream JetStream Push 模式 事件發布、廣播通知 PubSubPullJetStream JetStream Pull 模式 工作佇列、批次處理 PubSubPushClassic Classic NATS Push 輕量級事件通知 Request/Response 實作 基本概念 Request/Response 模式適用於需要同步回應的場景,如 API 呼叫、資料查詢等。 ...

July 7, 2025 · 7 分鐘 · Rain Hu

Devcontainer

安裝工具 sudo apt-get update && sudo apt-get install -y iputils-ping telnet

April 10, 2025 · 1 分鐘 · Rain Hu

[C#] 打包 nuget

NuGet 打包與引用指南 概述 本文檔詳細說明了如何創建 NuGet 包並將其添加到專案中的步驟流程。NuGet 是 .NET 生態系統中的包管理器,可以簡化函式庫的分發和引用過程。 打包 .NET 專案為 NuGet 包 生成 NuGet 包 (.nupkg) 要將您的 .NET 專案打包成 NuGet 包,請在專案根目錄中執行以下命令: dotnet pack -c Release 這個命令會編譯專案並創建發佈配置的 NuGet 包。生成的 .nupkg 檔案通常位於 bin/Release 目錄中。 參數說明: -c Release:以 Release 配置模式進行打包,這會優化程式碼並移除除錯資訊 查找生成的 NuGet 包 打包完成後,可以使用以下命令查找所有生成的 .nupkg 檔案: ls **/*.nupkg 這個命令會遞迴地搜索當前目錄及其子目錄中的所有 .nupkg 檔案並列出它們。 使用本地 NuGet 包 複製 NuGet 包到本地倉庫 要將生成的 NuGet 包複製到本地 NuGet 倉庫中,可以使用以下命令: cp **/*.nupkg /Users/rainhu/advantech/mynuget/ 這會將所有找到的 .nupkg 檔案複製到指定的本地目錄 /Users/rainhu/advantech/mynuget/。 配置本地 NuGet 來源 要使用本地 NuGet 包,您需要將本地目錄添加為 NuGet 來源。在您的專案中,可以通過以下方式配置: ...

April 8, 2025 · 2 分鐘 · Rain Hu

基於 Ollama 和 LangChain 的 Naive RAG 實作(搭配 streamlit UI)

在此為確保程式碼的可執行性,使用了免費的模型,若要求性能,可以使用替代方案。 完整程式碼 Basic Moves 1. 載入文件 loader = WebBaseLoader(urls_list) documents = loader.load() 使用 WebBaseLoader 從給定的 URL 列表中載入文件。在這裡可以根據需求替換其它 Loader。 PyPDFLoader 用於 PDF 文件。 TextLoader 用於純文本文件。 2. 分割文件 pythonCopytext_splitter = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=7500, chunk_overlap=100) doc_splits = text_splitter.split_documents(documents) 文件分割是一個關鍵步驟。這裡使用 CharacterTextSplitter 並基於 tiktoken 編碼器進行分割。 參數說明: chunk_size: 定義每個 chunk 的最大 token 數。較大的 chunk 可能包含更多上下文,但可能降低檢索精度。 chunk_overlap: 定義相鄰塊之間的重疊 token 數。增加重疊可以幫助保持上下文連續性,但會增加記憶體需求。 替代方案: RecursiveCharacterTextSplitter: 可以更智能地處理文檔結構。 TokenTextSplitter: 直接基於標記進行分割,可能更準確但速度較慢。 3. 選擇 embedding 模型 pythonCopyembeddings = OllamaEmbeddings(model="mistral") 這裡使用 Ollama 的 Mistral 模型生成嵌入。 替代方案: OpenAI HuggingFace Gemini 4. 創建向量資料庫 pythonCopyvector_store = Chroma.from_documents( documents = doc_splits, embedding = embeddings, collection_name = "rag-chroma", ) 替代方案: FAISS (Meta 的) Milvus Pinecone 5. 建立 Retriever Interface retriever = vector_store.as_retriever() 可以通過設置參數 search_type 與 search_kwargs 來調整檢索行為。 6. 執行 RAG rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) 定義 RAG 鏈。可以通過修改 prompt 或使用不同的 LLM 來優化性能。 7. 查詢 return rag_chain.invoke(question) 調用 RAG 鏈針對輸入的問題返回答案。 Advanced Moves 加入 metadata 並進行篩選: loader = WebBaseLoader(urls_list) loader.requests_kwargs = {'verify':False} docs = loader.load() docs = [Document(page_content=doc.page_content, metadata={"source": doc.metadata['source']}) for doc in docs] # 在檢索時使用 metadata 篩選 retriever = vector_store.as_retriever(search_kwargs={"filter": {"source": "特定URL"}}) 加入 pre/post retrieval 處理: from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import LLMChainExtractor compressor = LLMChainExtractor.from_llm(llm) compression_retriever = ContextualCompressionRetriever( base_compressor=compressor, base_retriever=retriever ) 加入 rerank 提升回答的加權: from langchain.retrievers import EnsembleRetriever bm25_retriever = BM25Retriever.from_documents(documents) ensemble_retriever = EnsembleRetriever( retrievers=[retriever, bm25_retriever], weights=[0.5, 0.5] ) 改變 naive RAG 為 graph RAG: from langchain.graphs import NetworkxEntityGraph from langchain.indexes import GraphIndexCreator graph_creator = GraphIndexCreator( graph_type=NetworkxEntityGraph, include_embeddings=True ) graph = graph_creator.from_documents(documents) # 使用 graph RAG retrieved_nodes = graph.get_relevant_nodes(query)

July 30, 2024 · 2 分鐘 · Rain Hu

[Swift] UI Challenge

Challenge 1: Card Style struct ContentView: View { var body: some View { ZStack { Color(.systemMint) .ignoresSafeArea() VStack(alignment: .leading, spacing: 20.0){ Image("eva") .resizable() .aspectRatio(contentMode: .fit) .cornerRadius(15) .padding(.all) HStack { Text("Eva Hsu") .font(.largeTitle) .fontWeight(.semibold) .foregroundColor(.black) .padding() Spacer() VStack { HStack { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") } .foregroundColor(.orange) .font(.caption) Text("(Reviews 240,152)") } .padding() } Text("The best girl in the world.") .foregroundColor(.primary) .padding(.horizontal) HStack { Spacer() Image(systemName: "binoculars.fill") Image(systemName: "fork.knife") } .foregroundColor(.gray) .font(.caption) .padding() } .background(Rectangle() .foregroundColor(.white) .cornerRadius(15) .shadow(radius: 15)) .padding() } } }m

June 21, 2024 · 1 分鐘 · Rain Hu

[System Design] 系統設計概念與資源 System Design and Resources

系統設計的核心概念 System Design Key Concepts 可擴展性(Scalability) 延遲與吞吐量(Latency vs Throughput) CAP 定理(CAP Theory) ACID 交易(ACID Transactions)

March 26, 2024 · 1 分鐘 · Ashish Pratap Singh, Rain Hu
Oh! You closed up the window, so you cannot see raining

[Hugo] 使用 Hugo-notice

Shortcodes 介紹 Shortcodes 是內容檔案中的一個簡單片段,Hugo將使用預先定義的範本對其進行呈現。 除了更乾淨的 Markdown 外,Shortcodes 還可以隨時更新新的技術或標準。 Notice shortcodes 將以下程式碼加入到 Hugo 專案底下的 layouts/shortcodes/notice.html {{/* Available notice types: warning, info, note, tip */}} {{- $noticeType := .Get 0 | default "note" -}} {{/* Workaround markdownify inconsistency for single/multiple paragraphs */}} {{- $raw := (markdownify .Inner | chomp) -}} {{- $block := findRE "(?is)^<(?:address|article|aside|blockquote|canvas|dd|div|dl|dt|fieldset|figcaption|figure|footer|form|h(?:1|2|3|4|5|6)|header|hgroup|hr|li|main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video)\\b" $raw 1 -}} {{/* Count how many times we've called this shortcode and load the css if it's the first time */}} {{- if not ($.Page.Scratch.Get "noticecount") -}} <style type="text/css">.notice{--root-color:#444;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#c33;--warning-content:#fee;--info-title:#fb7;--info-content:#fec;--note-title:#6be;--note-content:#e7f2fa;--tip-title:#5a5;--tip-content:#efe}@media (prefers-color-scheme:dark){.notice{--root-color:#ddd;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#800;--warning-content:#400;--info-title:#a50;--info-content:#420;--note-title:#069;--note-content:#023;--tip-title:#363;--tip-content:#121}}body.dark .notice{--root-color:#ddd;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#800;--warning-content:#400;--info-title:#a50;--info-content:#420;--note-title:#069;--note-content:#023;--tip-title:#363;--tip-content:#121}.notice{padding:18px;line-height:24px;margin-bottom:24px;border-radius:4px;color:var(--root-color);background:var(--root-background)}.notice p:last-child{margin-bottom:0}.notice-title{margin:-18px -18px 12px;padding:4px 18px;border-radius:4px 4px 0 0;font-weight:700;color:var(--title-color);background:var(--title-background)}.notice.warning .notice-title{background:var(--warning-title)}.notice.warning{background:var(--warning-content)}.notice.info .notice-title{background:var(--info-title)}.notice.info{background:var(--info-content)}.notice.note .notice-title{background:var(--note-title)}.notice.note{background:var(--note-content)}.notice.tip .notice-title{background:var(--tip-title)}.notice.tip{background:var(--tip-content)}.icon-notice{display:inline-flex;align-self:center;margin-right:8px}.icon-notice img,.icon-notice svg{height:1em;width:1em;fill:currentColor}.icon-notice img,.icon-notice.baseline svg{top:.125em;position:relative}</style> <div><svg width="0" height="0" display="none" xmlns="http://www.w3.org/2000/svg"><symbol id="tip-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet"><path d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"/></symbol><symbol id="note-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet"><path d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></symbol><symbol id="warning-notice" viewBox="0 0 576 512" preserveAspectRatio="xMidYMid meet"><path d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></symbol><symbol id="info-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet"><path d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"/></symbol></svg></div> {{- end -}} {{- $.Page.Scratch.Add "noticecount" 1 -}} <div class="notice {{ $noticeType }}" {{ if len .Params | eq 2 }} id="{{ .Get 1 }}" {{ end }}> <p class="first notice-title"><span class="icon-notice baseline"><svg><use href="#{{- $noticeType -}}-notice"></use></svg></span>{{- i18n $noticeType -}}</p> {{- if or $block (not $raw) }}{{ $raw }}{{ else }}<p>{{ $raw }}</p>{{ end -}} </div> Classes 警告 {{< notice warning >}} 這是警告(warning) {{< /notice >}} ...

January 19, 2024 · 2 分鐘 · Rain Hu
Oh! You closed up the window, so you cannot see raining

[ML] 機器學習與統計學

Introduction to ML 統計學與機器學習差在哪裡? 同: 將資料(data)轉為資訊(info) 異: 有無強烈的人為事先假設 統計學 統計學是在資料分析的基礎上,研究如何測定、收集、整理、歸納和分析反映資料,以便給出正確訊息的科學。 機器學習 機器學習演算法是一類從資料中自動分析獲得規律,並利用規律對未知資料進行預測的演算法。 \(\begin{array}{lll} \text{Item} & \text{Statistics} & \text{Machine Learning}\\\hline \text{特性} & \text{伴隨事前假設,依賴明確規則,以模型定義資料關聯性,重視模型解釋性} & \text{幾乎無視前假設,不依賴明確規則,相信經驗}\\ & \text{事前假設(人)}\rightarrow\text{模型估計(機器)} & \text{特徵萃取(機器)}\rightarrow\text{網路建構(機器)} \\\hline \text{優點} & \text{模型可解釋} & \text{不須事先假設或了解資料關聯性}\\ & \text{推論有強烈理論根據} & \text{可抓取資料的所有(幾乎)複雜特徵}\\ & \text{符合事前假設前提下,可做更多的推論}\\ & \text{符合事前假設前提下,不需大量資料} \\\hline \text{缺點} & \text{所有推論接基於事前假設,常難以驗證假設的正確性} & \text{模型難以解釋(黑盒子)}\\ & \text{難以抓取資料中過於複雜的特徵} & \text{推論無強烈理論根據} \\\hline \text{專家} & \text{統計背景} & \text{資訊背景及統計背景} \\\hline \end{array}\) 結論 統計模型的重點是有合理的事前假設 在有合理假設之情況下,統計模型能發揮效力(即使資料量少) 機器學習的重點是大量有代表性的資料 在有大量有效資料之情況下,機器學習能發揮效力(即使人類對資料間的關聯之了解並不多) 何時使用統計方法? 何時使用機器學習? 資料關聯性清楚,容易給予合適的模型假設時,建議使用統計模型 資料無明確規則(如影像及語音辨識),且資料量夠多時,建議使用機器學習方法(可以佐以人為提示) 統計與機器學習類似的專有名詞 \(\begin{array}{ll} \text{Statistics} & \text{Machine Learning} \text{response, dependent variable} & \text{label} \\\hline \text{covariate, explanatory variable, independent variable} & \text{feature} \\\hline \text{model} & \text{network} \\\hline \text{parameter, coefficient} & \text{weight} \\\hline \text{fitting} & \text{learning} \\\hline \text{refression, classification} & \text{supervised learning} \\\hline \text{density estimation, cluster} & \text{unsupervised learning} \\\hline \end{array}\)

November 7, 2022 · 1 分鐘 · Rain Hu