01-Flutter-快速入门实战

flutter

  • everything is a widget

widget

在flutter中,所有看得见的看不见的东西都是widget

目录结构

  • android:
  • ios:
  • lib: dart文件,业务逻辑
  • lib/main.dart: 入口
  • pubspec.yaml: 工程信息以及依赖
阅读更多

22-Gradle

核心概念

  • 项目
    • Gradle项目是一个可以构建的软件,例如应用程序或库。
    • 包括一个根项目和任意数量的子项目。
  • 构建脚本
    • 构建脚本向 Gradle 详细介绍了构建项目所需采取的步骤。
    • 每个项目可以包含一个或多个构建脚本。
  • 依赖管理
    • 依赖管理是一种用于声明和解析项目所需的外部资源的自动化技术。
    • 每个项目通常都包含许多外部依赖项,Gradle 将在构建过程中解决这些依赖项。
  • 任务
    • 任务是基本的工作单元,例如编译代码或运行测试。
    • 每个项目都包含在构建脚本或插件中定义的一个或多个任务。
  • 插件
    • 插件用于扩展 Gradle 的功能,并可选择向项目贡献任务。

Gradle 项目结构

文件/目录名称 作用
gradlew/gradlew.bat Gradle 包装脚本
build.gradle(.kts) 项目的 Gradle 构建脚本
settings.gradle(.kts) Gradle 设置文件用于定义根项目名称和子项目
src 项目/子项目的源码、资源

使用gradle/gradlew编译

  • 编译

    1
    ./gradlew build
  • 编译单个任务

    1
    2
    ./gradlew :taskname
    ./gradlew taskname

    编译单个任务以及全部依赖

  • 编译多项目工程中的任务

    1
    2
    ./gradlew :subproject:taskName
    ./gradlew subproject:taskName

    :相当于分隔符,第一个冒号可以省略

  • 清理产物

    1
    ./gradlew clean
  • 执行多个任务

    1
    ./gradlew clean build
阅读更多

24青岛

牛客刷题-1

小米2019秋招安卓开发笔试题(B)

21. 最少立方数之和

给出一个数字N(0<N<1000000),将N写成立方数和的形式,求出需要的最少立方数个数。
例如N=17,1+8+8 = 17,最少需要3个立方数,则输出3。
N= 28,1+1+1+1+8+8+8=28, 需要7个立方数,1+27=28,需要2个立方数,所以最少立方数为2,则输出2。

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
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
private static final List<Integer> cubs;
private static final int cubNum;
static {
cubs = new ArrayList<Integer>();
for(int i = 1; i*i*i <= 1000000; i++) {
cubs.add(i*i*i);
}
cubNum = cubs.size();
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int n = in.nextInt();
int index = Collections.binarySearch(cubs, n);
if(index < 0) {
index = -index - 2;
}
if(index < 0) {
throw new RuntimeException("unreachable");
}
int[] dp = new int[n+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for(int j = 1; j <= index+1; j++) {
for(int i = cubs.get(j-1); i <= n; i++) {
dp[i] = Math.min(dp[i], dp[i - cubs.get(j-1)] + 1);
}
}
System.out.println(dp[n]);
}
}
}

完全背包,从所有立方数里选数,取数目最小的情况

资产包打包

阅读更多

LeetCode-35

518. 零钱兑换 II

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int change(int amount, vector<int>& coins) {
int n = coins.size();
vector<int> dp(amount+1);
dp[0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = coins[i-1]; j <= amount; j++) {
dp[j] += dp[j-coins[i-1]];
}
}
return dp[amount];
}
};

322. 零钱兑换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
int n = coins.size();
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
for(int i = 1; i <= n; i++) {
for(int j = coins[i-1]; j <= amount; j++) {
if(dp[j - coins[i-1]] != INT_MAX)
dp[j] = min(dp[j], dp[j - coins[i-1]] + 1);
}
}
return dp[amount] == INT_MAX ? -1 : dp[amount];
}
};

25. K 个一组翻转链表

啊?真的是困难吗

阅读更多

01-Binder

看源码的时候可以用uml图辅助理解

多进程

为什么多进程

  • 突破内存限制:Android系统在内存不足时,会优先杀占用内存多的进程
  • 功能稳定性:把一些功能放到独立的进程中,保证进程功能的纯粹性和稳定性
  • 规避系统内存泄漏:独立的WebView进程阻隔内存泄漏问题
  • 隔离风险:不稳定功能放到子进程,保证主进程的稳定性

Android中的进程间通信

  • Binder
    • aidl
  • Socket
  • 管道:handler
  • 共享内存
    • fresco,mmkv(匿名)
  • 信号:
    • ANR监控
    • matrix、xcrash、友盟apm
