0%

Algorithm

你让某些人为你工作了七天, 你要用一根金条作为报酬。这根金条要被分成七块。你必须在每天的活干完后交给他们一块。如果你只能将这根金条切割两次,你怎样给这些工人分?

分析:严格来说应该是智力题,不是算法题。
解决方法是切两次,把金条分成1/7,2/7,4/7三份,编号a,b,c

第一天,给a

第二天,给b,拿回a

第三天,给a

第四天,给c,拿回a,b

第五天,给a

第六天,给b,拿回a

第七天,给a

Read more »

这周看完了《枪炮、病菌与钢铁》,简单记下读书笔记。

大多数都只对人类几千年,甚至只有最近几百年的历史有所了解。大家都知道中国在古代经济和科技都是比较领先的,后来被西方超过,不仅是中国,全球大多数发展落后的地方都被西方掠夺或者殖民过。但是从人类一万多年的历史看,人类是从非洲大陆起源的,为什么不是有领先优势的非洲人来占领和殖民欧亚大陆呢?决定人类社会发展、进步的决定性因素究竟是什么?

作者先提出了这个问题,然后开始从地理和历史中寻找答案。作者主要从地理环境和物种(尤其是可驯化的动植物)分布上尝试解答上面的问题,是大陆环境的差异而非人种的生物差异导致了上面所说的问题。

人类社会遵循采集狩猎到农业到工业的一个路径。气候和可供驯化的动物能够让人类更早定居并进入农业社会,从而发展出钢铁和枪炮等工具,人畜直接的传染能产生新的病菌同时让人群具有免疫力。这样有着先进工具和对病菌免疫的族群对传统狩猎社会是碾压式的优势,数百人的队伍就能打败上万人的军队。

书中一个比较有意思的地方是关于物种和技术的传播。欧亚大陆东西向的主轴线让作物和牲畜的传播比其他大陆更快,因为这种传播大大依赖于气候因而也就是大大依赖于纬度,传播的速度在非洲就比较缓慢了,而在美洲就尤其缓慢。除了纬度,还有高山和沙漠等环境的阻隔也能起到类似的作用。

另外一个观点是关于竞争的,为什么中国没有成为发展创造的中心。中国在地理上的四通八达最后却成了一个不利条件,某个专制君主的一个决定就能使改革创新半途而废,而且不止一次地这样做了。相比之下,欧洲在地理上的分割形成了几十个或几百个独立的、相互竞争的小国和发明创造的中心。如果某个国家没有去追求某种改革创新,另一个国家会去那样做的,从而迫使邻国也这样去做,否则就会被征服或在经济上处于落后地位。欧洲的地理障碍足以妨碍政治上的统一,但还不足以使技术和思想的传播停止下来。欧洲还从来没有哪一个专制君王能够像在中国那样切断整个欧洲的创造源泉。

书中关于技术先于需求、以及技术退化的相关的讨论也值得思考,现代的人们可能对技术的一些习以为常的观点和认知,在历史上却不是一直如此。

本书资料详实,文字严谨,观点明确,脉络清晰,值得一读。

Algorithm

3sum(Meidium)

解法一:三层暴力循环,时间复杂度 O(n3) 以上了,直接 PASS。

解法二:先排序,然后从第一个开始,用 0 减去的值当作剩下两数之和,采用 two-sum 的头尾指针办法来解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public List<List<Integer>> threeSum(int[] num) {
Arrays.sort(num);
List<List<Integer>> res = new LinkedList<>();
for (int i = 0; i < num.length-2; i++) {
//为了保证不加入重复的 list,因为是有序的,所以如果和前一个元素相同,只需要继续后移就可以
if (i == 0 || (i > 0 && num[i] != num[i-1])) {
//两个指针,并且头指针从i + 1开始,防止加入重复的元素
int lo = i+1, hi = num.length-1, sum = 0 - num[i];
while (lo < hi) {
if (num[lo] + num[hi] == sum) {
res.add(Arrays.asList(num[i], num[lo], num[hi]));
//元素相同要后移,防止加入重复的 list
while (lo < hi && num[lo] == num[lo+1]) lo++;
while (lo < hi && num[hi] == num[hi-1]) hi--;
lo++; hi--;
} else if (num[lo] + num[hi] < sum)
lo++;
else
hi--;
}
}
}
return res;
}

