---
# System prepended metadata

title: is gossip or rumors?
tags: [quest]

---

###### tags: `quest`

is gossip or rumors?
===


---
##### [2022-12-09] golang - nil interface ?
⠿ 解釋下面程式碼，第 9 行輸出會得到什麼？

```go=
package main

import "fmt"

func main() {
  var ptr *string = nil

  fmt.Printf("   StringIsNil(ptr) -> %v\n", StringIsNil(ptr))      // true
  fmt.Printf("InterfaceIsNil(ptr) -> %v\n", InterfaceIsNil(ptr))   // ??
}

func StringIsNil(v *string) bool {
  return v == nil
}

func InterfaceIsNil(v interface{}) bool {
  return v == nil
}
```
🎬 https://go.dev/play/p/CV-JWhmV-Jq


---
##### [2023-01-11] sql - migrate data to new table
⠿ 將 `actor` 表中血型為 `S` 的角色紀錄寫入 `actor_only_blood_s` 。

**資料表**：`actor`
| id   | name  | blood_type |
|:-----|:------|:-----------|
| 1    | luffy | F          |
| 2    | zoro  | XF         |
| 3    | nami  | X          |
| 4    | usopp | S          |
| 5    | sanji | S          |

**資料表**：`actor_only_blood_s`
| id   | name  |
|:-----|:------|
| 4    | usopp |
| 5    | sanji |

📝 https://www.sqlite.org/lang_insert.html
🎬 https://www.jdoodle.com/ia/C5W


---
##### [2023-01-12] sql - null comparison
⠿ 解釋下面程式碼，第 4~7 行輸出會得到什麼？

```sql=
SELECT
    1 = 1,         -- 1 <TRUE>
    1 = 0,         -- 0 <FALSE>
    NULL = NULL,   -- ?
    NULL <> NULL,  -- ?
    NULL = 1,      -- ?
    1 = NULL;      -- ?
```
📝 https://www.sqlite.org/nulls.html
🎬 https://www.jdoodle.com/ia/C6o


---
##### [2023-01-17] golang - implicit cast string to []byte 
⠿ 解析下面程式碼，第 10 行輸出會得到什麼？

```go=
package main

import "fmt"

func main() {
	var buffer []byte = nil
	var input string  = "foo"

	fmt.Printf("WriteBuffer_1() -> %v\n", string(WriteBuffer_1(buffer, input))) // foo
	fmt.Printf("WriteBuffer_2() -> %v\n", string(WriteBuffer_2(buffer, input))) // ??
}

func WriteBuffer_1(buf []byte, v string) []byte {
	return append(buf, []byte(v)...)
}

func WriteBuffer_2(buf []byte, v string) []byte {
	return append(buf, v...)
}
```
📝 https://cs.opensource.google/go/go/+/refs/tags/go1.19.5:src/log/log.go;l=115;drc=1c65b69bd1dbc930c6246877f6c21c81f2a60d55
🎬 https://go.dev/play/p/CLQaAWCc7ko


---
##### [2023-01-18] sql - update table from other table
⠿ 按 `id` 取 `contribution` 表的貢獻值欄位增加 `staff` 的薪水。

**資料表**：`staff`
| id<sup>`PK`</sup> | name  | salary |
|:------------------|:------|:-------|
| 1                 | luffy |  3,000 |
| 2                 | zoro  |  1,100 |
| 3                 | nami  |    300 |
| 4                 | usopp |    500 |
| 5                 | sanji |  1,000 |

**資料表**：`contribution`
| id<sup>`PK`</sup> | contribution |
|:------------------|:-------------|
| 1                 |          200 |
| 2                 |          100 |
| 3                 |          600 |
| 4                 |            0 |
| 5                 |           40 |

📝 https://www.sqlite.org/lang_update.html
📝 https://www.sqlite.org/lang_insert.html
🎬 https://www.jdoodle.com/ia/C61
🎬 https://www.jdoodle.com/ia/C63


---
##### [2023-02-01] lua - table contains `nil` elements
⠿ 解析下面程式碼，第 20-25, 28-33 行的區段分別會輸出什麼？


```lua=
local t = { 1, 2, 3, 4, 5, nil, 7 }

-- helper function for output
local function output(v)
  io.write(tostring(v))
end

-- print size of the table `t`
print(#t)                   -- output: 7

-- dump all elements with index 
do
  for i = 1, #t do
    output(t[i])
  end
  output('\n')              -- output: 12345nil7
end

-- dump all elements with ipairs 
do
  for i, v in ipairs(t) do
    output(v)
  end
  output('\n')              -- output: ??
end

-- dump all elements with pairs 
do
  for i, v in pairs(t) do
    output(v)
  end
  output('\n')              -- output: ??
end
```
📝 lua 7.3 – Stateless Iterators - https://www.lua.org/pil/7.3.html
🎬 https://www.jdoodle.com/ia/Co1
$~$
> 💡 下面程式碼有助於理解 pairs() 的行為。
```lua
print(next(t, 1)) -- output: 2   2
print(next(t, 2)) -- output: 3   3
print(next(t, 3)) -- output: 4   4
print(next(t, 4)) -- output: 5   5
print(next(t, 5)) -- output: 7   7
print(next(t, 6)) -- output: 7   7
print(next(t, 7)) -- output: nil
```


