Fork me on GitHub

电影感的真面目

视频地址:https://www.bilibili.com/video/BV1Fa4y1e7tJ

电影感这三个字的实体:

  1. 好看:摄影
  2. 好听

摄影

大量使用了使用单机广角运动长镜头

视觉效果构成占比:
好灯光 > 好镜头 > 好机器

电影到底拍的是什么?

背景能够触发观众的指定记忆,对人物产生一个联想。

背景的选择是无限的,人物的联想也就变得无限了

电影拍的不是人,是人活在世界当中的样子,而背景就是世界

比电视剧更优质的电影感说到底就是更大的眼界和格局了

ARTS 2020-6-29 ~ 2020-7-5

ARTS是由左耳朵耗子陈皓在极客时间专栏《左耳听风》中发起的一个每周学习打卡计划。

1
2
3
4
5
6
7
Algorithm:至少做一个 LeetCode 的算法题。主要为了编程训练和学习。

Review:阅读并点评至少一篇英文技术文章。主要为了学习英文,如果你英文不行,很难成为技术高手。

Tip:学习至少一个技术技巧。主要是为了总结和归纳你日常工作中所遇到的知识点。

Share:分享一篇有观点和思考的技术文章。主要为了输出你的影响力,能够输出你的价值观。

1. Algorithm(算法)

剑指offer 038、LeetCode 104:二叉树的深度

题目

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

例如:

给定二叉树 [3,9,20,null,null,15,7],

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

返回它的最大深度 3 。

提示:

节点总数 <= 10000
注意:本题与主站 104 题相同:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法

1. 递归
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 递归实现二叉树最大深度
* 时间复杂度O(n)
* 空间复杂度:线性表最差O(n)、二叉树完全平衡最好O(logn)
*
* @param root 根节点
* @return 最大深度
*/
class Solution {
public int maxDepth(TreeNode root) {
// 递归退出条件,到叶子节点
if (root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
// 0ms
2. 迭代

BFS 广度优先

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

import java.util.LinkedList;
import java.util.Queue;

/**
* BFS层次遍历思想迭代实现二叉树最大深度
* 时间复杂度O(n)
* 空间复杂度:线性表最差O(n)、二叉树完全平衡最好O(logn)
*
* @param root 根节点
* @return 最大深度
*/
public class Solution2 {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
// BFS的层次遍历思想,记录二叉树的层数,
// 遍历完,层数即为最大深度
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
int maxDepth = 0;
while (!queue.isEmpty()) {
maxDepth++;
// 每层size
int levelSize = queue.size();
for (int i = 0; i < levelSize; i++) {
TreeNode node = queue.pollFirst();
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
return maxDepth;
}
}
// 3ms

DFS前序遍历思想

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
public class Solution3 {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
Stack<TreeNode> stack = new Stack<>();
Stack<Integer> value = new Stack<>();
stack.push(root);
value.push(1);
int maxDepth = 0;
// DFS实现前序遍历,每个节点记录其所在深度
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
// DFS过程不断比较更新最大深度
int temp = value.pop();
maxDepth = Math.max(temp, maxDepth);
// 当前节点的子节点入栈,同时深度+1
if (node.left != null) {
stack.push(node.left);
// 记录当前节点所在深度
value.push(temp + 1);
}
if (node.right != null) {
stack.push(node.right);
// 记录当前节点所在深度
value.push(temp + 1);
}
}
return maxDepth;
}
}
// 7ms

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @Description 测试
* @Author Gao Hang Hang
* @Date 2020-07-08 20:47
**/
public class Test {

public static void main(String[] args) {
//Solution solution = new Solution();
//Solution2 solution = new Solution2();
Solution3 solution = new Solution3();
TreeNode root = new TreeNode(3);
root.left = new TreeNode(9);
root.right = new TreeNode(20);
root.right.left = new TreeNode(15);
root.right.right = new TreeNode(7);
System.out.println(solution.maxDepth(root));
}

}

参考

https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/solution/javashi-xian-san-chong-fang-fa-di-gui-shi-xian-die/

https://leetcode.com/problems/maximum-depth-of-binary-tree/discuss/34195/Two-Java-Iterative-solution-DFS-and-BFS

2. Review(点评)

https://attacomsian.com/blog/spring-data-jpa-query-annotation

3. Tip(技巧)

4. Share(分享)

1、推荐《软件随想录》这本书

2、如何不靠运气变得富有

Naval 是美国风险投资家,这是他的3小时长播客《如何不靠运气变得富有》的中文翻译,介绍了他的财富观,非常值得一读。

3、知识付费对年轻人到底是好是坏?能否在本质上缓解焦虑?

ARTS 2020-6-22 ~ 2020-6-28

ARTS是由左耳朵耗子陈皓在极客时间专栏《左耳听风》中发起的一个每周学习打卡计划。

1
2
3
4
5
6
7
Algorithm:至少做一个 LeetCode 的算法题。主要为了编程训练和学习。

Review:阅读并点评至少一篇英文技术文章。主要为了学习英文,如果你英文不行,很难成为技术高手。

Tip:学习至少一个技术技巧。主要是为了总结和归纳你日常工作中所遇到的知识点。

Share:分享一篇有观点和思考的技术文章。主要为了输出你的影响力,能够输出你的价值观。

1. Algorithm(算法)

LeetCode 160、剑指 Offer 52 相交链表

题目地址:剑指 Offer 52. 两个链表的第一个公共节点

160. 相交链表

解法1

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
public class Solution {
/**
* For example, the following two linked lists:
A: a1 → a2

c1 → c2 → c3

B: b1 → b2 → b3
begin to intersect at node c1.
time : O(n);
space : O(1);
* @param headA
* @param headB
* @return
*/
public a160_相交链表.cspiration.ListNode getIntersectionNode(a160_相交链表.cspiration.ListNode headA, a160_相交链表.cspiration.ListNode headB) {
if (headA == null || headB == null) return null;

/* 获取链表长度 */
int lenA = len(headA);
int lenB = len(headB);

/* 将较长链表的指针向前移动 */
if (lenA > lenB) {
while (lenA != lenB) {
headA = headA.next;
lenA--;
}
} else {
while (lenA != lenB) {
headB = headB.next;
lenB--;
}
}

/* 同时移动两个元素,直到遇到相同元素 */
while (headA != headB) {
headA = headA.next;
headB = headB.next;
}
return headA;
}

public int len(ListNode head) {
int len = 1;
while (head != null) {
head = head.next;
len++;
}
return len;
}
}

解法2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 边界检查
if (headA == null || headB == null) return null;

ListNode a = headA;
ListNode b = headB;

// 如果a&b有不同的len,那么我们将在第二次迭代后停止循环
while (a != b) {
// 对于第一次迭代的结束,我们只是将指针重置为另一个链表的头部
a = a == null ? headB : a.next;
b = b == null ? headA : b.next;
}

return a;
}
}