阅读更多

LeetCode-排序

复习排序算法

  • 稳定性容易记错的是选择排序
    • 选择排序是从未排序中选择最小的,直接与未排序的第一个交换,所以不稳定
    • 选择排序是从未排序中选择最小的,插入到已排序的后面,就是稳定的

先手写一遍常见排序算法

  • 比较排序
    • 交换排序
      • 冒泡
      • 快排
    • 插入排序
      • 简单插入
      • 希尔排序
    • 选择排序
      • 简单选择
      • 堆排序
    • 归并排序
      • 二路归并
      • 多路归并
  • 非比较排序
    • 计数排序
    • 桶排序
    • 基数排序
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#include <iostream>
#include <bits/stdc++.h>
#include <random>
using namespace std;

template <typename T>
void printVec(const vector<T>& vec, function<string(const T&)> toString);

template<typename T>
void bubbleSort(vector<T>& vec, function<int(const T&, const T&)> compare) {
int len = vec.size();
for(int i = 0; i < len; i++) {
for(int j = 0; j < len - i - 1; j++) {
if(compare(vec[j], vec[j+1]) > 0) {
swap(vec[j], vec[j+1]);
}
}
}
}

template<typename T>
void selectSort(vector<T>& vec, function<int(const T&, const T&)> compare) {
int len = vec.size();
for(int i = 0; i < len; i++) {
int minIndex = i;
for(int j = i+1; j < len; j++) {
if(compare(vec[minIndex], vec[j]) > 0) {
minIndex = j;
}
}
swap(vec[i], vec[minIndex]);
}
}

template<typename T>
void stableSelectSort(vector<T>& vec, function<int(const T&, const T&)> compare) {
int len = vec.size();
for(int i = 0; i < len; i++) {
int minIndex = i;
for(int j = i+1; j < len; j++) {
if(compare(vec[minIndex], vec[j]) > 0) {
minIndex = j;
}
}
T t = vec[minIndex];
for(int j = minIndex; j > i; j--) {
vec[j] = vec[j-1];
}
vec[i] = t;
}
}

template<typename T>
void insertSort(vector<T>& vec, function<int(const T&, const T&)> compare) {
int len = vec.size();
for(int i = 0; i < len-1; i++) { // 下面是i+1,这里要len-1
for(int j = i+1; j > 0; j--) {
if(compare(vec[j], vec[j-1]) < 0) {
swap(vec[j], vec[j-1]);
} else {
break;
}
}
}
}


template<typename T>
void mergeSort(vector<T>& vec, function<int(const T&, const T&)> compare, int start, int end) {
if(end - start <= 1) return;
int mid = (end - start) / 2 + start;
mergeSort(vec, compare, start, mid);
mergeSort(vec, compare, mid, end);
// merge
vector<T> tmp(end - start);
int cur = 0, i = start, j = mid;
while(i < mid && j < end) {
if(compare(vec[i], vec[j]) <= 0) { // 稳定性
tmp[cur++] = vec[i++];
} else {
tmp[cur++] = vec[j++];
}
}
while(i < mid) {
tmp[cur++] = vec[i++];
}
while(j < end) {
tmp[cur++] = vec[j++];
}
for(i = start; i < end; i++) {
vec[i] = tmp[i - start];
}
}

template<typename T>
void mergeSort(vector<T>& vec, function<int(const T&, const T&)> compare) {
int len = vec.size();
mergeSort(vec, compare, 0, len);
}

template<typename T>
void quickSort(vector<T>& vec, function<int(const T&, const T&)> compare, int start, int end) {
if(end - start <= 1) return;
int i = start, j = end - 1;
while(i < j) {
while(i < j && compare(vec[i], vec[j]) <= 0) j--;
swap(vec[j], vec[i]);
while(i < j && compare(vec[i], vec[j]) <= 0) i++;
swap(vec[i], vec[j]);
}
quickSort(vec, compare, start, i);
quickSort(vec, compare, i+1, end); // i + 1, 已排序的枢轴就不用了
}

template<typename T>
void quickSort(vector<T>& vec, function<int(const T&, const T&)> compare) {
int len = vec.size();
quickSort(vec, compare, 0, len);
}


template<typename T>
void heapAdjust(vector<T>& vec, int i, int end, function<int(const T&, const T&)> compare) {
for(int j = i; ; ) {
int largest = j;
if(j*2+1 < end && compare(vec[largest], vec[j*2+1]) < 0) {
largest = j*2+1;
}
if(j*2+2 < end && compare(vec[largest], vec[j*2+2]) < 0) {
largest = j*2+2;
}
if(j == largest) break;
swap(vec[j], vec[largest]);
j = largest;
}
}

