fabric-2.fabric自定义与实践

计划配置一个4个节点的网络,三个节点模拟IOT设备,一个代表公司节点

主要工作

  1. 创建了一个拥有两个org的通道
  2. 自定义了一个网络,org1拥有三个节点,org2拥有1个节点
  3. 用go语言自定义了chaincode并编译
  4. 在网络上安装通道,执行链码

fabric环境变量

  • 为了使用cryptogen等工具
    1
    2
    3
    cd fabric-samples/bin
    sudo echo export PATH=\$PATH:$(pwd) >> ~/.bashrc
    source ~/.bashrc
阅读更多

fabric-1.fabric环境配置与搭建

准备工作

  • 需要安装git,curl,docker,docker compose
    1
    sudo apt install docker-compose
  • 给当前用户运行docker的权限
    1
    2
    3
    4
    5
    6
    7
    8
    ## 创建docker组
    sudo groupadd docker
    ## 将当前用户加入docker组
    sudo usermod -aG docker tt
    ## 重启服务
    sudo service docker restart
    ## 刷新docker成员
    newgrp docker

go环境的安装

1
2
3
4
5
6
7
8
9
10
wget https://golang.google.cn/dl/go1.19.linux-amd64.tar.gz
tar -zxvf go1.19.linux-amd64.tar.gz
sudo mv go /usr/local/
sudo tee -a ~/.bachrc <<-'EOF'
export GOROOT=/usr/local/go
## export GOPATH=/home/go/goProject
export GOPROXY=https://goproxy.cn
export PATH=$PATH:$GOROOT/bin
EOF
source /etc/profile

fabric的安装

阅读更多

LeetCode-14

927. 三等分

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
class Solution {
public:
vector<int> threeEqualParts(vector<int>& arr) {
int sum = countOne(arr);
int len = arr.size();
if(sum % 3 != 0) {
return {-1,-1};
}
if(sum == 0) {
return {0, len -1};
}

int p1,p2,p3;
p1 = p2 = p3 = 0;
int i = 0;
int cur = 0;
while(i < len) {
if(arr[i] == 1) {
if(cur == 0) {
p1 = i;
} else if(cur == sum/3) {
p2 = i;
} else if(cur == 2*sum/3) {
p3 = i;
}
cur++;
}
i++;
} //把1平均分成3份,p1 p2 p3分别找到三段的第一个1的位置
// printf("%d %d %d\n", p1, p2, p3);
int x = p1,y = p2,z = p3;
int farclen = len - p3;
if(p1 + farclen > p2 || p2 + farclen > p3) {
return {-1, -1};
}
while(x < p2 && y < p3 && z < len) {
if(arr[x] != arr[y] || arr[y] != arr[z]) {
return {-1, -1};
}
x++;y++;z++;
}
// printf("%d %d %d\n", x, y, z);
return {p1+farclen-1, p2+farclen};
}
int
countOne(vector<int>& arr) {
int count = 0;
for(int a : arr) {
count += a;
}
return count;
}
};

难,看懂解析思路后才写出来的

刚开始的思路是找0,把1分成了n段,取n/3 , 2n/3和 n段后面的0,然后向右移动双指针比较

后来发现有超级长的输入,超时了

解析的思路与我刚好相反,先数1的个数,如果是0或者不能被3整除,说明不能分成三段

1的个数为n,找到第0 n/3 2n/3个1,记为p1, p2, p3

p3到后末尾的长度就是三个子串的长度,如果p1 或 p2 + 字串长度分别大于p2 p3,说明无解

然后向后比较,若后面的数完全相同则有解

阅读更多

LeetCode-15

904. 水果成篮

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
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int len = fruits.size();
vector<int> v(len);
int i = 0;
int cur = fruits[i];
i++;
int max_diff = 1;
int typea = fruits[0], typeb = -1, typec = -1;
vector<int> last(len+1);
int curr = 0;
int j = 1;
while(j < len) {
while(j < len && fruits[j] == fruits[curr]) {
j++;
}
last[j] = curr;
curr = j;
j++;
}
while(i < len) {
int diff = 1;
typeb = typec = -1;
while(i < len) {
if(fruits[i] != typea && fruits[i] != typeb) {
if(typeb == -1) {
typeb = fruits[i];
} else if(typec == -1) {
typec = fruits[i];
}
}
if(typec == -1) {
diff++;
} else {
break;
}
i++;
}
max_diff = diff > max_diff ? diff : max_diff;
if(i-1 >= 0 && i < len){
typea = fruits[i-1];
i = last[i]+1;
}
}
return max_diff;
}
};

想法很简单,就是从左往右遍历,数当前遇到了几种水果,当遇到第三种水果后,更新一下装入水果的最大值,三种水果记录为typea, typeb, typec
然后回溯,找到前一个节点在左侧最后一个typea后第一次出现的位置(其实也是typea最后出现的位置的后两个位置)

