《精益创业》一书对 MVP 和迭代思维有比较好的讲解,可以看看。
PS:有篇老外写的关于 MVP 的文章不错,其中的配图被到处使用。可能需要:Making sense of MVP (Minimum Viable Product) - and why I prefer Earliest Testable/Usable/Lovable
https://www.ibm.com/developerworks/cn/opensource/os-cn-bigdata-ambari/index.html
https://www.ibm.com/developerworks/cn/opensource/os-cn-bigdata-ambari2/
https://mp.weixin.qq.com/s?__biz=MzIzMzgxOTQ5NA==&mid=2247489505&idx=3&sn=ef74759dda79a0e8f99bae8350f4d7be&chksm=e8fe8be8df8902fe9643405ac4e23196a41128d63afd7451960e26c5783f301d46ba0287c4d5&scene=21#wechat_redirect
参与开源项目的最佳办法就是加入到你正在使用的已有项目上来。
我们推荐你从已正在使用的或感兴趣的项目开始。这里有几个很棒的地方供你参考:
GitHub Explore: 受欢迎和热门的项目。
GitHub Stars: 被其他人star过的项目(指的是你自己库的项目)。
GitHub Showcases: 一个能搜索相关库的方法。
LayerVault News: .前端和设计相关的项目。
如果你发现了你正在使用的项目中的一个bug(但是你不知道怎么去修复它),或对文档有不解或对项目有疑问 — 那么创建一个话题吧!
创建话题专业提示
1.在建话题之前检查已有的话题:话题重复对双方都无利,所以搜索整个正开放和已关闭的话题以检查你遇到的问题是否已经有人解决了。
2.务必对自己的问题有清晰的认识:期望的结果是什么?然而却发生了什么? 详细描述其他人如何重现该问题。
3.在像JSFiddle 或CodePen类似的平台上重现该问题并给出问题demo的链接。
4.包含一些系统相关的细节,比如用的什么浏览器、库或操作系统及版本号。
5.在你的话题或在Gist里贴出你的错误输出或日志。如果在话题里贴出来,请用三个反引号``` 包围起来使得能够良好的呈现给大家。
learn-github-from-zero.pdf 百度网盘。ended
Git的最佳资料,关于 Git 看这几份资料足够了:
1. ProGit中文版:
https://git-scm.com/book/zh/v2
2. 廖雪峰的Git教程:
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
3. Git简易指南:
http://rogerdudler.github.io/git-guide/index.zh.html
https://mp.weixin.qq.com/s?__biz=MzIzMzgxOTQ5NA==&mid=2247489522&idx=1&sn=e56c83eae436e177306a4d818d2ef73c&chksm=e8fe8bfbdf8902eda75dd7afe069cf8d7a70b9b183b95035859a5ded5609956393a73a2f8b39&scene=21#wechat_redirect
通过线程池复用线程有以下几点优点:
减少资源创建 => 减少内存开销,创建线程占用内存
降低系统开销 => 创建线程需要时间,会延迟处理的请求
提高稳定稳定性 => 避免无限创建线程引起的OutOfMemoryError【简称OOM】
ThreadPoolExecutor的构造函数共有四个,但最终调用的都是同一个:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue
workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
线程池执行任务逻辑和线程池参数的关系
# 总结:
FixedThreadPool和SingleThreadExecutor => 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而引起OOM异常
CachedThreadPool => 允许创建的线程数为Integer.MAX_VALUE,可能会创建大量的线程,从而引起OOM异常
这就是为什么禁止使用Executors去创建线程池,而是推荐自己去创建ThreadPoolExecutor的原因
CPU密集型 => 线程池的大小推荐为CPU数量 + 1,CPU数量可以根据Runtime.availableProcessors方法获取
IO密集型 => CPU数量 * CPU利用率 * (1 + 线程等待时间/线程CPU时间)
混合型 => 将任务分为CPU密集型和IO密集型,然后分别使用不同的线程池去处理,从而使每个线程池可以根据各自的工作负载来调整
阻塞队列 => 推荐使用有界队列,有界队列有助于避免资源耗尽的情况发生
拒绝策略 => 默认采用的是AbortPolicy拒绝策略,直接在程序中抛出RejectedExecutionException异常【因为是运行时异常,不强制catch】,这种处理方式不够优雅。处理拒绝策略有以下几种比较推荐:
在程序中捕获RejectedExecutionException异常,在捕获异常中对任务进行处理。针对默认拒绝策略
使用CallerRunsPolicy拒绝策略,该策略会将任务交给调用execute的线程执行【一般为主线程】,此时主线程将在一段时间内不能提交任何任务,从而使工作线程处理正在执行的任务。此时提交的线程将被保存在TCP队列中,TCP队列满将会影响客户端,这是一种平缓的性能降低
自定义拒绝策略,只需要实现RejectedExecutionHandler接口即可
如果任务不是特别重要,使用DiscardPolicy和DiscardOldestPolicy拒绝策略将任务丢弃也是可以的
如果使用Executors的静态方法创建ThreadPoolExecutor对象,可以通过使用Semaphore对任务的执行进行限流也可以避免出现OOM异常
Stream API的性能到底如何呢,代码整洁的背后是否意味着性能的损耗呢?
1、对于简单操作,比如最简单的遍历,Stream串行API性能明显差于显示迭代,但并行的Stream API能够发挥多核特性。
2、对于复杂操作,Stream串行API性能可以和手动实现的效果匹敌,在并行执行时Stream API效果远超手动实现。
所以,如果出于性能考虑
1、对于简单操作推荐使用外部迭代手动实现
2、对于复杂操作,推荐使用Stream API
3、在多核情况下,推荐使用并行Stream API来发挥多核优势,
4、单核情况下不建议使用并行Stream API。
如果出于代码简洁性考虑,使用Stream API能够写出更短的代码。即使是从性能方面说,尽可能的使用Stream API也另外一个优势,那就是只要Java Stream类库做了升级优化,代码不用做任何修改就能享受到升级带来的好处。
https://www.jianshu.com/p/0bb4daf6c800?from=groupmessage
Stream 和集合的其中一个差异在于什么时候进行计算。
一个集合,它会包含当前数据结构中所有的值,你可以随时增删,但是集合里面的元素毫无疑问地都是已经计算好了的。
流则是按需计算,按照使用者的需要计算数据,你可以想象我们通过搜索引擎进行搜索,搜索出来的条目并不是全部呈现出来的,而且先显示最符合的前 10 条或者前 20 条,只有在点击 “下一页” 的时候,才会再输出新的 10 条。
再比方在线观看电影和你硬盘里面的电影,也是差不多的道理。
Stream 和集合的另一个差异在于迭代。
我们可以把集合比作一个工厂的仓库,一开始工厂比较落后,要对货物作什么修改,只能工人亲自走进仓库对货物进行处理,有时候还要将处理后的货物放到一个新的仓库里面。在这个时期,我们需要亲自去做迭代,一个个地找到需要的货物,并进行处理,这叫做外部迭代。
后来工厂发展了起来,配备了流水线作业,只要根据需求设计出相应的流水线,然后工人只要把货物放到流水线上,就可以等着接收成果了,而且流水线还可以根据要求直接把货物输送到相应的仓库。这就叫做内部迭代,流水线已经帮你把迭代给完成了,你只需要说要干什么就可以了(即设计出合理的流水线)。
Java 8 引入 Stream 很大程度是因为,流的内部迭代可以自动选择一种合适你硬件的数据表示和并行实现;而以往程序员自己进行 foreach 之类的时候,则需要自己去管理并行等问题。
流和迭代器类似,只能迭代一次。
lambda表达式是Stream API的基石。
我们常常会看到这样的代码
Arrays.sort(new Integer[]{1, 8, 7, 4}, new Comparator() {
@Override
public int compare(Integer first, Integer second) {
return first.compareTo(second);
}
});
上面这种写法就是使用了匿名类,我们经常会使用匿名类的方式,因为我们只运行一次,不想它一直存在。
上面的代码写着麻烦,但是转换成下面这样的呢?
Arrays.sort(new Integer[]{1, 8, 7, 4},
(first,second) -> first.compareTo(second));
把一些不必要的细节都屏蔽。对于这种只包含一个抽象方法的接口,你可以通过lambda接口来创建该接口的对象,这种接口被称为函数式接口。
lambda表达式引入了一个新的操作符:->,它把lambda表达式分为了2部分
(n) -> n*n
左侧指定表达式所需的参数,如果不需要参数,也可以为空。右侧是lambda代码块,它指定lambda表达式的动作。
需要注意的是如果方法中只有一个返回的时候不用声明,默认会返回。如果有分支返回的时候需要都进行声明。
(n) -> {
if( n <= 10)
return n*n;
return n * 10;
}
方法引用
有些时候,先要传递给其他代码的操作已经有实现的方法了。比如GUI中先要在按钮被点击时打印event对象,那么可以这样调用
button.setOnAction(event -> System.out.println(event));
这个时候我想偷懒,我不想写event参数,因为只有一个参数,jvm不能帮帮我吗?下面是修改好的代码
button.setOnAction(System.out::println);
表达式System.out::println
是一个方法引用,等同于lambda表达式x -> System.out.println(x)
。::操作符将方法名和对象或类的名字分割开来,以下是三种主要的使用情况:
前两种情况,方法引用等同于提供方法参数的lambda表达式。比如Math::pow ==== (x,y) -> Math.pow(x,y)
。
第三种情况,第一个参数会称为执行方法的对象。比如String::compareToIgnoreCase ==== (x,y) -> x.compareToIgnoreCase(y)
。
还有this::equals ==== x -> this.equals(x)
,super::equals ==== super.equals(x)
。
构造器引用
List strList = Arrays.asList("1","2","3");
Stream stream = strList.stream().map(Integer::new);
上面代码的Integer::new
就是构造器引用,不同的是在构造器引用中方法名是new。如果存在多个构造器,编译器会从上下文推断并找出合适的那一个。
知识星球
Google Chrome
IntelliJ IDEA
插件推荐
Alibaba Java Coding Guidelines |
《阿里巴巴Java开发规约》扫描插件,让你的编码规范起来 |
GitHub
github 教程: learn-github-from-zero,作者 stormzhang
掘金
一个高质量的技术社区
LeetCode
简单来说就是一个刷题网站,里面有各种类型的算法题目,每天做那么一点,既能加强算法,也能保持编码手感以及训练写白板代码。
七牛云
一个方便快捷的云存储平台,可以用作些小项目的云存储,同时它为所有用户提供了免费的额度,是一个很适合个人使用的云存储平台。
ProcessOn
一个很好用的在线作图网站,支持流程图、思维导图、原型图、UML、网络拓扑图等,不过呢,免费版每个账号只能新建 9 个文件,当然,如果不想花这个钱的话,作完一张图之后保存到本地,然后重新作图也是可以的。
有道云笔记
阿里巴巴 Java 手册
代码托管服务和工具:
国内服务:
国外服务:
成功大数据项目的路线图
成功大数据的路线图分为六步:
第一步:确定对企业业务有重大影响的大数据用例和创新方向。
第二步:我们要制定基于大数据项目的详尽的产品服务创新规划。
第三步:要详细了解大数据项目所需要的业务功能要求和选择与之相匹配的技术。
第四步:就大数据项目带来的商业利益在企业内部达成共识。
第五步:我们要选择容易实现的目标入手,快速迭代研发、试错、稳步推进。也就是说不要刚开始就要搞高大上、大而全的项目,因为失败的几率几乎是百分之百,非常容易失败,因为预算太大,选的工具太复杂,调动的资源很多,很难一下子实现所有的目标,所以通常我们从一个晓得目标,容易实现的目标开始,这样可以鼓励士气,错误犯在研发的初期,而不是在中期和最后,这个最重要。
第六步:做大数据项目和产品一定要挖掘和实现大数据能给我们带来的特殊价值,这是其它的方法或者是其它类的数据做不到的,只有实现了这种特殊的价值,我们才能实现业务所需要的具体功能,不管是扩展市场的份额,或者是更精准的了解你的客户需求,还是说你要增加边际利润率,或者是提高产品上市的速度,缩短研发周期,这些都是大数据可以做的。另外就是跨界创新,传统企业可以通过大数据这个纽带跟其他企业的业务结合起来。
十二个各个领域都包含的项目案列,小编都有搭建与设计视频,有一定大数据基础与工作经验的朋友是可以根据视频内容完成整个项目的搭建的。非常的实用!需要视频的朋友,加入小编的java与大数据交流圈子615997810找群主获取视频学习这些项目的搭建。下面就来给大家介绍一下这十二个项目主要的内容与领域的权重值:
1,离线数据处理:项目内容为通过对网站访问日志的采集和清洗,结合数据库中的结构化用户数据,统计并展示网站的PV、UV情况,以对网站的运行情况进行监控。通过此项目,回顾并串联前面讲述的离线数据处理相关技术,如:FIune、Sqoop、Hive、Spark等,了解和掌握PB级数据离线处理的一般过程和架构。
2,流式数据处理:项目内容为通过对数据库交易数据修改的实时同步,监控网站实时交易情况,以提高网站交易情况监控的时效性,降低网站运行的风险。 通过此项目,回顾并串联前面讲述的实时数据处理相关技术,如:kafka、Spark、Streaning和HBase等,了解和掌握实时数据处理的一般过程和架构。
3,推荐系统:项目内容,基于公开数据库的商品推荐,某大型互金公司产品推荐系统剖析, 通过对公司实际推荐项目的剖析和根据真实数据搭建推荐系统的实操演练,了解推荐系统的一般架构和常用算法。
4,搜索系统:项目内容,通过网站爬虫爬取网站数据,然后基于KlastlcSeard和Klbana搭建一个完整的搜索系统。
5,系统运行情况仪表盘: 通过对网站访问日志的采集和清洗,结合数据库中的结构化用户数据,统计并展示网站的PV,UV情况,以对网站的运行情况进行监控。通过此项目,回顾并串联前面讲述的离线数据处理相关技术,如Flume,Sqoop,Hive,Spark等,掌握PB级数据离线处理的一般过程和架构。
6, 实时交易监控系统 : 过对数据库交易数据修改的实时同步,监控网站实时交易情况,以提高网站交易情况监控的时效性,降低网站运行的风险。通过此项目,回顾并串联前面讲述的实时数据处理相关技术,如Kafka,Spark Streaming和HBase等,掌握实时数据处理的一般过程和架构。
7,推荐系统理论与实战: 讲解推荐系统的相关背景,常用算法及通用架构;基于公开数据集从零构建一个电影推荐系统。通过对公司实际推荐项目的剖析和根据真实数据搭建推荐系统的实操演练,了解推荐系统的一般架构和常用算法
8,数据仓库搭建理论与实战: 讲解数据仓库搭建的方法论,常用建模理论;以互金公司数据仓库搭建场景作为切入,实例演示数据仓库搭建过程及技术架构。
9,分布式业务监控系统: 讲解业务监控系统需求背景,基于大数据的技术方案;通过实例代码搭建完整的业务监控系统
10,基于ES的日志系统 : 基于Flume,ElasticSearch等技术搭建系统日志收集与查询系统。
11,信贷需求预测系统: 以京东信贷需求预测竞赛为背景,实例讲解数据挖掘项目中如何设计特征,模型基础,建模以及调参等。
12,用户画像系统 : 讲解用户画像系统的需求背景,基于大数据技术的解决方案;通过实例代码演示用户画像系统的搭建。
已读书目:
《数据产品设计》艾达。关注目录即可。
《数据资产管理——盘活大数据时代的隐形财富》高伟
数据资产治理的三全:全景(场景)、全生命周期(时间)、全流程(空间)
开放组体系架构框架TOGAF。
当数据分析成为一种搜索:
搜索式的数据分析能力,把数据分析的过程,变成寻求不同答案的过程,基于对现有数据的认识,通过一系列的假设、关联、验证,最终找到一个相对可靠的答案。
数据应用商店:交易数据产品、数据算法。