ONE NOTE

Rage, rage against the dying of the light.

Some boilerplate of javascript.

debounce()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function debounce(fn, wait) {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn();
}, wait);
};
}
function test() {
console.log("hello");
}
let myFn = debounce(test, 1000);
myFn();
myFn();
myFn();
myFn();

sleep()

sleep() can only use in an async function , and the sleep() mast marked with await

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async function sleep(delay) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, delay);
});
}

// how to use it
async function test() {
console.log("start");
await sleep(3000);
console.log("execute");
}

test();

A simple Pubsub

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
class PubSub {
constructor() {
this.topics = {};
}
sub(topic, callBack) {
if (!this.topics[topic]) {
this.topics[topic] = [callBack];
} else {
this.topics[topic].push(callBack);
}
}
unsub(topic, callBack) {
if (!this.topics[topic]) return;
this.topics[topic] = this.topics[topic].filter((item) => {
return item !== callBack;
});
}
subOnce(topic, callBack) {
function fn() {
callBack();
this.off(topic, fn);
}
this.sub(topic, fn);
}
pub(topic, ...params) {
this.topics[topic] && this.topics[topic].forEach((fn) => fn.apply(this, params));
}
}

Implement a keyword function new

面向对象编程-javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function myNew(fn, ...args) {
let obj = Object.create(fn.prototype);
let res = fn.call(obj, ...args);
if (res && (typeof res === "object" || typeof res === "function")) {
return res;
}
return obj;
}

function Man(age, name) {
console.log(this);
this.age = age;
this.name = name;
}

const obj = myNew(Man, 18, "イフ");
console.log(obj.__proto__);

SetInterval

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function mySetInterval(fn, time = 1000) {
let timer = null,
isClear = false;
function interval() {
if (isClear) {
isClear = false;
clearTimeout(timer);
return;
}
fn();
timer = setTimeout(interval, time);
}
timer = setTimeout(interval, time);
// to convenient, use a fallback instead of intervalId
return () => {
isClear = true;
};
}

reference

zhihu

个人认为和js,py不同的地方

菜鸟教程

数组

1
2
3
4
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
// 编译器确定长度
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

切片(可变数组)

1
2
3
4
5
6
7
8
9
10
11
// init
s :=[] int {1,2,3 }
s :=make([]int,len,cap)

// 截取,和py一致
numbers[1:4]

// append() and copy()
var numbers []int
numbers = append(numbers, 0)
copy(numbers1,numbers)

指针

1
2
3
4
5
6
7
8
9
10
11
i := 8
f := 3.00
var ip *int
var fp *float64
// 取地址
ip = &i
fp = &f
fmt.Printf("%d\n", *ip)
fmt.Printf("%f\n", *fp)
fmt.Printf("%x\n", ip)
fmt.Printf("%x\n", fp)

map集合

1
2
3
4
5
6
7
8
m := map[string]int{
"ゼロ": 0,
}
m["いち"]=1
m["に"]=2
m["さん"]=3

delete(m,"ゼロ")

range遍历

1
2
3
4
5
6
7
8
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
for i, v := range pow {
// do somethings
// i,v是索引和值
}
}

函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func sum(s string, nList ...int) int {
// 类似es6的拓展运算符,以切片形式接受变长参数
fmt.Println("received vars:", s, nList)
var res int = 0
for _, v := range nList {
res += v
}
return res
}

func main() {
arr := []int{1, 2, 3, 4}
// 类似es6的拓展运算符
res := sum("hello", arr...)
fmt.Println("result of sun(): ", res)
fmt.Println()

res = sum("hello", arr[0], arr[1])
fmt.Println("result of sun(): ", res)
}

类型转换

1
2
a := int 16
b := float64 = float64(a)

字符串类型转换

1
2
3
4
5
6
7
8
// str -> int
var str string = "10"
var num int
num, _ = strconv.Atoi(str)

// int -> str
num := 123
str := strconv.Itoa(num)

接口类型变量

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
// init
type Phone interface {
call(param int) string
takephoto()
}

type Huawei struct {
}

func (huawei Huawei) call(param int) string{
fmt.Println("i am Huawei, i can call you!", param)
return "damon"
}

func (huawei Huawei) takephoto() {
fmt.Println("i can take a photo for you")
}


func main() {
phone := Phone
phone = new(Huawei)
phone.takephoto()
r := phone.call(50)
fmt.Println(r)
}

关键字defer

defer关键字标注的语句会在return之前调用.

