ARTS-for-week8-20181207

2024-08-27 01:48
文章标签 arts week8 20181207

本文主要是介绍ARTS-for-week8-20181207,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

阅读文本大概需要 17 分钟。

每周完成一个ARTS:
本周的 Algorithm 来源 LeetCode 3. Longest Substring Without Repeating Characters

本次 Review 阅读了 Medium 上的一篇关于面向对象编程的文章

Tip 自己折腾的 Ubuntu14.04 更新原装系统的 Python2.7 版本到 Python3.6

Share 分享英国一家做人体芯片的公司相关的报道和看法

ps:由于公众号不支持添加外链,所以大家遇到有链接的地方滑到文章最下面点击阅读原文就可以访问了哈,如果觉得文章不错,欢迎分享给周围的朋友们哈

又到周末啦,大家该吃吃该喝喝该玩玩,同时也不要抽点时间忘了学习哦。

下面更新 ARTS 第 八 周的内容。

1.Algorithm

LeetCode 3. Longest Substring Without Repeating Characters 链接 难度:[Medium]

【题意】

Given a string, find the length of the longest substring without repeating characters.

Example 1:

1
2
3
Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3.

Example 2:

1
2
3
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

1
2
3
4
Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

【思路】

一个直观的思路,我们用一个 map 记录每个字符串的索引即位置,然后依次循环往后判断当下每个字符串,如果该字符串在之前出现过,则删除前面出现的单词,也就是说我们不仅要记录当下的字符串的索引还要记录之前出现过的字符串的索引,这样就能保证最后留存的字符里没有重复的字符,同时在这个过程中不断更新记录最大长度。

时间复杂度是 O(n),空间复杂度是O(n)。

【参考代码】

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
class Solution {
public://use mapint lengthOfLongestSubstring(string s) {int len = s.length();map<char,int>M;int preRepeatPos = -1;int maxLen = 0;for(int i = 0; i < len; ++i ){if( M.find(s[i]) != M.end() && preRepeatPos < M[s[i]]) // if current s[i] is already exists means first time meet the duplicated char {preRepeatPos = M[s[i]];}if( i-preRepeatPos > maxLen ) maxLen = i - preRepeatPos;   // update maxLen;M[s[i]] = i;   // update index,must put the last pos}return maxLen;}
};/*//don't use mapint lengthOfLongestSubstring(string s){const int MAX_CHARS = 256+233;int M[MAX_CHARS];memset(M, -1, sizeof(M));int maxLen = 0;int preRepeatPos = -1;for(int i=0; i < s.size(); i++){if (M[s[i]] !=-1 && preRepeatPos < M[s[i]]) {preRepeatPos = M[s[i]];}if ( i - preRepeatPos > maxLen ){maxLen = i - preRepeatPos;}M[s[i]] = i;}return maxLen;
}*/

2.Review

Goodbye, Object Oriented Programming。(英文)

本次 Review 阅读了 Medium 上的一篇关于面向对象编程的文章

我们都知道,面向对象编程有三大原则: 继承、封装、多态

作者提到了在遵守面向对象编程三大原则时遇到的典型的问题,并提出了相应的解决办法让我们避免该问题,概要如下:

1. GoodBye Inheritance

作为面向对象三原则之一的继承,其最大的优点在于可以抽象特性,使得我们可以复用相关的属性和方法。但这也带来了如下几个问题:

  • Banana Monkey Jungle Problem: 继承可能会造成比较复杂的继承体系,也就是说,我们需要继承一个类时,发现还需要引入该类的父类,而父类又有父类,类中包含的其他类对象可能又有一大堆父类。造成了所谓的 Banana Monkey Jungle Problem 问题:我们只是想要一根香蕉,结果给了我们一片香蕉林。

    解决方法:作者提出 Contain and Delegate 方法。

  • The Diamond Problem(钻石问题,也叫做菱形继承问题): 即一个子类继承了两个父类,而这两个父类又继承了同一个父类并复写了相同的方法,这会导致子类在方法调用时可能无法调用到合适的方法。也就是子类不知道到底应该调用哪个方法。

    解决方法:同样是 Contain and Delegate 方法。

    举例,现有如下的伪代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    >   Class PoweredDevice {
    >   }
    >   Class Scanner inherits from PoweredDevice {
    >     function start() {
    >     }
    >   }
    >   Class Printer inherits from PoweredDevice {
    >     function start() {
    >     }
    >   }
    >   Class Copier inherits from Scanner, Printer {
    >   }
    >
    