参考链接

https://www.youtube.com/watch?v=1bWqD_MwWuw

https://leetcode-cn.com/problems/intersection-of-two-linked-lists/solution/tu-jie-xiang-jiao-lian-biao-by-user7208t/

《程序员面试金典(第6版)》

阅读更多...

你真的对这个世界做好准备了吗?

B 站上的一个视频,讲的挺好。要找到自己的真本性

很多时候生活都是可以通过选择来优化的:

一、目标准备(得有一个努力的方向,无论目标的大小,就算目标是长生不老)

二、心态准备(世界很大,人外有人,时刻准备谦卑;悲观者一事无成,乐观者能从各人中获得知识)

三、方向(将自己的爱好和兴趣转化为事业,因为每次遇到困难后,带领你克服困难的总是那一份热爱)

四、投身实践(反复迎接失败和挫折 ,不断地自我提高和自我强化,有两种情况,第一种是正面,得到了你想要地成就,第二种是失败了,很正常,要积极的分析失败的原因,然后去改正,有时候只是时间问题)

利他最好的是能利所有的人

最近看了快手出的一本《被看见的力量》这本书,快手创始人宿华在其中写了一篇序,其中就提到他对利他的理解。

原文:我们的小团队做了很多类似雇佣军的事,到处去帮别人处理技术问题,把我们的能量放大,但后来我们发现也并不能帮助很多人。我意识到,如果要利他,不应该凭借我个人的力量利他,应该以机制的力量、价值观的力量利他,利他最好的是能利所有的人。

以前看文章常常会听到这样的观点:最好的商业模式就是“利他”模式。其中的观点认为一个企业的产品没有对消费者有利,是不可能长久的。靠忽悠和技巧只能昙花一现而已。

我以前对利他的理解也比较浅显,认为利他只是利一些人而已,宿华的观点则是站在了更高的维度,值得学习。

买了台NAS

一直有备份照片的烦恼,存在电脑里吧不方便查看,存手机里又太占手机空间,NAS 就完美解决了这些问题。而且 NAS 不仅只有备份照片这一种用途,还可以很方便的打造个人影音库,用着很爽,推荐购买。
我这台机器是在淘宝买的,硬盘买的希捷 2T 机械硬盘,现在只用了一个盘位,还能插入三块硬盘,看以后的需求再购入。

扩展阅读

NAS 最近这么火,到底值不值得买?

Java – 如何在 String.Format 中显示 % ?

Photo By Yegor Meteor

原文地址:https://mkyong.com/java/java-how-to-display-in-string-format/

作者:mkyong

翻译:高行行

这个例子说明了如何在String.format中显示百分比 %