---
##### [2023-02-09] bitwise - count bit set (int32)
⠿ 計算 32 位元整數有幾個位元被設定。

```go=
package main

// see also: https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel

import (
	"fmt"
)

func main() {
	x := int32(123)

	fmt.Printf("%b\n", x) // 1111011

	x = (x & 0x55555555) + ((x >> 1) & 0x55555555)
	x = (x & 0x33333333) + ((x >> 2) & 0x33333333)
	x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f)
	x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff)
	x = (x & 0x0000ffff) + ((x >> 16) & 0x0000ffff)

	numOfOne := x
	fmt.Println(numOfOne) // 6 <--
}
```
📝 https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
🎬 https://go.dev/play/p/XICbjwVsg64

⠿ go 1.19+
```go=
package main

import (
	"fmt"
	"math/bits"
)

func main() {
	x := int32(123)

	fmt.Printf("%b\n", x) // 1111011

	// go 1.19+
	numOfOne := bits.OnesCount32(uint32(x))
	fmt.Println(numOfOne) // 6 <--
}
```
📝 https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/math/bits/bits.go;l=102
🎬 https://go.dev/play/p/qAIFvP14boN


---
##### [2023-02-15] golang - convert float value to string
⠿ 解析下面程式碼，第 13、14、18 行分別會輸出什麼？

```go=
package main

import (
	"bytes"
	"fmt"
	"strconv"
)

func main() {
	s := "3.1415926535897932384626433"

	f, _ := strconv.ParseFloat(s, 32)
	fmt.Println(f)        // ??
	fmt.Printf("%f\n", f) // ??

	var buf bytes.Buffer
	fmt.Fprint(&buf, f)
	fmt.Println(string(buf.Bytes())) // ??
}
```
📝 https://pkg.go.dev/fmt
🎬 https://go.dev/play/p/f8vZFnezTp-

> 💡 For floating-point values, width sets the minimum width of the field and precision sets the number of places after the decimal, if appropriate, except that for %g/%G precision sets the maximum number of significant digits (trailing zeros are removed). For example, given 12.345 the format %6.3f prints 12.345 while %.3g prints 12.3. The default precision for %e, %f and %#g is 6; for %g it is the smallest number of digits necessary to identify the value uniquely.


---
##### [2023-02-24] golang - holder singleton object
⠿ 說說下面程式碼，第27行使用 `holder` 型別的作用是什麼？為什麼不使用 `v.Store(&Foo{})`？

```go=
package main

import (
    "fmt"
    "sync/atomic"
)

var (
    singleton *atomic.Value = defaultSingleton()
)

func main() {
    f := Load()
    fmt.Printf("%#+v\n", f)
}

type Foo struct{}
type holder struct{ v *Foo }

func Load() *Foo {
    v := singleton.Load().(holder).v
    return v
}

func defaultSingleton() *atomic.Value {
    v := &atomic.Value{}
    v.Store(holder{v: &Foo{}})   // why don't just use `v.Store(&Foo{})` ?
    return v
}
```

🎬 https://go.dev/play/p/CzyqFrF37Je
📝 https://pkg.go.dev/sync/atomic#Value.Store
👉 https://github.com/uber-go/atomic/blob/df976f2515e274675050de7b3f42545de80594fd/error.go#L26-L28


---
##### [2023-03-01] golang - Blank Identifier (underscore) for interface checks
⠿ 說說下面程式碼，第7行使用空識別子(Blank Identifier)的作用是什麼？

```go=
package main

import (
    "fmt"
)

var _ fmt.Stringer = new(Foo)   // why declare by Blank Identifier?

func main() {
    f := new(Foo)
    fmt.Printf("Hello %s\n", f)
}

type Foo struct{}

func (f *Foo) String() string {
    return "foo"
}
```

🎬 https://go.dev/play/p/Y4x0pH0xfJb
📝 https://go.dev/doc/effective_go#blank_implements


---
##### [2023-04-21] lua - number arithmetic
⠿ 解析下面程式碼，第 9-10, 29-30 行的區段分別會輸出什麼？


