家电清洗,深海恐惧症,高考满分作文-机械轴承021,机械知识大全

作者 | Kevin Ghadyani译者 | 清儿爸修正 | Rachel出品 | AI科技大本营(ID:rgznai100)

为了更了解其他人对软件工程的观点,我开端张狂在 YouTube 上追 TechLead 的视频。在接下来的几天里,我为他在 Google 作业时提出的一道面试题想出了各种处理计划。

经过 TechLead 模仿 Google 面试(软件工程师职位)


TechLead 在 Google 的 100 屡次面试中都提出了一个问题,这引起了我对 RxJS 的爱好。本文会评论处理该问题的一切传统办法。

他问这个问题的真实意图是从应聘者得到下列信息:在编码之前,他们会问正确的问题吗?提出的处理计划是否契合项目攻略?他乃至指出,是否得到正确的答案一点都不重要,重要的是应聘者的考虑办法,以及应聘者是否可以了解这个问题。

他谈到了一些处理计划,包括递归办法(受仓库巨细约束)和迭代办法(受内存巨细约束)。本文将对这两个处理计划进行具体评论。

TechLead 的问题

在 TechLead 的问题中,他要求应聘者在如下网格中,核算出一切色彩相同的最大接连块的数量。


当看到这个问题时,我的榜首反应是,有必要做一些 2D 图画建模才干处理这个问题。听起来这道题在面试中简直不或许回答出来。

但在听完他的具体解说之后,我方知状况并非如此。在这个问题中,咱们需求处理的是现已捕获的数据,而不是解析图画。

数据建模

在编写任何代码之前都需求界说数据模型。关于任何问题,首要要弄清楚咱们在处理什么,并搜集事务需求。

在咱们事例中,TechLead 为咱们界说了许多具体的需求,例如:

  • 五颜六色方块或“节点”的概念
  • 数据会集包括 1 万个节点
  • 节点被安排成行和列,即二维数据
  • 列数和行数或许不同
  • 节点有色彩信息,并具有对“邻接”这一概念的表明办法

咱们还可以从数据中取得更多信息:

  • 节点不会堆叠
  • 节点不会和其本身邻接
  • 节点不会有重复的邻接
  • 坐落边角的节点会比其他节点少一个或两个邻接

还有一些不知道信息,例如:

  • 行数与列数的比
  • 或许的色彩数量
  • 只要一种色彩的或许性
  • 色彩的大致散布

开发人员的水平越高,其需求问的问题越多。尽管这有所协助,但假如不能找出不知道信息,问题的实践处理仍是会存在阻止。

大部分人并不会想到问询这些不知道信息。在开端研讨这个算法之前,我也不知道这些不知道信息是什么。要找到一切的不知道信息,需求与事务人好日子格楞员进行重复的评论才行。

关于 TechLead 的这张相片来说,色彩的散布好像是随机的。他只用了三种色彩,而且没有说到其他约束,因而咱们暂时也做这种假定。别的咱们还假定,这些色彩或许是相同的。

为了保证算法的有效性,因而我假定咱们运用的是 100x100 的网格,以避免处理1行10000列这样的极点状况。

在一般状况下,我会在检查数据的开端几个小时内问询一切这些问题。这也是 TechLead 真实关怀之处。应聘者需求考虑,是要从编写一个随机处理计划开端,仍是要首要找出问题所在。假如提早计划的话,这些问题将更简略处理。在处理这些问题之后,咱们终究只需重写代码的一小部分即可。

创立数据模型

咱们需求知道数据是怎样输入的,以及咱们期望以何种办法来处理这些数据。由于没有处理数据的体系,因而咱们需求自己规划一个可视化的办法。

数据的根本结构如下:

  • Color
  • ID
  • X
  • Y

需求 ID 的原因在于,咱们或许不止一次碰到同一个图片格。要想避免无限循环的话,就有必要符号在这些状况下该图片格所在的方位。