请注意,Scanner 类和 Printer 类都实现了一个名为 start 的函数。 那么 Copier 类继承了哪个启动函数?扫描仪?还是打印机?它不可能两者兼而有之吧。

解决:采用 Contain and Delegate 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>   Class PoweredDevice {
>   }
>   Class Scanner inherits from PoweredDevice {
>     function start() {
>     }
>   }
>   Class Printer inherits from PoweredDevice {
>     function start() {
>     }
>   }
>   Class Copier {
>     Scanner scanner
>     Printer printer
>     function start() {
>       printer.start()
>     }
>   }
>

请注意,Copier 类现在包含打印机和扫描仪的实例。它将 start 函数委托给 Printer 类的实现。同理它也可以很容易地委派给 Scanner 类去实现。这样就解决了上面的继承问题。

  • The Fragile Base Class Problem(脆弱的基类): 当父类的方法发生改变时,可能会影响到子类,如果子类很多的话,那么不可避免的,后果就会很严重,会在很大程度上影响到已有代码。

  • The Hierarchy Problem(无法确认的继承关系): 程序是对现实世界的抽象,而现实世界中的事物并不都有严密的继承体系,作者举了一个例子,对于一份公司的文件,假如现在我要存储它,那么我既可以在 docuemnt -> company 路径下存储,又可以在 company -> document 路径下存储,这时无法给出明确的继承体系,但如果采用组合的方式,将这些层级视为文件的 tag 标签,就可以解决这个问题。

对于The Diamond Problem 问题,有人说最简洁的方式就是禁止多继承,比如 Java 就不允许多继承,但 Python 就允许多继承,其有一套多继承时的方法调用规则,问题就是如果两个父类有相同的方法,其中一个父类的方法可能永远不会被调用到。对于其他问题,作者给出的解决建议就是我们常说的 「组合优于继承」。

通过对层次结构重新进行分类,通过依赖注入的方式,将继承变为多个对象之间的组合,这样避免了父类改变对子类的影响,同时类之间功能独立,可以灵活组合,提到了代码的扩展性。所以作者最后提到 「GoodBye Inheritance」。

2. GoodBye Encapsulation
  • 对于封装,作者提到其最大的问题在于方法间引用的传递导致的问题。为了提高效率,对象不是通过它们的值而是通过引用传递给函数。 这意味着函数不会传递Object,而是传递一个引用或指向Object的指针。虽然我们可以将某个对象设置为私有变量,当发生外部传递动作时,其传递过来的只是地址值,这就导致了如果其他的方法也传入了相同的引用,就会影响到当前使用该引用对象的方法。

  • 解决方法就是将对象进行深拷贝,避免受其他方法有相同引用可能造成的影响,但是在某些涉及到系统资源的地方并不能深拷贝,在一些极端情况下可能会造成问题。

3 GoodBye Polymorphism

多态虽然是面向对象编程的三大特性之一,但是通过接口,我们可以非常灵活的组合某个对象拥有的行为,在 Java 中被称为 interface, Python中的 mixin 类,其根据行为自由组合,完全可以实现更加的合适的对象。关于这一块具体的例子其实也应该有很多,后续我会继续分享。

个人 review

以上就是作者的提到的内容概要。个人在实际工作体验中觉得上述提到的问题确实存在,而且身边大多数程序员最先接触的可能都是面向对象的编程语言,如果上过大学就知道,毕竟大学里面也都会开设类似面向对象思想的专业课程,因此一开始也深受面向对象编程的影响。但随着经验的增加,我们也逐渐发现,其实编程方式也不止面向对象编程一种,通过了解更多的编程范式我们会找到更适合的编程方式来完成我们要做的事情,耗子叔的专栏中也有编程范式游记系列,非常值得反复实践思考消化。