JavaStringFormat1.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.mkyong;

public class JavaStringFormat1 {

public static void main(String[] args) {

String result = String.format("%d%", 100);

System.out.println(result);

}

}

输出

1
2
3
4
5
6
Exception in thread "main" java.util.UnknownFormatConversionException: Conversion = '%'
at java.base/java.util.Formatter.checkText(Formatter.java:2732)
at java.base/java.util.Formatter.parse(Formatter.java:2718)
at java.base/java.util.Formatter.format(Formatter.java:2655)
at java.base/java.util.Formatter.format(Formatter.java:2609)
at java.base/java.lang.String.format(String.java:2897)

解决办法

要显示或转义一个%,我们需要放两个%%

JavaStringFormat2.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.mkyong;

public class JavaStringFormat2 {

public static void main(String[] args) {

String result = String.format("%d%%", 100); // 100%

System.out.println(result);

}

}

输出

1
100%

参考文章

Java中如何让String.format正常处理%

SQL 查询中的 NULL 值

本文通过各种 SQL 小例子,解释 NULL 值的用途和带来的问题。

英语原文地址:https://mitchum.blog/null-values-in-sql-queries/

作者:MITCHUM

翻译:高行行

参考翻译文章:https://blog.csdn.net/lnotime/article/details/104847946

小结:

  • SQL 里的 NULL 和其他编程语言里的 NULL 是完全不同的东西
  • 在 SQL 中 NULL 为未知

翻译水平有限,可能存在翻译不准确的地方,尽情谅解。

今天的帖子是关于 SQL 中的 NULL 值的,由我的朋友兼数据库向导 Kaley 提供。如果你想了解有关 SQL,Oracle 数据库以及使查询运行更快的更多信息,请访问他的网站


这是一个使很多萌新开发人员陷入困境的话题-SQL 查询中 NULL 值的概念。

每当你向数据库发出SQL查询时……你想知道一列中是否包含 NULL 值……编写查询以查到结果的正确方式是什么?

你应该使用这样的查询吗?

1
2
SELECT * FROM SOME_TABLE
WHERE SOME_COLUMN = NULL

要么!你应该使用这样的查询吗?

1
2
SELECT * FROM SOME_TABLE
WHERE SOME_COLUMN IS NULL

…答案是,你应该使用第二个查询(SOME_COLUMN IS NULL)。

下图为实际的查询例子 🌰

为什么呢?

为什么其他的比较都不用 IS 关键字呢?

如果我们想知道一个字段是否等于 1,我们可以使用如下的 WHERE 子句:

1
WHERE SOME_COLUMN = 1

那么为什么我们在IS关键字上使用 NULL 值呢?为什么我们需要区别对待 NULL ?

答案是这样的:**在 SQL 中,NULL 表示“未知”的概念 _ _**(因此 NULL 值表示“未知”值)。

1. Null 为未知

在大多数数据库中,NULL 和空字符串(由双撇号 “” 或 ‘’ 表示)之间存在差异。

但是,并非所有数据库都这样:例如,Oracle 数据库不允许你使用空字符串。任何时候 Oracle 数据库看到一个空字符串,它都会自动将空字符串转换为 NULL 值。

但是,对于大多数其他数据库,NULL 值与空字符串的处理方式不同:

  • 空字符串被视为没有值的已知值
  • 将 NULL 值视为未知值

举个例子,就好像问:美国总统西奥多·罗斯福的中间名是什么?

  • 一种答案可能是:“嗯,我不知道西奥多·罗斯福的中间名是什么。”(此想法可以由 Theodore Roosevelt 的记录的 MIDDLE_NAME 列中的 NULL 值表示,即中间名字段为 NULL)
  • 另一种答案可能是**“西奥多·罗斯福总统实际上没有中间名。他的父母从未给他起过中间名,我知道的事实就是西奥多·罗斯福(Theodore Roosevelt)没有中间名。 **(你可以通过在 MIDDLE_NAME 列中输入一个空字符串或 ‘’ 来表示,即中间名字段为空字符串)

Oracle 数据库是最显著的例外,其中这两个值实际上都将由 NULL 表示-除 Oracle 以外的大多数数据库对 NULL 和空字符串的处理方式都非常不同。

只要你记得 NULL 值代表一个未知值,那么这将有助于你编写 SQL 查询,并帮助你解决使用 NULL 值可能遇到的一些棘手情况。

例如,如果你要使用这样的 WHERE 子句查询:

1
2
SELECT * FROM SOME_TABLE
WHERE 1 = 1

该查询将返回行(假设 SOME_TABLE 不是空表!),因为表达式“ 1 = 1” 可证明是 true 的……它可以被证明是正确的。

如果我要说:

1
2
SELECT * FROM SOME_TABLE
WHERE 1 = 0