Review

Kotlin and Exceptions

文章前面介绍了 Java 异常的一些历史,中间主要在说明 Kotlin 中异常应该怎么使用:

  1. 处理程序逻辑错误,比如传入了负值之类的场景,传到程序上层进行处理
  2. 双重用途 API,不确定是逻辑错误还是可以无需干预的输入错误,例如 string.toInt() 这种 API,在后者的情况可以用如下代码解决,而不应该使用异常:
    1
    val number = string.toIntOrNull() ?: defaultValue
  3. API设计
    仅仅在逻辑错误的地方使用异常,而不要用异常来做函数返回值的变通方法。对于不是逻辑错误的异常,可以通过包装结果来避免在逻辑代码中使用 try/catch。
    对于单个错误的场景,可以通过 null 来返回代表错误。对于多种错误的情况,可以使用 sealed class 和 when 来处理。
  4. 输入/输出
    Kotlin 在输入/输出中默认使用异常。应该在代码中指定一个地方,以统一解决所有网络错误。

异步编程和协程,大多数情况和同步编程的异常处理一致。然而,在高度并发的情况下,可以使用结构化协程并发,所有的异常都在上层进行统一处理。

Read more »

相关概念

自带字体

Android 中默认字体是 Roboto,4.0 引入,5.0 进行了大的改良。

中文 5.0 之前是 Droid,之后是 Noto Sans「思源黑体」。

字体属性

android:typeface属性是自 API-1 以来就被添加进系统的,不能引用外部字体,只允许被设置为以下四种typeface:

  • normal
  • sans
  • serif
  • monospace

android:fontFamily 对 typeface 的一次加强,可以支持更多的字体样式,例如:

  • casual
  • cursive
  • condensed
  • serif-monospace

fontFamily 优先级比 typeface 高,同时被设置的话,后者会自动失效
fontFamily的某些字体是有系统版本限制的,比如 sans-serif-medium 是 5.0 之后才添加的,版本支持情况可以看这个回答

Read more »

Fiddler

下载地址

基本设置:

  1. 安装完默认就开始抓本机的请求了,左边是请求列表,右边是请求详情
  2. 使能远程机器连接:菜单Tools > Fiddler Options,勾选上 Allow remote clients to connect 。这里可以看到默认的端口是8888。官方文档
  3. 在手机上设置代理,本机ip查看可以把光标移动到Fiddler工具栏最右边的Online选项卡上,即可显示。

抓取HTTPS:

  1. 在手机浏览器上访问 http://[上一步的ip]:8888/ 或者 http://ipv4.fiddler:8888/,在页面上下载 FiddlerRoot certificate,然后选择信任即可。操作方法在上面的设置方法链接里面也有。
  2. 点开 Tools > Fiddler Options > HTTPS,勾选上 Decrypt HTTPS Traffic 即可。官方文档

过滤请求

  • 排除请求。比如应用中图片比较多,我们可以在图片请求上右键菜单上选择 Filter Now,点击 Hide 相应的Host即可
  • 只显示指定的Host。右边窗口在工具栏下面有一排标签,其中有一个带勾选框的的Filters标签,点击后在页面左上角勾选上 Use Filters,然后在Hosts区域选择 Show only Internet Hosts 和 Show only the following Hosts,然后再下面输入框填上白名单内的Host即可,使用分号分隔。Host的写法可以参照左边请求列表的 Host 列来写即可。带图的教程

Charles

Read more »

