Algorithm
905. 按奇偶排序数组
题目
给定一个非负整数数组 A,返回一个由 A 的所有偶数元素组成的数组,后面跟 A 的所有奇数元素。
你可以返回满足此条件的任何数组作为答案。
示例:
输入:[3,1,2,4]
输出:[2,4,3,1]
输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
思路
这个题目主要时要把数组分为奇偶两部分,和快排中分割元素的思想一致,因此可以使用快排分割元素的思想。也就是设置两个变量i、j,初始为零,用j从前往后遍历数组,如果遇到偶数,就把i、j交换位置,将偶数换到前面,然后i加1,最后就能得到一个偶数在前,奇数在后的数组。
实现
func sortArrayByParity(A []int) []int {
if A == nil || len(A) == 0 {
return A
}
for i, j := 0, -1; i < len(A); i++ {
if A[i]%2 == 0 {
j++
A[i], A[j] = A[j], A[i]
}
}
return A
}
Review
Goodbye, Object Oriented Programming
这篇文章通篇都在分析面向对象编程方式的缺点,作者从oop的三大特性着手分析,继承、封装和多态。
首先呢,是对继承进行分析,这也是作者分析的最为详细的部分,从四个角度进行论证:
- 针对继承的重用性,为了复用一个当前继承体系中已有的类,不得不把它的父类、父类依赖的类都一起添加进来,可以使用组合和代理解决这个问题。
- 针对多继承的分析,就是说当一个类继承了两个具有相同父类的类时会造成的问题,这同样也使用组合和代理解决。
- 当父类修改逻辑可能会造成子类的行为异常,同样,也是用组合及代理进行解决。
- 作者认为继承的层次结构和现实生活中的模型并不一致,现实中很多的模型都是包含的关系,而非继承关系,因此作者认为应该使用组合的思想,而非继承的思想来对层次结构进行划分。
接着,作者对封装进行分析,他认为封装并不安全,因为封装的只是外部传来的对象引用,外部依然能够对这个对象进行修改,这样有违封装的本意,要做到安全的话智能对对象进行深拷贝,但这样也会有问题。
然后,作者认为完全可以使用基于接口的多态替代基于继承的多态。
在最后,作者建议使用函数式编程。
我觉得作者其实主要还是对于继承深恶痛绝的,因为对于继承的缺点,举了挺多的例子,同时对于封装的多态的缺点,只能算是一笔带过了。但是感觉作者的观点似乎不完全正确。
作者说当他想复用一个已有的类到新项目中时,要把它的父类、父类依赖的类都导过去,导致的结果就是,本来只想要一根香蕉,却得到了整篇森林。以此来抨击继承,然后推荐用组合或者代理去实现,但是这样的继承结构是不是本来就不合理?想要复用这样的它,肯定会有问题。还有作者举得例子都不是很有说服力,因为不管是函数式编程也好,面向对象编程也好,总是不可能说完全按照理想的状态来的,根据不同的语言总会有不同的需要注意的点,只能说都会面对不同的问题。
不过我觉得不管是面向对象编程还是函数式编程,在介绍理念的时候都是使用非常简单而直白的例子来讲解的,但只有在体验过各种错综复杂的需求、场景之后才能真正的有所领悟吧。不过也许函数式编程真的更容易实现优雅的代码,大概作者是深有体会才会写这样一篇文章,还真是想要去了解一下。
Tip
这周了解了一下怎么用MAT分析安卓应用内存,这里介绍一下吧。
先打开android studio的profile
选择memory,进入内存详情界面
image.png
然后先点上方的删除按钮触发GC,之后在点下载按钮抓取heap dump文件
image.png
image.png
然后把heap dump文件保存下来。
image.png
这时会生成一个hprof文件。但是这个文件还不能直接用MAT打开,需要用安卓的hprof-conv工具转换一下,
image.png
接下去就可以用MAT打开这个文件了,MAT的下载链接:https://www.eclipse.org/mat/downloads.php
打开后就看到如下界面,这样就可以开始分析内存了
image.png
网友评论