如果有多个defer表达式,调用顺序类似于栈,越后面的defer表达式越先被调用。

1
2
3
4
5
6
7
// defer表达式可能会在设置函数返回值之后,在返回到调用函数之前,修改返回值,使最终的函数返回值与你想象的不一致。
func f() (result int) {
defer func() {
result++
}()
return 0
}

go并发

这个我觉得是比较有意思的,通过并发和channel使得多线程很方便

通道chan

通道(channel)是用来传递数据的一个数据结构。

通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。

默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须有接收端相应的接收数据.

带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
c <- x
fmt.Printf("trans %d\n", x)
time.Sleep(100 * time.Millisecond)
x, y = y, y+1
}
close(c)
}

func main() {
c := make(chan int, 5)
go fibonacci(2*cap(c), c)
time.Sleep(5 * time.Second)
for i := range c {
// 这里会阻塞fibonacci线程
time.Sleep(1 * time.Second)
fmt.Printf("recive %d\n", i)
}
}

输出应该是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
trans 0
trans 1
trans 2
trans 3
trans 4
trans 5
recive 0
trans 6
recive 1
trans 7
recive 2
trans 8
recive 3
trans 9
recive 4
recive 5
recive 6
recive 7
recive 8
recive 9

包管理

go的包管理有些麻烦,我在这里也摸了大坑.

go1.11以后增加了module模式,由环境变量GO111MODULE控制

非mod模式

  • 此时的go没有项目的概念,非常杂乱.
  • GOROOTGOPATH是两个重要的环境变量.导入包时,在上面两个路径下的src目录寻找模块.
  • 如果想自定义模块,必须放在$GOPATH/src下才能导入

mod模式

  • 项目下的go.mod类似package.json,requirements.txt,pom.xml
  • 同项目下的module可以直接引用,不需要src目录.
  • 依赖管理用go mod系列指令文档

日本语-第五弹

文法

  • 名詞「发音同お」 動詞
    • 李さんは 毎日「まいにち」 コーヒー を 飲みます「のみます」
    • 私は 毎日 新聞「しんぶん」 を 読みます「よみます」
  • 名詞「场所」 動詞
    • 存在场所用に 动词进行场所用で
    • 李さんは 図書館「としょかん」で 勉強します「べんきょうします」
  • 名詞 名詞 「若干名词作选择」
    • 私は 毎朝「まいあさ」 パンか お粥「おかゆ」を 食べます「たべます」
    • 休みは 月曜日「げつようび」か 日曜日です
  • 名詞を ください 「please give me …」
    • コーラと ケーキを ください。 「cola and cake pleae.」
    • 申込書「もうしこみしょ」を ください。
    • この本を ください。

某人一天的生活

起きます「おきます」

窓「まど」を 開きます「開く/ひらく」

顔「かお」を 洗います 「洗う/あらう」

歯「は」を磨きます「磨く/みがく」

髪「かみ」を とかします 「comb hair」

服を 着ます 「着る/きる」

お茶「おちゃ」を 入れます「いれます」「make tea」

お茶を 飲みます

ご飯を 食べます

新聞を 読みます「よみます」

靴「くつ」を はきます

ドア「door」を 閉めます「しめます」

「すずめの戸締まり」「すずめのとじまり」

鍵「かぎ」を かけます「lock it」

ごみを 出し「だし」ます「put out the trash」

会社へ 行きま

切符を 買います「きっぷをかいます」

雑誌を 読みます

音楽「おんがく」を 聞きます「ききます」

表达词

  • そうですか
  • そうですね
  • じゃあ
  • しつれいします
  • いってらっしゃい
  • いってまいりまうす「我走了(正式)」
  • いってきます「我走了」
  • ただいま/おかえりなさい
  • いらっしゃいませ
  • かしこまりました「我明白了,敬语」

笔试题

一共五题,第一道简单/普通难度,第二道普通难度,三四五大概是普通/困难吧.

分组交换链表

一个链表两个一组,前后两组交换,递归

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
class ListNode {
int val;
ListNode next = null;
}

public class Solution {
public ListNode reorderList(ListNode head) {
// 跳出
if (head == null) {
return head;
} else if (head.next == null) {
return head;
} else if (head.next.next == null) {
return head;
} else if (head.next.next.next == null) {
return head;
}
// 递归到最后
ListNode nextHead = reorderList(head.next.next.next.next);
ListNode thirdNode = head.next.next;
thirdNode.next.next = head;
head.next.next = nextHead;
return thirdNode;
}
}

