Seven's blog

你不会找到路,除非你敢于迷路

0%

ARTS-14

Algorithm

832. 翻转图像

解法一

使用双层循环。

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
int[][] result = new int[A.length][A[0].length];
for (int i = 0; i < A.length; i++) {
int columnNumber = A[i].length;
for (int j = 0; j < A[i].length; j++) {
result[i][j] = A[i][columnNumber - j - 1] ^ 1;
}
}
return result;
}
}

执行用时:1ms,内存消耗:36.6MB。

解法二

减少内层循环次数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
int[][] result = new int[A.length][A[0].length];
int innerLoopTimes = (A[0].length + 1) / 2;
for (int i = 0; i < A.length; i++) {
int columnNumber = A[i].length;
for (int j = 0; j < innerLoopTimes; j++) {
result[i][j] = A[i][columnNumber - j - 1] ^ 1;
result[i][columnNumber - j - 1] = A[i][j] ^ 1;
}
}
return result;
}
}

执行用时:1ms,内存消耗:36.3MB。

解法三

尝试在原有数组上操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
int columnNumber = A[0].length;
int innerLoopTimes = (columnNumber + 1) / 2;
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < innerLoopTimes; j++) {
int temp = A[i][j] ^ 1;
A[i][j] = A[i][columnNumber - j - 1] ^ 1;
A[i][columnNumber - j - 1] = temp;
}
}
return A;
}
}

执行用时:0ms,内存消耗:36.2MB。

Review

The Two Kinds of Moderate

文章阐述了两种截然不同的温和派:一种是自然的温和,他们本来的观点就是温和派;另一种是有意的温和,他们没有自己的观点,故意在极左和极右之间选择一个温和的观点。

这让我想到当今世界中的杠精。他们没有自己的观点,但是不管你的观点如何,他们总能找到你观点的对立面,然后对你进行无情的抨击。

极端点说,最可怕的事情不是你的观点被整个世界反对,而是一个人本身没有观点。很多时候,观点就是我们意识的载体。而意识,就是我们存在的证明。

对一件事没有观点,要么是自身没有灵魂,要么是认知落后。这才是比较可怕的事情。

Tip

普通索引和唯一索引

查询过程

  • 使用普通索引,查找到满足条件的第一个记录后不会停止。系统会查找下一个记录,直到碰到第一个不符合条件的记录才停止;
  • 使用唯一索引,由于索引定义了唯一性,查找到第一个满足条件的记录后,就会停止继续检索。

因为 InnoDB 的数据是按照数据页为单位来读写的。所以“使用普通索引查找下一个记录”这个操作的消耗大概率是发生在内存中的,对性能的影响微乎其微。

所以单从查询性能来讲,普通索引和唯一索引差异不大。

更新过程

change buffer:当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InnoDB 会将这些更新操作缓存在 change buffer 中,这样就不需要从磁盘中读入这个数据页了。在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。通过这种方式保证这个数据逻辑的正确性。

change buffer 实际上是可以持久化的数据,不仅在内存中有拷贝,也会被写入到磁盘上。将 change buffer 中的操作应用到原数据页,得到最新结果的过程称为 merge。除了访问数据页会触发 merge 外,系统有后台线程会定期 merge,在数据库正常关闭的过程中,也会执行 merge 操作。

索引,如果能够将更新操作先记录在 change buffer 中,减少读磁盘,语句的执行速度会得到明显的提升。

唯一索引的每次更新操作都需要先判断这个操作是否违反唯一性约束,那么对应的数据页会被读入到内存,所以没有必要使用 change buffer 了。

如果要更新的目标页在内存中,两者的执行效率相差无几。

如果要更新的目标页不在内存中:

  • 对于唯一索引来说,需要将数据页读入内存,判断唯一索引是否冲突,没有冲突的话插入记录,语句执行结束;
  • 对于普通索引来说,直接将更新记录在 change buffer 中,语句执行就结束了。

场景:对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时 change buffer 的使用效果最好。

Share

近些年来,少有事物能够做到人尽皆知。遗憾的是,新型冠状病毒做到了。

但是,除去病毒本身,它背后的人生百态更加耐人寻味。

轻视

一部分人的轻视导致疫情没有在最佳的时间得到控制,一部分人的轻视导致自己、家人甚至是陌生人惨受牵连。

未知的事物,我们应该怀抱敬畏之心。

人血馒头

消息一出,各大网店、药店的口罩瞬间脱销。有趣的是、当我从药店空手走出来的时候,有个人从后面追上来:“哥,要口罩吗?”黄牛的嗅觉,真是灵敏。

随后又爆出新闻,有一些不合格的口罩被售出。

还有更劲爆的消息,甚至还有人回收口罩想要二次销售。

良心这种东西,总是会被利益给吃掉。

利益

什么是对?什么是错?对于人类这种群居生物来说,多数人的利益就是对,少数人的利益就是错。

社会、人心、就是如此。

疫区的人想出去,是为了自己的利益;外面的人想隔离,也是为了自己的利益。想要追求自己的利益本没有错,错在自己的利益和大多数人冲突。

谣言

疫情一出,谣言四起。

始终想不明白造谣的人有何意图。三人成虎,很多人又特别喜欢相信这类谣言,进而推波助澜。

最可怕的事情莫过于,我以为我在做的错的事情是对的。

普通人

我们这样的普通人,最好能够做到不传谣、不信谣、不轻视。在一定程度上,不给他人添乱,也是一种善良。

倘有余力,努力提升自己对真实时态的认识,然后尽可能科普给更多人。

微信公众号
扫码关注, 一起进步!