然后数据库将看到此情况,并将“ 1 = 0”评估为 false(这意味着该查询将_永远不会_返回任何行)。

但是如果我要说:

1
2
SELECT * FROM SOME_TABLE
WHERE 1 = NULL

数据库基本上是这样的:“我不知道这两个值(1 和我们的黑盒 NULL 值)是否相等”……因此它不返回任何记录。

2. 三值逻辑

当 SQL 查询中有 WHERE 子句时,它可以具有三种不同结果之一:

  • true(它将返回行)
  • false(不会返回行)
  • NULL(未知也不会返回行)

你可能会想,“好吧,既然数据库对这两个值的处理完全相同,我为什么要关心 false 和 null 之间的区别?”

好吧,让我告诉你哪里可能遇到麻烦:让我们介绍一下 NOT() 条件。

如果你要说:

1
2
SELECT * FROM SOME_TABLE
WHERE NOT(1 = 1)

然后,数据库首先要求值 1 = 1,然后说:“好吧,那显然是对的。”

但是随后它将对其应用 NOT() 条件。“当 true 被 NOT() 修饰时,它变成了 false……所以 NOT() 条件导致我们的 WHERE 子句在这里是 false 的。”

因此,上面的查询不会返回任何记录。

但是,如果你要说:

1
2
SELECT * FROM SOME_TABLE
WHERE NOT(1 = 0)

然后,数据库首先计算表达式 1 = 0,并说:“那显然是 false 的。”

但是然后它将应用 NOT() 条件,这将给我们相反的结果,因此它变为 true

因此此查询将返回记录!

如果我发出以下查询怎么办?

1
2
SELECT * FROM SOME_TABLE
WHERE NOT(1 = NULL)

数据库首先要评估 1 = NULL。(请记住,它将把 NULL 当作一个未知值!)

它会说:“我不能说 1 是否等于 NULL,因为我不知道 NULL(未知)值是什么。”

因此,它不会产生 true 的结果也不会产生 false 的结果 – 而是会产生 NULL(未知)结果。

NULL 结果将由 NOT() 运算符修饰。

每当你使用 NULL 并将其置于 NOT() 条件时……结果就是另一个 NULL!(未知的反面是……嗯……另一个未知)。

因此,NOT() 运算符对 null 条件不做任何事情。

所以这些查询中的……

1
2
SELECT * FROM SOME_TABLE
WHERE NOT(1 = NULL)
1
2
SELECT * FROM SOME_TABLE
WHERE 1 = NULL

…将不返回任何记录…即使它们是相反的!

3. NULL 和 NOT IN

如果我使用 WHERE 子句发出这样的查询:

1
2
SELECT * FROM SOME_TABLE
WHERE 1 IN (1, 2, 3, 4, NULL)

…那么显然 WHERE 子句将是 true 的,由于 1 在我们的 IN 列表中,所以该查询将返回记录…

但是如果我要说:

1
2
SELECT * FROM SOME_TABLE
WHERE 1 NOT IN (1, 2, 3, 4, NULL)

那么显然这将是 false 的,该查询将永远不会返回记录,因为数字 1 出现在我们的 IN 列表中,并且我们说“ NOT IN”…

现在,如果我要说这样的话怎么办?

1
2
SELECT * FROM SOME_TABLE
WHERE 5 NOT IN (1, 2, 3, 4, NULL)

此 WHERE 子句将永远不会返回任何记录,因为它不是真正的可证明(它不能被证明是 true 的)。数字 5 没有明确出现在“ IN”列表中 - 但是 5 可能在我们的“黑盒” NULL 值内(数据库不一定知道 NULL 的值是什么)。

这将产生 NULL 结果(表示未知结果),因此 WHERE 子句永远不会返回任何记录。

这就是将 NULL 值等效为未知值为什么很重要的原因 - 每当你编写复杂的SQL查询时,它都会为你提供帮助。

希望你现在已经准备好处理 SQL 查询中的 NULL 值!有关 SQL,Oracle 数据库以及使查询运行更快的更多信息,请访问 blog.tuningsql.com

资料

实际例子 🌰的 SQL 文件

1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE `user` (
`id` int(25) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(32) DEFAULT NULL,
`sex` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

INSERT INTO `test`.`user`(`id`, `name`, `age`, `sex`, `password`) VALUES (2, '小白', 1, '0', '333');
INSERT INTO `test`.`user`(`id`, `name`, `age`, `sex`, `password`) VALUES (3, 'white', 12, '0', '111');
INSERT INTO `test`.`user`(`id`, `name`, `age`, `sex`, `password`) VALUES (4, 'white', NULL, '0', '222');

参考文章

神奇的 SQL 之温柔的陷阱 → 三值逻辑 与 NULL !

  • Copyrights © 2015-2023 高行行
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信