优化(空间,放弃last数组)

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
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int len = fruits.size();
vector<int> v(len);
int i = 0;
int cur = fruits[i];
i++;
int max_diff = 1;
int typea = fruits[0], typeb = -1, typec = -1;
while(i < len) {
int diff = 1;
typeb = typec = -1;
int lasta = i-1, lastb = 0;
while(i < len) {
if(fruits[i] != typea && fruits[i] != typeb) {
if(typeb == -1) {
typeb = fruits[i];
} else if(typec == -1) {
typec = fruits[i];
}
}
if(fruits[i] == typea) {
lasta = i;
} else if(fruits[i] == typeb) {
lastb = i;
}
if(typec == -1) {
diff++;
} else {
break;
}
i++;
}
max_diff = diff > max_diff ? diff : max_diff;
if(i-1 >= 0 && i < len){
if(fruits[i-1] == typea) {
i = lastb + 2;
} else if(fruits[i-1] == typeb) {
typea = typeb;
i = lasta + 2;
}
// printf("%d, %d, %d\n", i, lasta, lastb);
}
}
return max_diff;
}
};

1441. 用栈操作构建数组

阅读更多

LeetCode-13

1640. 能否连接形成数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
bool canFormArray(vector<int>& arr, vector<vector<int>>& pieces) {
int arr_map[105] = {0};
int len_arr = arr.size();
for(int i = 0; i < len_arr; i++) {
arr_map[arr[i]] = i+1;
}
int pie_len = pieces.size();
for(int i = 0; i < pie_len; i++) {
int i_len = pieces[i].size();
int diff = arr_map[pieces[i][0]];
if(diff == 0) {
return false;
}
for(int j = 1; j < i_len; j++) {
if(diff != arr_map[pieces[i][j]] - j) {
return false;
}
}
}
return true;
}
};

4ms,和最快的思路刚好相反,用map存储arr的index,最快的思路是反过来,用map存一个piece的第一个index

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
bool canFormArray(vector<int>& arr, vector<vector<int>>& pieces) {
int arr_map[105] = {0};
int len_arr = arr.size();
int pie_len = pieces.size();
for(int i = 0; i < pie_len; i++) {
arr_map[pieces[i][0]] = i+1;
}
int i = 0;
while(i < len_arr) {
int row = arr_map[arr[i]];
if(row == 0) return false;
vector<int>& subv = pieces[row-1];
int i_len = subv.size();
for(int j = 0; j < i_len; j++, i++) {
if(arr[i] != subv[j]) {
return false;
}
}
}
return true;
}
};

707. 设计链表

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
struct List {
List *next;
int val;
List(int val0, List* next0 = nullptr):val(val0), next(next0) {}
};

class MyLinkedList {
private:
List *root;
List *tail;
int size;
inline List* getNode(int& index) {
List *move = root;
while(index > 0 && move->next != nullptr) {
move = move->next;
index--;
}
return move;
}
public:
MyLinkedList() {
root = new List(0);
tail = root;
size = 0;
}

int get(int index) {
List *move = getNode(index);
return (move->next == nullptr) ? -1 : move->next->val;
}

void addAtHead(int val) {
List* node = new List(val, root->next);
root->next = node;
if(root == tail) {
tail = node;
}
size++;
}

void addAtTail(int val) {
List* node = new List(val, tail->next);
tail->next = node;
tail = node;
size++;
}

void addAtIndex(int index, int val) {
List *move = getNode(index);
if(index > 0) {
return;
}
List* node = new List(val, move->next);
move->next = node;
if(move == tail) {
tail = node;
}
size++;
}

void deleteAtIndex(int index) {
List *move = getNode(index);
List *target = move->next;
if(target != nullptr) {
move->next = target->next;
if(target == tail) {
tail = move;
}
delete target;
size--;
}
}
};
阅读更多

qq.md

我的QQ

1
2
3
"""
-... .- . -.. --. .... -.-. .--- -... -...
"""

实习笔记-1

px dp sp 的区别

px 其实就是像素单位,比如我们通常说的手机分辨列表800*400都是px的单位
sp 同dp相似,还会根据用户的字体大小偏好来缩放
dp 虚拟像素,在不同的像素密度的设备上会自动适配

隐藏状态栏任务栏

在api30之前

1
getWindow().getDecorView().setSystemUIVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN)
阅读更多

实习笔记-4

ImageView的参数

1
android:adjustViewBounds="true"

对应源码

1
2
3
4
5
6
7
@android.view.RemotableViewMethod
public void setAdjustViewBounds(boolean adjustViewBounds) {
mAdjustViewBounds = adjustViewBounds;
if (adjustViewBounds) {
setScaleType(ScaleType.FIT_CENTER);
}
}

应用场景

  • 当宽高有且仅有一个设置为wrapContent的时候是有用,指定一个宽or高,再根据drawable的比例确定另一个高/宽的值
阅读更多

实习笔记-3

在安卓中显示gif图片

使用WebView

1
2
3
4
5
6
<WebView
android:id="@+id/runWebView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
1
2
3
4
5
6
7
8
runWebView.loadDataWithBaseURL(null,
"<html>
<body bgcolor='#f3f3f3'>
<div align=center>
<IMG src='file:///android_asset/run.gif'/>
</div>
</body>
</html>", "text/html", "UTF-8",null);

实现底部状态栏

使用recyclerview + gridlayoutmanager

阅读更多