We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
题目
两两交换链表中的节点(中等难度)
代码
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */ /** * @param {ListNode} head * @return {ListNode} */ var swapPairs = function(head) { // 如果为空链表则直接返回头(null) if (!head) return head; // 取得本节点(head)的下一个节点 let next = head.next; // 如果本节点有下一个节点 if (next) { // 取得本节点下一个节点的下一个节点,作为下一对节点的头节点 let nextPairHead = next.next; // 令下一个节点的下一个节点指向本节点 next.next = head; // 令本节点的下一个节点指向 下一对节点互换后的头节点 head.next = swapPairs(nextPairHead); // 返回本节点的下一个节点,作为本对的新头节点返回 return next; } // 如果本节点没有下一个节点,则返回本节点,作为“本对节点”(实际上只有一个节点)的头结点 else { return head; } };
执行结果:通过 执行用时:60 ms,在所有 javascript 提交中击败了 91.77% 的用户 内存消耗:33.8 MB,在所有 javascript 提交中击败了 16.23% 的用户
思路: 使用递归,详见注释: 如果为空链表则直接返回头(null) 取得本节点(head)的下一个节点 如果本节点有下一个节点 取得本节点下一个节点的下一个节点,作为下一对节点的头节点 令下一个节点的下一个节点指向本节点 令本节点的下一个节点指向 下一对节点互换后的头节点 返回本节点的下一个节点,作为本对的新头节点返回 如果本节点没有下一个节点,则返回本节点,作为“本对节点”(实际上只有一个节点)的头结点
另外,还可以使用迭代:
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */ /** * @param {ListNode} head * @return {ListNode} */ var swapPairs = function(head) { if (head && head.next) { // 上一个节点 let prev; // 遍历的当前节点 let curr = head; // 最终要返回的头节点 head = curr.next; while (curr && curr.next) { let next = curr.next; if (prev) prev.next = next; curr.next = next.next; next.next = curr; prev = curr; curr = curr.next; } } return head; };
对比: 与高分对比: 本代码运行 55 个测试用例花费约 60ms,平均一个测试用例约 1.1ms; 高分代码运行 55 个测试用例花费约 60ms,平均一个测试用例约 1.1ms。 思路一致代码略。
阅读: Know Kubernetes — Pictorially
点评: Kubernetes 被称作 “containers orchestrator”,也就是容器编排者。
所谓“容器”(container),就是用于盛放应用代码及其依赖库,还有操作系统内核依赖库的程序。容器将以上这些东西与容器的宿主(也就是运行容器的主机)进行隔离,包括:
而 Kubernetes 则起到了对这些容器编排的作用。所谓编排,就是管理,具体是提供诸如以下但不限于以下这些功能:
容器编排者有很多,为何作者独爱 Kubernetes ?
因为它如同乐高积木般的特性,使得使用者能够在容器群规模扩大的同时仍能对它们的管理保持得心应手,并且通过对容器进行灵活的组装编排,实现不同的自定义需求(比如任务调度功能等),而高度活跃的社区更是令这种自定义需求能够获得快速的响应。
接着作者就开始以图文并茂的方式介绍 Kubernetes 的架构啦,具体看原文吧~
简单来说,就是:
当使用 git 命令行合并代码时,通常会用到 git mergetool 命令。
这个命令会调出一个编辑器,用来编辑代码,进行合并。
有时候,我们希望使用 vscode 作为默认的编辑器,因为它的代码合并和比较功能较为友好。
这时可以使用这个方法。
首先参考官方文档,找到 gitconfig。
gitconfig
git config --list --show-origin
然后打开 gitconfig,添加或编辑如下内容:
# 声明默认的 mergetool [merge] tool = vscode # 使用 vscode 作为 mergetool 时, # vscode 的打开命令 [mergetool "vscode"] cmd = code --wait $MERGED # 声明默认的 difftool [diff] tool = vscode # 使用 vscode 作为 difftool 时, # vscode 的打开命令 [difftool "vscode"] cmd = code --wait --diff $LOCAL $REMOTE
此时,当进入合并状态时,git mergetool 或 git difftool 就会调出 vscode, 就可以很开心地使用 vscode 的合并和比较功能了~
git mergetool
git difftool
参考:
分享一篇极客专栏《设计模式之美》 07 | 理论六:为什么基于接口而非实现编程?有必要为每个类都定义接口吗
本文介绍了“基于接口而非实现”的编程原则,以及如何贯彻该原则,并分析了是否有必要为每个类都定义接口。 重要段落摘抄如下:
为什么基于接口而非实现编程?
“基于接口而非实现编程”这条原则的另一个表述方式,是“基于抽象而非实现编程”。 后者的表述方式其实更能体现这条原则的设计初衷(也可参考扩展阅读)。 在软件开发中,最大的挑战之一就是需求的不断变化, 这也是考验代码设计好坏的一个标准。 越抽象、越顶层、越脱离具体某一实现的设计, 越能提高代码的灵活性,越能应对未来的需求变化。 好的代码设计,不仅能应对当下的需求,而且在将来需求发生变化的时候, 仍然能够在不破坏原有代码设计的情况下灵活应对。 而抽象就是提高代码可扩展性、灵活性、可维护性最有效的手段之一。
“基于接口而非实现编程”这条原则的另一个表述方式,是“基于抽象而非实现编程”。 后者的表述方式其实更能体现这条原则的设计初衷(也可参考扩展阅读)。
在软件开发中,最大的挑战之一就是需求的不断变化, 这也是考验代码设计好坏的一个标准。
越抽象、越顶层、越脱离具体某一实现的设计, 越能提高代码的灵活性,越能应对未来的需求变化。
好的代码设计,不仅能应对当下的需求,而且在将来需求发生变化的时候, 仍然能够在不破坏原有代码设计的情况下灵活应对。
而抽象就是提高代码可扩展性、灵活性、可维护性最有效的手段之一。
如何进行基于接口而非实现的编程?
要遵从“基于接口而非实现编程”的原则,具体来讲,我们需要做到下面 3 点: 函数的命名不能保护任何实现细节。 应对具体的实现细节进行封装。 应为实现类定义抽象的接口。 (使用者依赖接口,而非具体的实现类来编程)
要遵从“基于接口而非实现编程”的原则,具体来讲,我们需要做到下面 3 点:
我们在做软件开发的时候,一定要有抽象意识、封装意识、接口意识。 在定义接口的时候,不要暴露任何实现细节。 接口的定义只表明做什么,而不是怎么做。 此外,在设计接口的时候,我们要多思考一下, 这样的接口是否足够通用、 是否能够做到在替换具体的接口实现的时候,不需要任何接口定义的改动
我们在做软件开发的时候,一定要有抽象意识、封装意识、接口意识。 在定义接口的时候,不要暴露任何实现细节。 接口的定义只表明做什么,而不是怎么做。
此外,在设计接口的时候,我们要多思考一下, 这样的接口是否足够通用、 是否能够做到在替换具体的接口实现的时候,不需要任何接口定义的改动
是否有必要为每个类都定义接口?
从“基于接口而非实现编程”原则的设计初衷出发, 如果在我们的业务场景中, 某个功能只有一种实现方式,未来也不可能被其他实现方式替换, 那么我们就没有必要为其设计接口,也没有必要基于接口编程, 而是直接使用实现类就可以了。
也就是说,越是不稳定的系统,我们越是要在代码的可扩展性、维护性上下功夫。 而相反,如果某个系统特别稳定,在开发完之后,基本上不需要做维护, 那么我们就没有必要为其扩展性和维护性投入不必要的开发时间。
扩展阅读:
The text was updated successfully, but these errors were encountered:
No branches or pull requests
ARTS 第二十一周(2019.11.18~2019.11.24)
Algorithm 两两交换链表中的节点(中等难度)
题目
两两交换链表中的节点(中等难度)
代码
执行结果:通过
执行用时:60 ms,在所有 javascript 提交中击败了 91.77% 的用户
内存消耗:33.8 MB,在所有 javascript 提交中击败了 16.23% 的用户
思路:
使用递归,详见注释:
如果为空链表则直接返回头(null)
取得本节点(head)的下一个节点
如果本节点有下一个节点
取得本节点下一个节点的下一个节点,作为下一对节点的头节点
令下一个节点的下一个节点指向本节点
令本节点的下一个节点指向 下一对节点互换后的头节点
返回本节点的下一个节点,作为本对的新头节点返回
如果本节点没有下一个节点,则返回本节点,作为“本对节点”(实际上只有一个节点)的头结点
另外,还可以使用迭代:
对比:
与高分对比:
本代码运行 55 个测试用例花费约 60ms,平均一个测试用例约 1.1ms;
高分代码运行 55 个测试用例花费约 60ms,平均一个测试用例约 1.1ms。
思路一致代码略。
Review 图解 Kubernetes
阅读:
Know Kubernetes — Pictorially
点评:
Kubernetes 被称作 “containers orchestrator”,也就是容器编排者。
所谓“容器”(container),就是用于盛放应用代码及其依赖库,还有操作系统内核依赖库的程序。容器将以上这些东西与容器的宿主(也就是运行容器的主机)进行隔离,包括:
正是对应用程序运行环境的隔离和包装,使得应用程序在不同环境下都能提供同样的稳定性,即杜绝了“这段代码在我的电脑上能运行啊”的问题。
而 Kubernetes 则起到了对这些容器编排的作用。所谓编排,就是管理,具体是提供诸如以下但不限于以下这些功能:
容器编排者有很多,为何作者独爱 Kubernetes ?
因为它如同乐高积木般的特性,使得使用者能够在容器群规模扩大的同时仍能对它们的管理保持得心应手,并且通过对容器进行灵活的组装编排,实现不同的自定义需求(比如任务调度功能等),而高度活跃的社区更是令这种自定义需求能够获得快速的响应。
接着作者就开始以图文并茂的方式介绍 Kubernetes 的架构啦,具体看原文吧~
简单来说,就是:
Tip 使用 vscode 作为默认的 git mergetool 和 difftool
当使用 git 命令行合并代码时,通常会用到 git mergetool 命令。
这个命令会调出一个编辑器,用来编辑代码,进行合并。
有时候,我们希望使用 vscode 作为默认的编辑器,因为它的代码合并和比较功能较为友好。
这时可以使用这个方法。
首先参考官方文档,找到
gitconfig
。然后打开
gitconfig
,添加或编辑如下内容:此时,当进入合并状态时,
git mergetool
或git difftool
就会调出 vscode,就可以很开心地使用 vscode 的合并和比较功能了~
参考:
Share [极客专栏:设计模式之美] 09 | 为什么基于接口而非实现编程?有必要为每个类都定义接口吗
分享一篇极客专栏《设计模式之美》
07 | 理论六:为什么基于接口而非实现编程?有必要为每个类都定义接口吗
本文介绍了“基于接口而非实现”的编程原则,以及如何贯彻该原则,并分析了是否有必要为每个类都定义接口。
重要段落摘抄如下:
为什么基于接口而非实现编程?
如何进行基于接口而非实现的编程?
是否有必要为每个类都定义接口?
扩展阅读:
The text was updated successfully, but these errors were encountered: