HTML - Open link with new tab

方法如下:

<a href="某個網址" target="_blank" rel="noreferrer noopenner"> 
  New link
</a>

根據 google chrome 官方說明:

  • rel="noopener" prevents the new page from being able to access the window.opener property and ensures it runs in a separate process.
  • rel="noreferrer" has the same effect but also prevents the Referer header from being sent to the new page. See Link type “noreferrer”.

簡而言之,後面的 rel="noreferrer noopenner" 是安全性考量,避免新開的頁面如果是 malicious page 會影響到原本的頁面。不過新版的瀏覽器目前都默認 target="_blank" link 使用 rel=noopener

Reference

Links to cross-origin destinations are unsafe target=”_blank” 的安全性風險

React - React router with customized id

在 Route 的過程中,發現一個問題,那就是如何在跳轉到 /user 這個 link 的同時,透過 /user/:userid 這種方式將想傳遞的內容傳遞到 component 內呢?找到的方法如下:

  1. 定義 Route,後面的 <User /> 是要路由過去的 component,也就是需要取得 userid 的頁面
     <Route path="user/:userid" element={<User />} />
    
  2. 頁面跳轉的 Link,userid 是某個 dynamic 的變數,像如果 userid 是 1 的話,等同 <Link href="/user/1" />
     <Link href={"/user/"+ userid} />
    
  3. 在目標頁面(component),也就是 <User /> 內取得id
     import { useParams } from "react-router-dom";
        
     let { userid } = useParams();
    

Reference

React-Router v6 教学(附demo) React-Router doc

Go - Context

控制 Goroutine 的方式有 Waitgroup 和 Context,前面有講過 Waitgroup 簡單來說是可以指定一個數量,等到這個數量的 job 都執行完了之後再繼續執行主程式。

Context 的話,goroutine 內可能又有多個 goroutine,背景又有別的 goroutine,取消就會變得很麻煩,這就是 Context 常見的使用場景,在複雜的 goroutine 場景進行取消非常好用,又可以理解成:多個或有上下層關係的 goroutine 同步請求、處理請求、取消。

建立 Context 的方法:

  • context.Backgroud(), 較常使用
  • context.TODO()

With 函數(使用時需要從父 Context 衍生):

  • func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
  • func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
  • func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
  • func WithValue(parent Context, key, val interface{}) Context

WithTimeout,超時取消範例:

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	HttpHandler()
}

func HttpHandler() {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) 
        // cancel 其實沒被使用到 context 就結束了,但必須 defer cancel() 來避免 context leak
	defer cancel()
	deal(ctx)
}

func deal(ctx context.Context) {
	for i := 0; i < 10; i++ {
		time.Sleep(1 * time.Second)
		select {
		case <-ctx.Done(): // 三秒後context被關閉,執行此處
			fmt.Println(ctx.Err()) 
			return
		default: // 前三秒時
			fmt.Printf("deal time is %d\n", i)
		}
	}
}

WithCancel,取消範例:

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	go Talk(ctx)

	time.Sleep(10 * time.Second)
	cancel() // 十秒後閉嘴
	time.Sleep(1 * time.Second)
}

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	go Talk(ctx)

	time.Sleep(10 * time.Second)
	cancel()
	time.Sleep(1 * time.Second)
}

func Talk(ctx context.Context) {
	for range time.Tick(time.Second) {
		select {
		case <-ctx.Done():
			fmt.Println("我要閉嘴了")
			return
		default:
			fmt.Println("balabalabalabala")
		}
	}
}

Reference

【Go语言】小白也能看懂的context包详解:从入门到精通 用 10 分鐘了解 Go 語言 context package 使用場景及介紹

MySQL - Explicit Commit / Implicit Commit / Autocommit

資料庫提交數據的三種類型:

顯式提交 (Explicit Commit)

COMMIT 命令完成提交,例如:

select * from dept;
commit;

隱式提交 (Implicit Commit)

運行某些指令之後資料庫自動完成,不需要再做 COMMIT,例如:

CREATE TABLE Persons (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
);

隱式提交的指令有:CREATE TABLEDROP TABLE 等,這些指令各自被視作單一的 transaction,因此執行完畢做 ROLLBACK 不會有用。更多可以參考 Statements That Cause an Implicit Commit

自動提交 (Autocommit)

如果 autocommit mode 開啟的話,每一個 SQL statement 都將被視作單一的 transaction,不需要 COMMIT,會自動完成提交。MySQL 默認 autocommit mode 開啟。

可以用 SELECT @@autocommit 指令確認 autocommit mode 是否開啟,是的話值為 1。

Reference

autocommit, Commit, and Rollback MYSQL的COMMIT和ROLLBACK使用讲解

MySQL command category

常見的 Structured Query Language 指令有 Create, Drop, Insert 等,而這些指令又可以細分為幾個種類:

DDL (Data Definition Language)

這個種類的指令大多用來建立、變更、刪除資料庫物件的結構或 schema,例如:

  1. CREATE
  2. DROP
  3. ALTAR
  4. TRUNCATE
  5. RENAME

DQL – Data Query Language

一言以蔽之,用來查詢資料庫的資料,例如 SELECT。

DML – Data Manipulation Language

操作和修改資料庫中的資料,常見的有:

  1. INSERT
  2. UPDATE
  3. DELETE

DCL – Data Control Language

與權限、授權、許可相關的指令,例如:

  1. GRANT
  2. REVOKE

TCL – Transaction Control Language

與控制、管理事務(Transaction)相關,例如:

  1. BEGIN
  2. COMMIT
  3. ROLLBACK

Reference