关于继承、封装、多态,如果要仔细深入的分析,当然,涉及的各种知识太多了,不同的人可能有不同的理解,而且只是表达了自己的一点点看法,可能有不当之处,还希望得到您的反馈和批评。

3.Tip

踩坑记~

最近在折腾 Ubuntu 14.04 ,需要更新原装系统的 Python2.7 版本到 Python3.5,百度查到一篇教程,说是可以先一键命令删除原装的 Python2.7,然后再一键命令安装 Python3.5

1
2
3
> sudo apt-get remove python
> sudo apt-get install python3
>

然后我就傻傻地照着做了。

本来 Terminal 还提醒我要删除 400 多个安装包的,然而我还是同意了。。。同意了。。。

然后结果就杯具了。。。

真是不手贱就不会死。。。结果 Ubuntu 桌面没了。。。 删除完了系统崩了,启动不了了。。。

然后尝试重新安装桌面之类的未果。。。

最终得知 Ubuntu 很多软件依赖于 Python。。。删除需谨慎,在此记录一下。。。

正确的操作:

Step 0 – Install the pre-requisites (optional)

first 安装相应的 lib 库,准备环境(可选)

1
2
3
4
> $ sudo apt-get update
> $ sudo apt-get install build-essential libpq-dev libssl-dev openssl libffi-dev zlib1g-dev
> $ sudo apt-get install python3-pip python3-dev
>

than

1
2
3
4
> $ sudo apt-get update
> $ sudo apt-get install python3.6
> $ apt-cache search python3.6
>

than

Method 1 – using PPA

1
2
3
4
> $ sudo add-apt-repository ppa:jonathonf/python-3.6
> $ sudo apt-get update
> $ sudo apt-get install python3.6
>

Method 2 – Download and configure

1
2
3
4
5
> $ wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz
> $ tar -xvf Python-3.6.3.tgz
> $ cd Python-3.6.3
> $ sudo ./configure --enable-optimizations
>

If above configure ends up with no errors, execute the following commands to complete the installation of Python 3.6

1
2
3
> $ sudo make -j8
> $ sudo make install
>

Verification

Execute the python3.6

1
2
3
4
5
6
> hrw@hrw-VirtualBox:~$ python3.6
> Python 3.6.3 (default, Dec  7 2018, 20:05:20) 
> [GCC 4.8.4] on linux
> Type "help", "copyright", "credits" or "license" for more information.
> >>> 
>

Creating virtualenv using Python 3.6 (可选)

Given that you have more than one Python 3 versions installed, and need to use Python 3.6 for your project. Best practice is to create a virtual environment using Python 3.6

Install virtualenv
1
2
> $ sudo pip3 install virtualenv
>
Create virtualenv
1
2
3
4
> $ virtualenv -p /usr/bin/python3.6 ~/virtualenvs/venv_devopspy
> $ source virtualenvs/venv_devopspy/bin/activate
> (venv_devopspy) nahmed@localhost:~$
>

4.Share

BioTeq 英国领先的人类技术植入专家(英文)

英国有一家叫做 BioTeq 的创业公司,主营业务是人体芯片,也就是在人的体内植入 NFC 和 RDIF 芯片。上图是他们把芯片植入了客户的虎口。

这个芯片里面存有客户的个人信息,可以被读卡器读取。根据这家公司的描述,植入芯片以后,就不用携带钥匙了,挥挥手,门就开了。另外门禁系统和刷脸支付,都会有全新的解决方案,比现在大大简化。

第一眼看到这篇新闻,惊叹于科技进步的同时,心中不免有点隐隐担忧,有几个问题感觉不可避免。

第一个是自由问题,如果这个技术一旦大范围的普及开来,是否意味着侵犯了个人的自由权利。

第二个是数据隐私问题,如果一旦这个技术大范围的普及开来,芯片记录每个人体内的一切日常活动的数据信息被泄露或者被落入不法分子的手中,从而流通到黑市贩卖,后果很严重,想一想是不是很可怕。

这不禁让我想起来了初中读书的时候,课本上经常说:科技是一把双刃剑。科技是不会因为我们的担忧和恐惧而停滞不前,我们无法改变科技进步的方向和速度,但是我们可以改变对科技的态度。毕竟科技最终是要造福于人类。同时希望相应的法律法规能够在监管企业,机构的同时能同步的跟上科技进步的步伐。