```lua=
do
    local x = 0.1 + 2.8
    local y = 1.1 + 1.8

    print("do number arithmetic directly")
    print("x:", x, x * 100)   -- x:	2.9	290.0
    print("y:", y, y * 100)   -- y:	2.9	290.0

    print( (x==y) )           -- ?
    print( (x*100==y*100) )   -- ?
end

do
    local x = string.format("%0.1f", 0.1 + 2.8)
    local y = string.format("%0.1f", 1.1 + 1.8)

    print()
    print("print number with string.format()")
    print( (x==y) )          -- true
    print( (x*100==y*100) )  -- true
end

do
    local x = tonumber(string.format("%0.1f", 0.1 + 2.8))
    local y = tonumber(string.format("%0.1f", 1.1 + 1.8))

    print()
    print("print number with tonumber() and string.format()")
    print( (x==y) )          -- ?
    print( (x*100==y*100) )  -- ?
end
```
📝 Floating Point Math - https://0.30000000000000004.com
🎬 https://www.jdoodle.com/ia/GQ8
$~$
> 💡 下面程式碼有助於理解：
```lua
local x = string.format("%0.17f", 0.1 + 2.8)
local y = string.format("%0.17f", 1.1 + 1.8)
print("x:", x)   -- x:	2.89999999999999991
print("y:", y)   -- y:	2.90000000000000036
```


---
##### [2023-05-10] golang - detect integer arithmetic overflow
⠿ 解析下面程式碼，第 12 行會輸出什麼？

```go=
package main

import "fmt"

func main() {
	{
		sum := add(7, 8)
		fmt.Printf("sum: %+v\n", sum)  // 15
	}
	{
		sum := add(9223372036854775807, 9223372036854775807)
		fmt.Printf("sum: %+v\n", sum)  // ??
	}
}

func add(x, y int64) int64 {
	return x + y
}
```

📝 Integer overflow - https://go.dev/ref/spec#Integer_overflow
🎬 https://go.dev/play/p/vpfZi0e4ku7

👉 解決原理： https://github.com/JohnCGriffin/overflow/blob/master/overflow_impl.go#L11-L17
```go=
func add(a, b int64) (v int64, ok bool) {
        c := a + b
        if (c > a) == (b > 0) {
                return c, true
        }
        return c, false
}
```
🐾 相關套件：https://github.com/johncgriffin/overflow



---
##### [??] golang - reassign elements from a re-slice
⠿ 解析下面程式碼，第 17 行的`??`會輸出什麼？

```go=
package main

import "fmt"

func main() {
	var (
		buffer   = []byte{1, 2, 3, 4, 5}
		fragment = buffer[2:]
	)

	fmt.Printf("%+v\n", buffer)   // [1 2 3 4 5]
	fmt.Printf("%+v\n", fragment) // [3 4 5]

	buffer[4] = 9

	fmt.Printf("%+v\n", buffer)   // [1 2 3 4 9]
	fmt.Printf("%+v\n", fragment) // [3 4 ??]
}
```
📝 Go Slices: usage and internals - https://go.dev/blog/slices-intro
🎬 https://go.dev/play/p/qrmjJ_CHST8
> 💡 Slicing does not copy the slice’s data. It creates a new slice value that points to the original array. This makes slice operations as efficient as manipulating array indices. Therefore, modifying the elements (not the slice itself) of a re-slice modifies the elements of the original slice.


---
##### [??] javascript - throw...
⠿ 解析下面程式碼，第 68 行的`??`會輸出什麼？


```javascript=
function throwError() {
    try {
        throw new Error('an error occurred')
        
        console.log('throwError:: nothing occurred')
    } catch (err) {
        console.error(`throwError:: ${err}`)
    }
}

function throwAny() {
    try {
        throw 'a message thrown'
        
        console.log('throwAny:: nothing occurred')
    } catch (err) {
        console.error(`throwAny:: ${err}`)
    }
}

function throwFalse() {
    try {
        throw false
        
        console.log('throwFalse:: nothing occurred')
    } catch (err) {
        console.error(`throwFalse:: ${err}`)
    }
}

function throwNull() {
    try {
        throw null
        
        console.log('throwNull:: nothing occurred')
    } catch (err) {
        console.error(`throwNull:: ${err}`)
    }
}

function throwUndefined() {
    try {
        throw undefined
        
        console.log('throwUndefined:: nothing occurred')
    } catch (err) {
        console.error(`throwUndefined:: ${err}`)
    }
}

function throwVoid() {
    try {
        throw void
        
        console.log('throwVoid:: nothing occurred')
    } catch (err) {
        console.error(`throwVoid:: ${err}`)
    }
}

// main
(function() {
    throwError()       // output:  throwError:: Error: an error occurred
    throwAny()         // output:  throwAny:: a message thrown
    throwFalse()       // output:  throwFalse:: false
    throwNull()        // output:  throwNull:: null
    throwUndefined()   // output:  throwUndefined:: undefined
    throwVoid()        // output:  ??
})()
```
🎬 https://www.jdoodle.com/ia/1eaH