开发资源

官方文档

对于初学者,开发工具可以直接从官网下载,官方文档上有详细介绍以及大量的样例(尤其是Codelabs)

在线查看源码

  • Chrome安装Android SDK Reference Search插件,再在前面原版网站的API中查询对应的类,网页上会有源码的链接出现
  • 使用XRef网站查看,教程
  • Github的镜像

开源库查找

  • android-arsenalAndroid军火库,汇集了最新的开源库
  • codekk 专注于开源分享、源码解析、框架设计、好文推荐、Android 内推

相关资讯

Read more »

常用的clone、status、add、push、checkout等命令经常用不容易忘记,但是一些中等频率的命令每次都要查询,索性做个记录。完整的常用命令见附录。

设置用户信息

1
2
3
4
git config --global user.name "your_name"
git config --global user.email "your_name@abc.com"
#查看当前所有的设置
git config --list

新建工程

  • 本地有文件

    1
    2
    3
    4
    5
    6
    cd existing_folder
    git init
    git remote add origin [url]
    git add .
    git commit -m "Initial commit"
    git push -u origin master
  • 本地无文件

    1
    2
    3
    4
    5
    6
    git clone [url]
    cd testGit
    touch README.md
    git add README.md
    git commit -m "add README"
    git push -u origin master
  • 本地存在仓库

    1
    2
    3
    4
    5
    6
    cd existing_repo
    git remote rename origin old-origin
    git remote add origin [url]
    # 也可以直接修改: git remote set-url origin [url]
    git push -u origin --all
    git push -u origin --tags

分支、Tag相关

1
2
3
4
5
6
7
# 删除远程分支
git push origin --delete [branch-name]

删除本地tag:
git tag -d tagName
删除远程tag:
git push origin :refs/tags/tagName

shallow clone

clone大型仓库的最近N次提交

1
2
3
4
5
6
7
8
9
10
11
12
git clone --depth 1 [url]
# 取回tag
git fetch --tags

# 切换分支
git remote set-branches origin 'remote_branch_name'
git fetch --depth 1 origin remote_branch_name
git checkout remote_branch_name

# 取回完整仓库
git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
git fetch --unshallow
Read more »

Data classes 是一种替代Java中传统POJOs的简洁方式,每当有人向Java开发者推广Kotlin是救世主的时候,data classes 一定是前三的理由之一。

别误解我,data classes 很棒, 但是从每个人谈论它们(也包括使用,我打赌)的样子看,许多人并不懂 data 关键词真正对一个类做了什么。所以,让我们搞清楚!

传统类(Regular classes)

这是一个非常简单的没有 data 关键词的数据模型类:

1
class Person(val name: String, var age: Int)

这个类实际上已经和我们叫做 POJO 的类是一样的了。在 Java 里,它有两个字段,合适的 getters 和 setters,然后还有一个有两个参数的构造器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public final class Person {
private final String name;
private int age;

public final String getName() {
return this.name;
}

public final int getAge() {
return this.age;
}

public final void setAge(int age) {
this.age = age;
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}
}

数据修改器(The data modifier)

现在我们把这个类变成一个 data class

1
data class Person(val name: String, var age: Int)
Read more »

1、I’m leaving GitLab to help everyone work remotely

远程工作迫使一个公司做一些不一样的事情:

  1. 异步工作成为一种必须
  2. 必须把一切都写下来

应该有自己选择在那里,什么时间工作的自由

作者即将去remote.com做新的CEO

2、 Writing things down (how to know what to do next)

感到不确定?把自己关心的和反对意见写下来,反复问自己就能明朗了

3、 书 - 《未来简史》

特别有意思的书,越往后读越有趣。关于人类和社会未来的思考,能让人暂时从当前的视野脱离出来,从更大的尺度看看更宏达的主题。

4、工具 Notion – All-in-one workspace for notes, tasks, wikis, and databases

Read more »