###### 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