此外,像这样的数据一般会分配某些 ID、哈希值或其他值。它是一个仅有的标识符,因而,咱们可以经过某种办法来标识特定的节点。假如咱们想知道最大的接连块,就需求知道该块中有哪些节点。

由于 TechLead 运用网格对数据进标识,我假定咱们会得到 X 和 Y 的值。依托这些特点,我就可以生成一些 HTML,并保证生成的内容与他给咱们的内容相相似。

这是运用肯定定位来完结的,就像他的比如相同:


答案:3


这种办法也可以处理更大一些的数据集,如下图:


答案:18


下面是生成节点的代码:

 1const generateNodes = ({
2 numberOfColumns,
3 numberOfRows,
4}) => (
5 Array(
6 numberOfColumns
7 * numberOfRows
8 )
9 .fill()
10 .map((
11 item,
12 index,
13 ) => ({
14 colorId: (
15 Math
16 .floor(
17 Math.random() * 3
18 )
19 ),
20 id: index,
21 x: index % numberOfColumns,
22 y: Math.floor(index / numberOfColumns),
23 }))
24)


咱们运用队伍信息创立一个一维数组,然后依据这些数据生成节点。

我用的是 colorId 而不是 color 。这样做有两个原因,一是随机化更为简练,二是咱们一般有必要自己查找色彩值。

尽管 TechLead 没有清晰阐明,但该标题只用了 3 个色彩值,因而,我将数据集约束为 3 种色彩。咱们只需知道它或许有数百种色彩,终究的算法就不需求改变了。

下面是一个更简略的比如,这是一个 2x2 的节点列表:

1[
2 { colorId: 2, id: 0, x: 0, y: 0 },
3 { colorId: 1, id: 1, x: 1, y: 0 },
4 { colorId: 0, id: 2, x: 0, y: 1 },
5 { colorId: 1, id: 3, x:马海涌 1, y: 1 },
6]

数据处理

咱们期望知道每个节点的邻接联络,但仅靠 X 和 Y 的值无法做到。所以,给定 X 和 Y,咱们还需求找出怎样找出相邻的 X 和 Y 值。其实很简略,咱们只需在 X 和 Y 上找到 +1 和 -1 的节点即可。

我为此写了一个函数:

 1const getNodeAtLocation = ({
2 nodes,
3 x: requiredX,
4 y: requiredY,
5}) => (
6 (
7 nodes
8 .find(({
9 x,
10 y,
11 }) => (
12 x === requiredX
13 && y === requiredY
14 ))
15 || {}
16 )
17 .id
18)

咱们用来生成节点的办法,实践上是一种核算相邻节点 ID 的数学办法。而在这一步中,我将采纳一个与之相反的思路家电清洗,深海恐惧症,高考满分作文-机械轴承021,机械常识大全,即假定节点将以随机次序输入。

我经过再次遍历一切节点来增加邻接联络:

 1const addAdjacencies = (
2 nodes,
3) => (
4 nodes
5 .map(({
6 colorId,
7 id,
8 x,
9 y,
10 }) => ({
11 color: colors[colorId],
12 eastId: (
13 getNodeAtLocation({
14 nodes,
15 x: x + 1,
16 y,
17 })
18 ),
19 id,
20 northId: (
21 getNodeAtLocation({
22 nodes,
23 x,
24 y: y - 1,
25 })
26 ),
27 southId: (
28 getNodeAtLocation({
29 nodes,
3家电清洗,深海恐惧症,高考满分作文-机械轴承021,机械常识大全0 x,
31 y: y + 1,
32 爱情面包房})
33 ),
34 westId: (
35 getNodeAtLocation({
36 nodes,
37 x: x - 1,
38 y,
39 })
40 ),
41 }))
42 .map(({
43 color,
44 id,寅行道
45 eastId,
46 northId,
47 southId,
48 贾烽是谁westId,
49 }) => ({
50 adjacentIds: (
51 [
52 eastId,
53 northId,
54 southId,
55 westId,
56 ]
57 .filter((
58 adjacentId,
59 ) => (
60 adjacentId !== undefined
61 ))
62 ),
63 color,
64 id,
65 }))家电清洗,深海恐惧症,高考满分作文-机械轴承021,机械常识大全
66)