template<typename T>
void heapSort(vector<T>& vec, function<int(const T&, const T&)> compare) {
int len = vec.size();
// heapAdjust
// for(int i = len-1; i > 0; i--) {
// if(compare(vec[i], vec[(i+1)/2-1]) > 0) {
// swap(vec[i], vec[(i+1)/2-1]);
// }
// } //wrong
for(int i = len/2; i >= 0; i--) {
heapAdjust(vec, i, len, compare);
}
// sort
for(int i = len-1; i > 0; i--) {
swap(vec[0], vec[i]);
heapAdjust(vec, 0, i, compare);
}
}

const int MAX_NUMBER = 1000;
const int MIN_NUMBER = -1000;
const int MAX_LEN = 2000000;

template <typename T>
int compare(const T& a, const T& b) {
if(a == b) return 0;
else if(a > b) return 1;
else return -1;
}
template <typename T>
void printVec(const vector<T>& vec, function<string(const T&)> toString) {
cout << "[";
if(vec.size() > 0) cout << toString(vec[0]);
for(size_t i = 1; i < vec.size(); i++) {
cout << ", " << toString(vec[i]);
}
cout << "]\n";
}
clock_t execTime(const function<void(vector<pair<int, int>> &)>& f, vector<pair<int, int>> &vec) {
clock_t start = clock();
f(vec);
clock_t end = clock();
return end - start;
}

void speedTest(decltype(bubbleSort<pair<int, int>>) sort, vector<pair<int, int>> &a, vector<pair<int, int>> b) {
auto cmp = [](const pair<int, int>& x, const pair<int, int>& y){ return compare(x.first, y.first); };
clock_t our = execTime([&](vector<pair<int, int>> & vec) {sort(vec, cmp);}, a);
clock_t libc = execTime([](vector<pair<int, int>> & vec) {std::sort(vec.begin(), vec.end());}, b);
cout << "our: " << our << ", libc: " << libc << ", promoted: " << double(libc - our) / double(libc) * 100 << "%" << endl;
}

void test(decltype(bubbleSort<pair<int, int>>) sort, bool is_stable) {
int len = rand() % MAX_LEN;
vector<pair<int, int>> vec;
map<int, int> cnt;
for(int i = 0; i < len; i++) {
int num = rand() % (MAX_NUMBER - MIN_NUMBER) + MIN_NUMBER;
vec.emplace_back(num, ++cnt[num]);
}

speedTest(sort, vec, vec);

bool stability = true, ok = true;
for(int i = 0; i < len - 1; i++) {
cnt[vec[i].first]--;
if(compare(vec[i].first, vec[i+1].first) > 0) {
ok = false;
} else if(compare(vec[i].first, vec[i+1].first) == 0) {
if(vec[i].second + 1 != vec[i+1].second) {
stability = false;
}
}
}
if(len > 0) cnt[vec[len-1].first]--;
for(auto & ite : cnt) {
if(ite.second != 0) {
ok = false;
break;
}
}
// cout << "ok: " << ok << ", stable: " << stability << endl;
if(!ok) {
printVec<pair<int, int>>(vec, [](const pair<int, int>& item) {
stringstream ss;
ss << "{" << item.first << ", " << item.second << "}";
return ss.str();
});
throw runtime_error("sort failed!\n");
}
if(is_stable && !stability) {
throw runtime_error("stability not match");
}
}
int main() {
srand(time(NULL));
test(bubbleSort, true);
test(selectSort, false);
test(stableSelectSort, true);
test(insertSort, true);
test(mergeSort, true);
test(quickSort, false);
test(heapSort, false);
}

LeetCode-34

2789. 合并后数组中的最大元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
long long maxArrayValue(vector<int>& nums) {
int n = nums.size();
long long ans = nums[n-1];
long long curSum = nums[n-1];
for(int i = n - 2; i >= 0; i--) {
if(nums[i] <= curSum) {
curSum += nums[i];
} else {
curSum = nums[i];
}
ans = max(ans, curSum);
}
return ans;
}
};

2864. 最大二进制奇数

  • 一次遍历原地算法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
string maximumOddBinaryNumber(string& s) {
int len = s.length();
int index = 0;
for(int i = 0; i < len; i++) {
if(s[i] == '1') {
s[i] = '0';
s[index++] = '1';
}
}
s[index-1] = '0';
s[len-1] = '1';
return s;
}
};

1261. 在受污染的二叉树中查找元素

阅读更多