推荐阅读

不是生活所迫,谁特么想努力!

ARTS-for-week7-20181130

爱学习,爱技术

这篇关于ARTS-for-week8-20181207的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110294

相关文章

ARTS-for-week9-20181214

阅读文本大概需要 10 分钟。 每周完成一个ARTS: Algorithm 来源 LeetCode 5.Longest Palindromic Substring Review 阅读了 Medium 上的一篇关于学习的文章 Tip 总结自己在台式机安装中标麒麟 V5 操作系统以及配置 Qt 环境的一些注意事项 Share 分享一篇关于 ZIP 压缩算法详细分析及解压实例解释 ps:由于公

ARTS-for-week7-20181130

阅读文本大概需要 8 分钟。 每周完成一个ARTS:每周至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tip、Share 简称ARTS) ps:由于公众号不支持添加外链,所以大家遇到有链接的地方滑到文章最下面点击阅读原文就可以访问了哈,如果觉得文章不错,欢迎分享给周

ARTS-for-week6-20181124

阅读文本大概需要 12 分钟。 每周完成一个ARTS:每周至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tip、Share 简称ARTS) ps:由于公众号不支持添加外链,所以大家遇到有链接的地方滑到文章最下面点击阅读原文就可以访问了哈,如果觉得文章不错,欢迎分享给

ARTS-for-week4-20181109

每周完成一个ARTS:每周至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tip、Share 简称ARTS) 第四周了,哇咔咔。时间过得好快^_^由于微信不支持添加外链,所以大家访问有链接的地方直接滑到文章最底部点击阅读原文就可以访问了^_^ 一  Algorithm

ARTS Tip5 数据结构基本概念

数据结构的研究内容: 研究数据元素之间的逻辑结构研究数据在计算机内部的存储结构研究如何在数据的逻辑结构和存储结构中实施有效的操作和处理 数据结构中数据之间的关系分为: 线性关系非线性关系(非线性关系又分为:树关系和图关系) 数据之间的结构分为: 逻辑结构:体现数据元素之间的逻辑关系 存储结构(物理结构):数据在计算机内的表示,包含数据元素的表示和关系的表示。 存储结构又可以分为:

ARTS Review6 IPv4和IPv6地址解剖

原文链接:https://medium.com/@josephcardillo/a-beginners-guide-to-ipv4-and-ipv6-anatomy-fcc9444b0d4d 这篇文章,作者主要剖析了IPv4和IPv6地址的区别: IPv在IPv4和IPv6中代表什么? 代表网络协议版本。 为什么不存在IPv1, IPv2, IPv3 and IPv5? 因为IPv4是第

ARTS Review7 编写可测试代码

原文链接:https://medium.com/feedzaitech/writing-testable-code-b3201d4538eb 这篇文章,作者主要讲了如何编写可测试的代码,一般人不愿意测试,是因为代码之间的耦合度太高,所以我们可以学习编写低耦合的代码,来方便我们开发项目。 编写可测试的代码需要遵循下面的一些原则和指导路线: SOLID design principles Si

ARTS leetcode7 Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.Example:Input: 1->2->4, 1->3->4Output: 1->1->2->3->4->4

ARTS Share5 Java数组

数组: 在Java中,数组是用来存储一组数据类型相同的变量的值,这些变量共用一个变量名。Java中的数组可以是一维数组也可以是多维数组,其中一维数组使用的频率比较高。 一维数组: 一维数组的声明: type array-name[] = new type[size];或者type[] array-name = new type[size]; type :表示数组的数据类型 array-n

ARTS Share4 mysql中autocommit

MySQL中的事务(自动提交,显示和隐式),在MySQL中事务控制数据操作语句以确保它们是原子的。什么叫做原子的,也就是说这个事务要么成功,要么失败。 什么时候算事务成功或者失败? 当向数据库事务发送commit命令的时候,说明事务提交成功;相反,如果向数据库事务发送rollback命令,那么就说明此次的事务提交失败,所有执行过的SQL,数据会进行回滚到最初的状态。 当对数据库数据进行修改的