这个预处理代码中,我尽量避免了任何不必要的优化。它不会影响算法的终究功用,只会有助于简化咱们的算法。

接下来,我将 colorId 换成 color 。这关于咱们的算法而言其实没有必要,这一步仅仅为了更好的可视化。

咱们为每组相邻的 X 和 Y 值调用 getNodeAtLocation 函数,并找到咱们的 northId 、 eastId 、 southId 和 westId 。在此进程中,咱们不会对 X 和 Y 的值进行参数传递。

获取根本 ID 之后,再将它们转换为一个 adjacentIds 数组,这个数如懿传荣佩组只包括那些具有值的邻接数组。如此一来,假如咱们有边角的话,就不必忧虑检查这些 ID 是不是为空。它还答应咱们对数组进行循环,而无需在算法中手艺记载每个根本 ID。

下面是另一个 2x2 网格的示例,这儿咱们运用了一组新的节点,并经过 addAdjacencies 来运转:

1[
2 { adjacentIds: [ 1, 2 ], color: 'red', id: 0 },
3 { adjacentIds: [ 3, 0 ], color: 'grey', id: 1 },
4 { adjacentIds: [ 3, 0 ], color: 'blue', id: 2 },
5 { adjacentIds: [ 1, 2 ], color: 'blue', id: 3 },
6]

优化预处理进程

为了简化本文的算法,我增加了另一个优化进程。该算法将删去与当时节点色彩不匹配的相邻 ID。

重写 addAdjacencies 函数,如下:

 1const addAdjacencies = (
2 nodes,
3) => (
4 仲姝婕nodes
5 .map(({
6 colorId,
7 id,
8 x,
9 y,
10 }) => ({
11 adjacentIds: (
12 nodes
13 .filter(({
14 x: adjacentX,
15 y: adjacentY,
16 }) => (
17 adjacentX === x + 1
18 && adjacentY === y
19 || (
20 adjacentX === x - 1
21 && adjacentY === y
22 )
23 || (
24 adjacentX === x
25 && adjacentY === y + 1
26 )
27 || (
28 adjacentX === x
29 && adjacentY === y - 1
30 )
31 ))
32 .filter(({
33 colorId: adjacentColorId,
34 }) => (
35 adjacentColorId
36 === colorId
37 ))
38 .map(({
39 id,
40 }) => (
41 id
42 ))
43 ),
44 color: colors[colorId],
45 id,
46 }))
47 .filter(({
48 adjacentIds,
49 }) => (
50 adjacentIds
51 .length > 0
52 ))
53)

我在增加更多功用的一同简化了 addAdjacencies 。

经过删去色彩不匹配的节点,咱们的算法可以 100% 确认 adjacentIds 特点中的任何 ID 都是邻接的节点。

终究,我删去了一切不具有相同色彩邻接的节点,这进一步简化了咱们的算法。这样,咱们就将节点缩减为只要咱们关怀的那些节点。

过错的办法:递归

TechLead 指出,咱们无法递归地履行这个算法,由于咱们会遇到仓库溢出的问题。

尽管在必定程度上,他这么说是对的,但有几种办法可以缓解这个问题。咱们可以运用迭代或许尾递归(tail recursion),但 JavaScript 不再将尾递归作为自带功用。

尽管咱们仍杨富宽然可以用 JavaScript 来写一个尾递归函数,但为使得算法愈加简略,我依然挑选了创立一个典型的递归函数。

在编写代码之前,咱们需求先找到算法。关于递归,运用深度优先查找是合理的。“不要忧虑他人不明白核算机科学术语。”在我向一位搭档展现我想出的不同处理计划时,他如此说道。

算法

咱们将从一个节点开端,尽或许向下查找,直到抵达一个端点。然后咱们将回来并采纳下一个分支途径,直到咱们扫描完整个接连块停止。在此进程中,咱们还有必要记载咱们查找过的部分,以及最大的接连块的长度。