可能的字符串

在每个字符串中选择一个字符,组成所有自负不重复的子字符串

例如 ab,ca,ccb –> acb , bac

很明显用回溯算法,但是没写出来,只好用暴力解法,结果超时.

下面是一个四不像.

edit : 第二天再写,只花了五分钟就改好了(果然还是考试时太着急了点),下面是成品(没有跑太多测试):

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
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

public class Solution {

public int result = 0;
public int sumFloor;

public List<String> handleInput() {
List<String> list = new ArrayList<String>();
// 输入handle
Scanner in = new Scanner(System.in);
int n = in.nextInt();
in.nextLine();
for (int i = 0; i < n; i++) {
list.add(in.nextLine());
}
in.close();
return list;
}

public int findSubString(List<String> ss) {
Set<Character> stack = new HashSet<>();
sumFloor = ss.size();
backstack(0, stack, ss);
return result;
}

// 回溯算法
public void backstack(int floor, Set<Character> stack, List<String> ss) {
// 跳出条件
if (floor == sumFloor) {
result++;
return;
}
// 遍历可以放入stack的元素
for (char c : ss.get(floor).toCharArray()) {
if (stack.contains(c)) {
return;
} else {
stack.add(c);
backstack(floor + 1, stack, ss);
stack.remove(c);
}
}
}

public static void main(String[] args) {
Solution foo = new Solution();
List<String> ss = new ArrayList<>();
ss.add("ab");
ss.add("ca");
ss.add("ccb");
System.out.println(foo.findSubString(ss));
}
}

后记

算法题挺久没刷了,手生了.

leetcode的题目都是写接口,对手动处理输入不熟悉.

文法(ぶんぽう)

  • 名詞(めいし) (助词发音e) 動詞(どうし)

    • 吉田さんは 中国へ 行きます
    • 森さんは 日本へ 帰り(かえり)ます
    • 李さんは どこへ 行きましたか
    • 昨日、どこへ 行きましたか
  • 名詞「場所」 から 動詞

    • 李さんは 先月「せんげつ」 北京から 来ました「きました」
  • 名詞「人」 動詞

    • 小野さんは 友達と 帰りました
    • 李さんは どれと 日本へ 来ましたか
  • 名詞「交通工具」 動詞

    • 上海まで 飛行機「ひこうき」で いきます
    • 私は パスで 家へ 帰ります
  • 名詞から 名詞まで 動詞

    • 李さんは 駅「えき」から アパートまで 歩いて「あるいて」 帰りました

表达词

1.たしか 不确定的感觉,似乎

2.です 省略

3.いえ/うち 房子/家庭

4.まっすぐ 直接

5.それ それは お疲れ様でした\

6.お疲れ様でした「おつかれさまでした」 辛苦了,再见的时候可以用

7.最終電車「さいしゅうでんしゃ」/終電「しゅうでん」 末班车

今天修改sudoers文件的时候,由于没有用visudo导致文件损坏(血的教训),没法sudo了,折腾了一番。

本来打算直接su root的,可惜实在记不得密码了

后来打算用pkexec,但是遇到了polkit-agent-helper-1: error response to policykit daemon: gdbus.error:org.freedesktop.policykit1.error.failed: no session for cookie的错误

好在下面这篇博文帮大忙了!

链接Ubuntu改坏sudoers后无法使用sudo的解决办法

另外以后不能随便用vim改重要的配置文件!

动词分类与变化

动词特点

日语动词都是以「う」段假名结尾的

动词三分类

  • 不是以「る」为结尾的动词都是“一类动词(五段动词)。
  • い段/え段+る 是二类动词。
  • か变,さ变,属于特殊变化。

规律

ます型的过去式与否定

过去:ました

否定:ません

过去否定:ませんでした

名词相关语法

時間に 动词

表示事件发生的时间,有时候也不用加に

時間 から 時間 まで 动词

表示动作持续时间

から:从

まで:到

いつ 动词ますか

询问什么时候

examples

A:毎日(まいにち)、何時(なんじ)に 寝(ね) ますか
B:十一時(じゅういちじ)三十分(さんじゅぶん)寝ます

A:昨日(きのう)、何時から 何時まで 働き(はたらき)ましたか
B:九時(くじ)から 六時(ろくじ)まで 働きました

A:先週(せんしゅ) 休み(やすみ)ましたか?
B:いええ、休みませんでした

A:試験(しけん)は いつ 始まりますか?
B:来週(らいしゅ)の 木曜日(もくようび)です。