校历第三周
[TOC]
TODO
Taps
微信小程序:setData()
原理案例
// 方法一:先准备好新的数组对象,再去赋值 |
实际案例
// 配套的 wxml |
课程记录
周一
大数据可视化
- 应该从正面来选择,而不是从负面来选择
- 例如:
- 应该是因为想做某件事,而去做
- 不应该是因为不想做另一件事然后选择的这件事
OFFICE装 企业版—— 就可以加装 Microsoft Visio- 数据清洗:有些位置的数据,如果是异常高(999999)或者未收集到(异常低,零),就需要用一段时间内的平均值代替,这就是数据清洗
- 任务四步:
- 数据收集
- 数据清洗
- 数据观察
- 结论提交
- 小数据时代,保证数据准确的最重要的方法是,随机性
- 最早的电子表格软件:Lotus 123
- EXCEL的进阶使用:宏 的打开,记录,修改
周二
Java高级
TOC:
- Java集合框架层次结构中,接口和类的关系
Collection接口中定义的通用方法Iterator的遍历能力- ForEach
for( var x : ... )循环,forEach()函数 - 在
Comparable接口之外,Comparator接口的比较能力 Collections中的静态工具方法
不想让子类使用的方法
如果一个方法在子类中没有意义,可以按如下方式实现它:
public void someMethod(){ |
Iterator 接口
Collection接口是 继承 自Iterable接口的Iterable接口,定义了iterator(),这个方法会返回一个Iterator实例迭代器.next()顺序访问下一个.hasNext()检测是否还有下一个.remove()移除迭代器返回的最后一个元素.forEach()- 可以接受lambda表达式作为参数
- 本身实际的参数类型是,函数接口
Consumer<? Super E>的一个实例
// 两者等价 |
Collection 接口
.addAll().removeAll().retainAll()分别是 并 差 交 运算.size()返回集合中元素的个数.containsAll()检测这个集合是否包含指定集合中的全部元素toArray()返回一个Object数组toArray(T[])返回一个T[]数组
List 接口
List接口 是继承自Collection接口的List接口 增加了面向位置的操作List接口 增加了一个能双向遍历线性表的新线性表迭代器.listIterator()ListIterator实例 增加了三个方法:.hasPrevious().previous().previousIndex()
LinkedList & ArrayList & Vector & Stack
LinkedList是List接口的链表实现LinkedList提供从线性表两端的 获取,插入,删除 元素的方法LinkedList的遍历应避免使用.get(index),这效率极低LinkedList的遍历应使用for( var k : ... )或_.forEach(...),来隐式地使用迭代器ArrayList是List接口的数组实现- 这个内置数组会自动扩容
- 但是不会自动缩容
.trimToSize()主动缩容至线性表大小
Vector和ArrayList完全类似,唯一的不同是,Vector的方法都是同步方法- 如果不需要同步,最好使用
ArrayList,因为它比Vector快得多 Stack是继承自Vector的扩展Vector()的一些方法:.capacity()返回该向量的当前容量.ensureCapacity()增加该向量的容量.copyInto(anArray: Object[]):void将该向量的元素复制到数组中.elements():Enumeration<E>返回该向量的一个枚举.trimToSize()裁剪该向量的容量到其大小
Stack的方法:.search(o1)返回该栈中指定元素的位置
Comparator 接口
Comparator接口 可以用于比较没有实现Comparable接口的类的对象Comparator接口 可以用于定义比较对象的新标准Comparator接口 包含方法.compare(o1,o2).comparing( func ).thenComparing( func ).reverse()用于生成逆序的比较器
.comparing( func )和.thenComparing( func )在编写简单的基于属性的简单比较逻辑时极度方便好用
Arrays.sort(list,Comparator.comparing(MyClass::getMainVal).thenComparing(MyClass::getOtherVal)); |
Collections 类 静态方法
- 。。。部分我认为简单常见的不再列出
reverseOrder()返回一个逆序排序的比较器shuffle(c1)随机打乱指定的线性表disjoint(c1,c2)如果c1和c2没有任何共同的元素,则返回真copy(des,src)浅拷贝,仅是复制了元素的引用
Queue 接口: Deque & PriorityQueue
Queue接口继承自java.util.CollectionQueue接口加入了 插入,提取,检验 等操作Queue定义的方法:offer(e)元素e入队- 元素出队并获取元素
poll()队空则抛出nullremove()队空则抛出异常
- 获取队头元素且不出队
peek()队空则抛出nullelement()队空则抛出异常
Deque接口继承自Queue接口,LinkedList类实现了Deque接口- 因此,可以用
LinkedList来创建一个**双端队列** LinkedList很适合用于队列操作,可以高效在列表的两端插入或移除Deque接口 继承自Queue接口,Deque是Double-Ended Queue双端队列Deque增加了队列从两端插入和删除元素的方法.addFirst(e).getFirst(e).removeFirst(e).addLast().getLast().removeLast()
PriorityQueue类 实现了一个优先队列- 默认情况下,优先队列使用
Comparable以元素的自然顺序进行排序 - 拥有最小数值的元素被赋予最高优先级(也就是,将最先出队)
- 如果几个元素拥有相同的最高优先级,则任意选择一个
- 可以使用构造方法
PriorityQueue( initialCapacity, comparator )中的comparator来指定一个顺序
周三
软工导论
社会内卷
- 一开始大家都在努力
- 后来,其中一个人通过努力淘汰了另一个人
- 不过人是会老的,而社会的节奏氛围快起来就慢不下来了
- 于是最后两个人都被淘汰了
作者:简在我心
链接:https://www.zhihu.com/question/346195467/answer/1287373146
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。一句话,大家越来越努力,越来越累,但是收获并没有增加,甚至实际上是下降了。
就像高考和高校绩效考核。
第一年,大家每年发一篇论文能得一万。
后来学校说多发多得。于是有人一年发了两篇,得了两万。
第二年,所有人发了两篇,结果大家还是只得了一万。因为学校的钱是个定数,没有增加。就像清北每年招生人数没有增加,增加的是所有人的努力。
第三年所有人发了三篇,所有人还是只得了一万……
n年后,大家每年发n篇论文,年终分红还是1万。
高考也是如此。
第一年,大家学习八小时,有个别同学学了十小时,他考上了清北。
第二年大家都学十个小时,结果只有学了十二个小时的学生考上了清北。
几年后,所有人每天学二十四个小时,清北还是只招那么千把人,怎么办呢?看谁家钱多,请的家教更牛逼……
这让我想起一部小说,属于内卷的升级版本。
刘震云写过一部小说叫《故乡相处流传》,里面有个吃蛋糕的情节。
大版食堂,把村里所有粮食做成一个大蛋糕,一开始随便吃。
后来看到蛋糕小了,村民意识到以后要挨饿了,于是拼命抢。
可是越是拼命抢,蛋糕消失得越快,所有人饿死得更快。
可是不抢的话,你饿死得更早。
是不是有点眼熟?
你不努力,你坠落更快;可是大家努力,大家坠落得更快。
———
原来一群人过独木桥,大家都慢悠悠的,每天能过去一千个人。
后来大家都聪明了,纷纷抢着过,结果堵在桥上,速度反而慢了。
再挤下去,独木桥断了。
还记得以前挤火车吗?
你不挤,你就没有机会上车。
可是大家都挤的话,因为有人的包被卡在门口,谁也进不了,越挤越动不了。
于是火车就开不了。
内卷,给人一种恐慌的感觉,大家在恐惧的驱使下,竭尽所能争夺资源,可是资源有限,大家越是争夺,资源损坏越大,甚至无序的竞争会带来毁灭性结局。
可是你不争,就被别人得了便宜,被人骂沙币。
归根结底,这样的争抢式的努力,只是从别人身上挖肉,而不是创造出新的价值。
这样的努力,看着很感人,实质上是无奈的徒劳的。
————
补充一下
其实社会发展到今天,凭现在的生产力,足以让所有人过上衣食无忧的生活。
但是由于分配问题,由于资本的压榨本能,使得大部分人并没有因为生产力和科技的发展获得相应的幸福感。
内卷的结果,是资本可以获得更加廉价的劳动力,资本增值更快。
但是劳动力本身却更苦了。
这也是为什么机器会吃人的根本原因。
机器哪会吃人,是资本要吃人。
尤其是在这个科技和知识是第一生产力的时代,内卷并不利于社会进步。
因为知识生产需要一个比较宽松的社会环境。
社会福利越好,知识生产反而会越佳。
那种残酷竞争所带来的不安全感,实际上是不利于科技进步的。
内卷状态下的知识生产者,是非常焦虑的。
相应的,知识学习者也是极度焦虑,这样的学习效果其实并不好。
这就是上面我专门举例高考和高校科研的原因所在。
更何况,这种过分的竞争极大的降低了人们的安全感和幸福感。
……
我所想象的理想世界是,每个人可以在解决温饱的前提下,做自己喜欢做的工作,焕发出最大的工作热情,从而促进社会进步。
当然,这只是理想。
数据流图 DFD
- 据说 microSoft Visio 画这个很方便
数据库设计,朱勇认为的,必须的三张表,三个字段
Java高级
- 发现,使用
Try-with-Resource配合 循环 进行使用时- 如果
Try-with-Resource在 循环体内 - 那么,仅首次循环能正常访问资源。
- 建议,将循环放在
Try-with-Resource的Try后花括号内
- 如果
// 实例 |
- 计算中缀表达式,用
numStack配合opStack,两个栈会更方便 - 而中缀转后缀并输出后缀表达式字符串,只用一个栈才更方便:运算符入栈,而数字直接出栈
周四
彭彬安卓
从 Activity 开始 —— 初步认识 Activity
- 彭老师说:入口函数
- 类比C语言、Java语言也是有 Main函数 的。
- 程序在编译执行时,先执行程序语言框架的初始启动加载指令,
- 在做好准备后,执行器去找固定的那个入口函数,从main的第一行指令再开始执行。
- 彭老师说:消息循环
- 电脑启动以后发生了什么?当电脑开机完成以后,大家看到一个桌面,这意味着什么?
- 意味着,电脑的操作系统已经启动好了,
- 经过了它自己的必要且复杂的启动过程,构建出了任务循环,进入等待。
- 等待什么,等待用户做的任何事情
- 比如双击,比如鼠标拖动
- 这些事情,都会成为信息,进入操作系统准备好的 任务循环/消息循环
- 收到消息以后,循环启动了,根据相应的消息,触发相应的操作,
- 比如,我双击了Chrome浏览器图标,操作系统就会去找,找Chrome程序托管在操作系统里的根
- 操作系统打开这个根,这个根就是这次任务的入口函数
- 启动Chrome浏览器这个任务本身会带来一些消息,返回给操作系统
- 执行了启动Chrome这个任务,操作系统自己又会记录一些消息
- 这些消息,有些会存在系统里,有些会以种种形式 交互 给用户
- 消息/任务 在这个活动里 有进有出,这就是循环。
- 彭老师说:生存环境
- Linux生存在 C语言 编写的操作系统内核上
- 安卓生存在 由Linux改编而来的 操作系统内核上
- 基于安卓开发的APP 生存在 安卓提供的 内核服务上
- 我说:
- 内核服务是什么。就是 SDK,就是ADK,就是胡隽讲了很多次的请求内核服务
- 也就是 计算机专业名词
Framework
- 彭老师说:Activity
- 之前提到的那个循环,就是一个Acitvity;Acitvity就是一个服务循环
- Acitivity启动以后,就是在等待消息,然后再去做相应的触发事情
- 重要的是:安卓应用的几乎每一个界面,都是一个 Activity
- 所有的 Activity 都最终继承自
android.app.activity
安卓 HelloWorld 工程
打字稍慢,有点跟不上哈哈哈哈
- 彭老师说:包名
- 安卓是Java开发的,包名是从Java开发延续下来的习惯
- 根据程序员们约定俗成的习惯,我们习惯将 域名 设置为 包名
- 因为对咱们程序员来言,“域名,是一个人或者一个组织,在互联网上唯一的标示”
- 彭老师说:安卓版本
- 应用程序设定的:指定运行的安卓版本,是向上向后兼容的。
- 如果这个应用程序是指定版本
Android 5.0,那么他应该是在Android ≥ 5.0的环境上能正常运行 - 除非,某个安卓版本进行了的特别大的不可兼容的更新。
- 比如 安卓10,安卓5 的 app 在安卓10上就可能会闪退,因为安卓10是一次很大的不向下向前兼容的更新。
- 彭老师说:布局 算法 布局器 布局文件 设置配置
- 布局,对程序员而言,就是 什么东西改摆放在哪里,该怎么摆的算法
- 布局器,就是官方为我们提供的布局算法,省得我们自己再去开发了
- 布局文件,就是对布局器提供的配置文件,能帮我们更好地使用布局器
- 因为,布局算法,一般都挺复杂的,会有很多参数,很多选项之类的东西
- 这些东西,为了方便,就从代码里抽离出来,放在专门的布局文件里
- 布局器会加载这个文件,按这个文件的配置来实现具体的布局
- 彭老师说:看看 HelloWorld 中的 Acitivity
|
- 彭老师问:什么是
@Override—— 是一个注解/标注 - 彭老师问:看到
onCreate大家想到了什么 —— 是一个 事件触发 的函数,在 create 时会触发的函数 - 彭老师问:
setContentView(R.layout.activity_main)- 观察参数:
- R → Resource(资源)
- layout → 布局
- activity_main → 一个静态常量
- 特殊的,R 不是程序员自己写的,是安卓这个框架自己生成的。
- 安卓框架把所有的Resource资源编译到 R 这个
public final class里 - 程序员在程序中通过访问 R 来访问工程的所有静态资源
彭老师说:结对编程(请百度,蛮好玩)两个人水平要差不多,效果才最好
彭老师说:所有在安卓程序里能被称为 组件 的东西,都是 View 这个类的子孙后代
彭老师说:XML文件,读作chā mile
“从今天起,咱们班任何一个同学都不能说自己不认识XML文件了啊”
XML格式:
- 标签名,标签属性,标签嵌套
android:icon里的android是一个命名空间,icon是这个空间下的一个属性名
C语言为什么从一般的应用开发里退出了。就是因为C语言没有“命名空间”,他的所有命名都是全局污染。
XML被发明出来是为了用于 数据交换 的。
彭彬 Java泛型 的知识补充
- 泛型存在的必要性:为了实现,算法 和 算法的操作对象 二者的分离解耦。
- 泛型不是语法糖
- 泛型是在编译时,通过类型擦除来生效的。
.class语法是Java提供的一个蓝图类,用于获取一个可以描述当前对象的类规范.class蓝图类语法,是在运行时,通过反射机制来生效。- 泛型 与
.class语法相比,或许在,将”类型参数化“上可以起到相似或者相同的效果,但是在 算法 与 算法的操作对象 分离 的目标上,.class的抽象层次没有泛型<>这样彻底。“两者属于不同的抽象层次”。
实验课内容
- 彭老师向大家热烈推荐了:<<阿里巴巴Java开发手册>>
- 文件放在
FTP: penbdownload上/2020智能终端与移动应用开发/课件/补充资料/阿里巴巴Java开发手册.pdf - 彭老师建议,这本书,每天看个 4~5 条,看不懂也留个印象在。
- 并向大家简述了其中的两点。
- 【推荐】慎用 Object 的 clone 方法来拷贝对象。
- 说明:对象的 clone 方法默认是浅拷贝,若想实现深拷贝需要重写 clone 方法实现属性对象 的拷贝
- 【强制】关于 hashCode 和 equals 的处理,遵循如下规则:
- 只要重写equals,就必须重写hashCode。
- 因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的 对象必须重写这两个方法。
- 如果自定义对象做为Map的键,那么必须重写hashCode和equals。
- 正例:String 重写了 hashCode 和 equals 方法,所以我们可以非常愉快地使用 String 对象 作为 key 来使用。
- 【推荐】慎用 Object 的 clone 方法来拷贝对象。
- 关于 浅拷贝 和 深拷贝:我还是不清楚:如果对象只有“一层”,那么浅拷贝深拷贝效果相同?
- 怎样实现一层的深拷贝呢?
- 关于
hashcode和equals- 各自是什么
- 为什么要一起重写
- 什么时候要重写
释疑
如果对象只有一层,那么浅拷贝和深拷贝效果相同。
对象的属性,
- 如果属性的值是“普通值”,那么浅拷贝会直接复制并新建一个副本
- 如果属性的值是“对象”,那么浅拷贝就仅仅是复制这个对象的引用
对于 两个东西 相等 这件事,有两个概念
- 一是,两个东西 的 值 相等,这由
equals()来决定 - 二是,两个东西 是 同一个东西,这由
hashCode()来决定
- 一是,两个东西 的 值 相等,这由
两个函数一起重写,能保证 当 两个东西的值相等时,就认定为同一个东西
在 Java 提供的 集合类 中,这尤其有必要