我将函数分红了两部分。其间一个函数将保存最大列表和从前扫描的 ID,一同至少循环每个节点一次。另一个函数则将从未扫描的根节点开端,进行深度优先遍历。

代码如下所示:

 1const getContiguousIds = ({
2 contiguousIds = [],
3 node,
4 nodes,
5}) => (
6 node
7 .adjacentIds
8 .reduce(
9 (
10 contiguousIds,
11 adjacentId,
12 ) => (
13 contiguousIds
14 .includes(adjacentId)
15 ? contiguousIds
16 : (
17 getContiguousIds({
18 contiguousIds,
19 node: (
20 nodes
21 .find(({
22 id,
23 }) => (
24 id
25 === adjacentId
26 ))
27 ),
28 nodes,
29 })
30 )
31 ),
32 (
33 contiguousIds
34 .concat(
35 node
36 .id
37 )
38 ),
39 )
40)


41const getLargestContiguousNodes = (
42 nodes,
43) => (
44 nodes
45 .reduce(
46 (
47 prevState,
48 node,
49 ) => {
50 if (
51 prevState
52 .scannedIds
53 .includes(node.id)
54 ) {
55 return prevState
56 }
57
58
59 const contiguousIds = (
60 getContiguousIds({
61 node,
62 nodes,
63 })
64 )
65
66
67 const {
68 largestContiguousIds,
69 scannedIds,
70 } = prevState
71
72
73 return {
74 largestContiguousIds: (
75 contiguousIds.length
76 > largestContiguousId朴振英老婆s.length
77 ? contiguousIds
78 : largestContiguousIds
79 ),
80 scannedIds: (
81 scannedIds
82 .concat(contiguousIds)
83 ),
84 }
85 },
86 {
87 largestContiguousIds: [],
88 scannedIds: [],
89 },
90 )
91 .largestContiguousIds

下面,咱们将逐渐进行剖析。

递归函数

getContiguousIds 是递归函数,在每个节点调用一次。在该函数每次回来成果时,咱们都会得到一个接连节点的更新列表。

这个函数只要一个判别条件:家电清洗,深海恐惧症,高考满分作文-机械轴承021,机械常识大全节点是否已在列表中?假如没有,则再次调用getContiguousIds 。当该函数回来成果时,咱们会取得一个更新的接连节点列表,该列表会被回来到 reducer ,并用作下一个 adjacentId 的状况。

每逢咱们用 concat 将当时节点连接到 contiguousIds 时,都要向 contiguousIds 传入值。每次进一步递归时,咱们都要保证在循环履行 adjacentIds 之前,当时节点现已被增加到 contiguousIds 列表中。这可以保证咱们不会无限地递归。

循环

该函数的后半部分也会遍历每个节点一次。递归函数运用 reducer来检查代码是否已被扫描。若已被扫描,就持续循环,直到找到一个没有循环的节点,或许直到退出循环停止。

假如咱们的节点尚未被扫描,则调用 getContiguousIds,并持续遍历,直到扫描完结。这是同步的,但或许需求一些时刻。

每逢函数回来一个 contignousIds 列表,都对照 largestContiguousIds 进行检查,假如该列表的回来值更大的话,就存储回来值。

一同,咱们将把这些 contiguousIds 增加到咱们的 scannedIds 列表中,以符号咱们查找的节点。

履行

就算咱们有 10000 个项目,这个算法也不会遇到 3 种随机色彩的仓库溢出问题。假如我把一切的都改成单一色彩,就或许会遇到仓库溢出的问题,这是由于咱们的递归函数阅历了 10000 次的递归。

次序迭代

由于内存比函数调用的仓库要大,所以我的下一个主意是在一个循环中完结整个工作。咱们将盯梢节点列表的列表。咱们将不断增加它们,并将它们链接在一同,直到退出循环。

这个办法要求在完结循环之前,将一切或许的节点列表保存在内存中。在递归示例中,咱们只将最大的列表保存在内存中。

 1const getLargestContiguousNodes = (
2 nodes,
3) => (
4 nodes恐龙x档案
5 .reduce(
6 (
7 contiguousIdsList,
8 {
9 adjacentIds,
10 id,
11 },
12 ) => {
13 const linkedContiguousIds = (
14 contiguousIdsList
15 .reduce(
16 (
17 linkedContiguousIds,
18 contiguousIds,
19 ) => (
20 contiguousIds
21 .has(id)
22 ? (
23 linkedContiguousIds
24 .add(contiguousIds)
25 )
26 : linkedContiguousIds
27 ),
28 new Set(),
29 )
30 )
31
32
33 return (
34 linked家电清洗,深海恐惧症,高考满分作文-机械轴承021,机械常识大全ContiguousIds
35 .size > 0
36 ? (
37 contiguousIdsList
38 .filter((
39 contiguousIds,
40 ) => (
41 !(
42 linkedContiguousIds
43 .has(contiguousIds)
44 )
45 ))
46 .concat(
47 Array
48 .from(linkedContiguousIds)
49 .reduce(
50 (
51 linkedContiguousIds,
52 cont揉捏食用iguousIds,
53 ) => (
54 new Set([
55 ...linkedContiguousIds,
56 ...contiguousIds,
57 ])
58 ),
5苏酒运用渠道9 new Set(adjacentIds),
60 )
61 )
62 )
63 : (
64 contiguousIdsList
65 .concat(
66 new Set([
67 ...adjacentIds,
68 id,
69 ])
70 )
71 )
72 )
73 },
74 [new Set()],
75 )
76 .reduce((
77 largestContiguousIds = [],
78 contiguousIds,
79 ) => (
80 contiguousIds.size
81 > largestContiguousIds.size
82 ? contiguousIds
83 : largestContiguousIds
84 ))
85)

另一个主意是,从顶部开端遍历,并将每个节点循环一次。到在此进程总,咱们有必要检查 ID 是否存在于节点列表的列表 cont余清辞iguousIdsList 中。

假如它不存在于任何 contiguousIds 列表中,咱们就将增加该列表和 adjacenIds 。这样,在循环时,就会有其他的内容链接到它。

假如咱们的节点在其间一个列表之中,那么节点就或许也存在于其间适当多的列表中。咱们想要把一切这些都链赵景强接在一同,并从 contiguousIdsList 中删去未链接的那些节点。在咱们得到节点列表的列表之后,检查哪个列表是最大的,这个算法就完结了。

履行

与递归版别不同的是,当一切 10000 个项目都是相同的色彩时,这个算法可以完结任务。但该算法的一个缺点是,它履行得适当慢。在上述代码的功用评价中,我没有考虑到循环列表的列表的状况,这明显对功用有很大的影响。

随机迭代

我想选用递归办法背面的思路,并以迭代办法进行运用。这一算法的方针是准确射中每个节点一次,而且只存储最大的接连块:

 1const getLargestContiguousNodes = (
2 nodes,
3) => {
4 let contiguousIds = []
5 let largestContiguousIds = []
6 let queuedIds = []
7 let remainingNodesIndex = 0
8
9
10 let remainingNodes = (
11 nodes
12 .slice()
13 )
14
15
16 while (remainingNodesIndex < remainingNodes.length) {
17 const [node] = (
18 remainingNodes
19 .splice(
20 remainingNodes速8多姆Index,
21 1,
22 )
23 )
24
25
26 const {
27 adjacentIds,
28 id,
29 } = node
30
31
32 contiguousIds
33 .push(id)
34
35
36 if (
37 adjacentIds
38 .length > 0
39 ) {
40 queuedIds
41 .push(...adjacentIds)
42 }
43
44
45 if (
46 queuedIds
47 .length > 0
48 ) {
49 do {
50 const queuedId = (
51 queuedIds
52 .shift()
53 )
54
55
56 remainingNodesIndex = (
57 remainingNodes
58 .findIndex(({
59 id,
60 }) => (
61 id === queuedId
62 ))
63 )
64 }
65 while (
66 queuedIds.length > 0
67 && remainingNodesIndex === -1
68 )
69 }
70
71 if (
72 queuedIds.length === 0
73 && remainingNodesIndex === -1
74 ) {
75 if (
76 contiguousIds.length
77 > largestContiguousIds.length
78 ) {
79 largestContiguousIds = contiguousIds
80 }
81
82 contiguousIds = []
83 remainingNodesIndex = 0
84
85 if (
86 remainingNodes
87 .length === 0
88 ) {
89 break
90 }
91 }
92 }
93
94 return largestContiguousIds
95}
96
97module.exports = getLargestContiguousNode

这儿,咱们没有将节点增加到从前扫描的 ID 列表,而是从 remainingNodes 数组中拼接出值来,可是我不主张咱们这样做。

分化

我把上述代码分红 3 个部分,用 if 句子分隔。

让咱们从中心部分隔端。首要检查 queuedIds 。假如该目标有值,就对行列中的内容进行循环,看看它们是否存在于 remainingNodes 中。

第三部分的内容取决于第二部分的成果。假如 queuedIds 目标为空,而且 remainingNodesIndex 是 -1 的话,那么咱们就现已完结了这个节点列表,并需求从一个新的根节点开端。新的根节点一直坐落索引 0 处,由于咱们正在对 remaininigNodes 进行拼接。

现在再来看循环的顶部。我可以运用 while (true) ,可是需求留一个跳出条件,以避免犯错。这在调试时很有用,由于要弄清楚无限循环或许是件苦楚的工作。

之后,咱们将拼接节点。咱们将节廊坊苏荷塘点增加到 contiguousIds 列表中,并将 adjacentIds 增加到行列中。

履行

这一算法简直和递归版别相同快。当一切节点都是相同色彩时,它是一切算法中速度最快的。

针对数据的优化

对相似的色彩进行分组

由于咱们只知道有两种蓝色,所以咱们可以将相似色彩的节点分组在一同,用于次序迭代版别。

经过将节点拆分红 3 个更小的数组,咱们可以削减内存占用,以及需求在列表的列表中履行的循环次数。尽管如此,这并不能处理一切色彩都相同的状况下会呈现的问题,因而咱们并不会运用此办法修正递归版别。这也意味着咱们可以对操作进行多线程处理,将履行时刻缩短近三分之一。

假如咱们按次序履行这些指令,只需先运转三个中最大的一个。假如最大值比别的两个值大,就无需检查它们。

或许存在的最大数据集的巨细

咱们可以检查每一次迭代,而不是在特定时刻距离检查是否有最大的列表。假如最大节点调集的规划大于或等于可用节点的一半(5000 或更高),那么,很明显咱们现已有了最大的列表。

若运用随机迭代版别的话,咱们可以找到迄今停止最大的列表巨细,并检查剩下的节点数量,假如没有比最大的节点调集巨细还小的数值,那么就可以阐明,咱们现已有最大的列表了。

运用递归

尽管递归有其局限性,但咱们仍可以运用它。咱们需求做的工作便是检查剩下节点的数量。假如它没有超出仓库的约束,咱们就可以运用更快的递归版别。这么做的危险是很大,但随着循环的深化,这一办法会缩短履行时刻。

运用 for 循环

在知道节点最大数量的状况下,咱们可以运用 for 循环编写 reduce 函数。不管何时,与 for 循环比较, Aray.prototype 办法都十分慢。

运用尾递归

我没有在本文中评论相关算法,由于我以为尾递归需求一篇独自的文章来论述。这是一个很大的主题,许多当地都需求解说。别的,尽管它运用了递归结构,但它或许并不会想你所期望的那样比while循环还快。

RxJS:可保护性与功用

有一些办法可以重写这些函数,这样你就可以更轻松地了解并保护它们。我想出的首要处理计划是运用 Redux-Observable 风格的 RxJS,但并不运用 Redux。

接下来,我想以惯例的办法来编写代码,然后运用 RxJS 流式传输数据,看看能将算法功用进步多少。

我运用 RxJS 做了 3 个版别的算法,并做了一些修正来加速履行速度。与我佘北浴场之前的文章不同的是,即便增加了行和列,一切的三个版别都会变慢。

我原本可以做许多优化,但要以代码的可读星野悠月性为价值,这不是我想要的。

终究,我总算找到了一个可行的处理计划,该计划现在是最快的,只需一半的履行时刻。这现已是总体上最好的改进了。

只要当每个节点都是相同的色彩时,我才干用可观察到的数据打败内存占用较多的次序迭代。从技能上来讲,这一算法也优于递归办法,由于在这种状况下,递归算法会呈现仓库溢出的问题。

在研讨怎样运用 RxJS 流数据之后,我意识到该办法对本文来说真实过于杂乱了。期望今后会有文章具体介绍这些代码示例。

假如期望检查具体代码,可以检查如下 GitHub 项目地址:

https://github.com/Sawtaytoes/JavaScript-Performance-Interview-Question

终究统计数据

一般来说,最大的接连块均匀有 30~80 家电清洗,深海恐惧症,高考满分作文-机械轴承021,机械常识大全个节点。

下面展现了相关算法的评价数据:

随机色彩


一种色彩

不管我进行了多少次测验,每种办法的相对排名方位都坚持不变。

当一切节点色彩都相一同,Redux-Observable 并发办法受到了影响,我试过许多办法测验进步这个办法的运转速度,可是没有成功。

游戏制造

在我的工作程序员生计中,我曾两次遇到过这段代码。其间一次是我在开发独立游戏《Pulsen》时运用 Lua 编写的代码,代码长度要小得多。

还有一次是在我制作一张世界地图的时分,该地区有一个预界说的节点列表,我对其进行了实时处理。这使得运用者可以经过键盘上的方向键来移动世界地图。

我还为具有 X 和 Y 值的不知道项列表编写了一个节点生成器。听起来是不是很熟悉?我相同需求使网格位居屏幕中心。不过,要做到这点,在 HTML 中比在游戏引擎中要更简略完成。尽管如此,将一堆肯定定位的 div 放在中心方位也并不简略。

在这个事例中,实时履行时刻并不怎样很重要,由于我在加载游戏时就进行了很多的预处理。

我想着重的是,TechLead 的问题或许是你会在工作生计中遇到的问题,但在典型的 JavaScript 运用程序中,往往不太需求考虑程序的速度。

TechLead 在 Google 运用的是 Java ,我猜他面试的职位都很关怀履行速度。他们有或许有一堆作业任务要处理很多的数据,因而像这样的处理计划或许是必要的。

可是,这个视频也有或许是关于 HTML 和 CSS 的职位的,谁知道呢!

结语

正如你在终究统计数据中所看到的那样,读起来最槽糕的代码简直是最快的,而且还完结了咱们一切的要求。

据我自己的经历,我花了更长的时刻来开发非 RxJS 版别的代码。我以为,这是由于更快的版别需求全面的考虑。Redux-Observable 可以让你以化整为零的办法进行考虑。

这是一道十分风趣的问题。它起先看起来好像很难,可是将它分化成几块之后,问题就方便的解决了。

原文链接:

https://medium.freecodecamp.org/bet-you-cant-solve-this-google-interview-question-4a6e5a4dc8ee

(*本文由AI科技大本营编译,转载请联络微信1092722531)

CTA核心技能及运用峰会

5月25-27日,由中国家电清洗,深海恐惧症,高考满分作文-机械轴承021,机械常识大全IT社区CSDN与数字经济人才开展中心联合主办的榜首届CTA核心技能及运用峰会将在杭州国际博览中心隆重召开,峰会将环绕人工智能范畴,约请技能领航者,与开发者一起讨论机器学习和常识图谱的前沿研讨及运用。

现在8折会议预售票抢购中,抢购地址:https://www.bagevent.com/event/2586643

增加小帮手微信15梁心怡101014297,补白“CTA”,了解票务以及会务概况。