首页 文章 精选 留言 我的

精选列表

搜索[整理],共9147篇文章
优秀的个人博客,低调大师

Java8 Stream常用API整理(值得收藏)

点击上方“Java专栏”,选择“置顶或者星标” 第一时间阅读精彩文章! 点击这段文字获取:5个可以写到简历的项目实战视频教程(含源码) 题 图:pexels 作 者:程铭程铭你快成名 来 源:https://blog.csdn.net/wangchengming1/article/details/89245402 Java8中有两大最为重要的改变,第一个是Lambda表达式,另外一个则是Stream API。 流是 Java8 引入的全新概念,它用来处理集合中的数据。 众所周知,集合操作非常麻烦,若要对集合进行筛选、投影,需要写大量的代码,而流是以声明的形式操作集合,它就像 SQL 语句,我们只需告诉流需要对集合进行什么操作,它就会自动进行操作,并将执行结果交给你,无需我们自己手写代码。 在项目中使用 Stream API 可以大大提高效率以及代码的可读性,使我们对数据进行处理的时候事半功倍。 这篇博文以实战角度出发,讲解平时开发中常用 API 的用法以及一些注意的地方。 首先创建一个对象 publicclassEmployee{privateintid;privateString name;privateintage;privatedoublesalary;privateStatus status;publicenumStatus {FREE, BUSY, VOCATION;}publicEmployee(){}publicEmployee(String name){this.name = name;}publicEmployee(String name, intage){this.name = name;this.age = age;}publicEmployee(intid, String name, intage, doublesalary){this.id = id;this.name = name;this.age = age;this.salary = salary;}publicEmployee(intid, String name, intage, doublesalary, Status status){this.id = id;this.name = name;this.age = age;this.salary = salary;this.status = status;}//省略get,set等。。。} 随便初始化一些数据 List<Employee> empList = Arrays.asList(newEmployee(102, "李四", 59, 6666.66, Status.BUSY),newEmployee(101, "张三", 18, 9999.99, Status.FREE), newEmployee(103, "王五", 28, 3333.33, Status.VOCATION),newEmployee(104, "赵六", 8, 7777.77, Status.BUSY), newEmployee(104, "赵六", 8, 7777.77, Status.FREE),newEmployee(104, "赵六", 8, 7777.77, Status.FREE), newEmployee(105, "田七", 38, 5555.55, Status.BUSY)); 中间操作 根据条件筛选 filter /*** 接收Lambda, 从流中排除某些元素。*/@TestvoidtestFilter(){ empList.stream().filter((e) -> {returne.getSalary() >= 5000;}).forEach(System.out::println);} 跳过流的前n个元素 skip /*** 跳过元素,返回一个扔掉了前n个元素的流。*/@Testvoid testSkip() {empList.stream().filter((e) -> e.getSalary() >= 5000).skip(2).forEach(System.out::println);} 去除重复元素 distinct /*** 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素*/@Testvoid testDistinct() {empList.stream().distinct().forEach(System.out::println);} 截取流的前n个元素 limit /*** 截断流,使其元素不超过给定数量。*/@Testvoid testLimit() {empList.stream().filter((e) -> {returne.getSalary() >= 5000; }).limit(3).forEach(System.out::println);} 映射 map /*** 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素*/@Testvoid testMap() {empList.stream().map(e -> e.getName()).forEach(System.out::println);empList.stream().map(e -> {empList.forEach(i -> {i.setName(i.getName() + "111");});returne;}).collect(Collectors.toList());} 自然排序 sorted /*** 产生一个新流,其中按自然顺序排序*/@Testvoid testSorted() {empList.stream().map(Employee::getName).sorted().forEach(System.out::println);} 自定义排序 sorted(Comparator comp) /*** 产生一个新流,其中按自然顺序排序*/@Testvoid testSortedComparator() {empList.stream().sorted((x, y) -> {if(x.getAge() == y.getAge()) {returnx.getName().compareTo(y.getName()); } else{returnInteger.compare(x.getAge(), y.getAge());}}).forEach(System.out::println);} 最终操作 是否匹配任一元素 anyMatch /*** 检查是否至少匹配一个元素*/@TestvoidtestAnyMatch() {boolean b = empList.stream().anyMatch((e) -> e.getStatus().equals(Status.BUSY));System.out.println("boolean is : "+ b);} 是否匹配所有元素 allMatch /*** 检查是否匹配所有元素*/@TestvoidtestAllMatch() {boolean b = empList.stream().allMatch((e) -> e.getStatus().equals(Status.BUSY));System.out.println("boolean is : "+ b);} 是否未匹配所有元素 noneMatch /*** 检查是否没有匹配的元素*/@TestvoidtestNoneMatch() {boolean b = empList.stream().noneMatch((e) -> e.getStatus().equals(Status.BUSY));System.out.println("boolean is : "+ b);} 返回第一个元素 findFirst /*** 返回第一个元素*/@TestvoidtestFindFirst() {Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();if(op.isPresent()) {System.out.println("first employee name is : "+ op.get().getName().toString());}} 返回流中任意元素 findAny /*** 返回当前流中的任意元素*/@TestvoidtestFindAny() {Optional<Employee> op = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findAny();if(op.isPresent()) {System.out.println("any employee name is : "+ op.get().getName().toString());}} 返回流的总数 count /*** 返回流中元素的总个数*/@TestvoidtestCount() {longcount = empList.stream().filter((e) -> e.getStatus().equals(Status.FREE)).count();System.out.println("Count is : "+ count);} 返回流中的最大值 max /*** 返回流中最大值*/@TestvoidtestMax(){Optional<Double> op = empList.stream().map(Employee::getSalary).max(Double::compare);System.out.println(op.get());} 返回流中的最小值 min /*** 返回流中最小值*/@TestvoidtestMin() {Optional<Employee> op2 = empList.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println(op2.get());} 归约 reduce归约是将集合中的所有元素经过指定运算,折叠成一个元素输出 /*** 可以将流中元素反复结合起来,得到一个值。返回T*/@TestvoidtestReduce(){Optional<Double> op = empList.stream().map(Employee::getSalary).reduce(Double::sum);System.out.println(op.get());}/*** 可以将流中元素反复结合起来,得到一个值,返回Optional< T>*/@TestvoidtestReduce1(){Optional<Integer> sum = empList.stream().map(Employee::getName).flatMap(Java8Stream::filterCharacter).map((ch) -> {if(ch.equals('六'))return1;elsereturn0;}).reduce(Integer::sum);System.out.println(sum.get());} 将元素收集到 list 里 Collectors.toList() /*** 把流中的元素收集到list里。*/@Testvoid testCollectorsToList() {List<String> list= empList.stream().map(Employee::getName).collect(Collectors.toList());list.forEach(System.out::println);} 将元素收集到 set 里 Collectors.toSet() /*** 把流中的元素收集到set里。*/@Testvoid testCollectorsToSet() {Set<String> list= empList.stream().map(Employee::getName).collect(Collectors.toSet());list.forEach(System.out::println);} 把流中的元素收集到新创建的集合里Collectors.toCollection(HashSet::new) /*** 把流中的元素收集到新创建的集合里。*/@Testvoid testCollectorsToCollection() {HashSet<String> hs = empList.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));hs.forEach(System.out::println);} 根据比较器选择最大值 Collectors.maxBy() /*** 根据比较器选择最大值。*/@TestvoidtestCollectorsMaxBy(){Optional<Double> max = empList.stream().map(Employee::getSalary).collect(Collectors.maxBy(Double::compare));System.out.println(max.get());} 根据比较器选择最小值 Collectors.minBy() /*** 根据比较器选择最小值。*/@TestvoidtestCollectorsMinBy(){Optional<Double> max = empList.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));System.out.println(max.get());} 对流中元素的某个字段求和 Collectors.summingDouble() /*** 对流中元素的整数属性求和。*/@TestvoidtestCollectorsSummingDouble(){Double sum = empList.stream().collect(Collectors.summingDouble(Employee::getSalary));System.out.println(sum);} 对流中元素的某个字段求平均值 Collectors.averagingDouble() /*** 计算流中元素Integer属性的平均值。*/@TestvoidtestCollectorsAveragingDouble(){Double avg = empList.stream().collect(Collectors.averagingDouble(Employee::getSalary));System.out.println(avg);} 分组,类似sql的 group byCollectors.groupingBy /*** 分组*/@TestvoidtestCollectorsGroupingBy(){Map<Status, List<Employee>> map= empList.stream().collect(Collectors.groupingBy(Employee::getStatus));System.out.println(map);} 多级分组 /*** 多级分组*/@TestvoidtestCollectorsGroupingBy1(){Map<Status, Map<String, List<Employee>>> map= empList.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {if(e.getAge() >= 60)return"老年";elseif(e.getAge() >= 35)return"中年";elsereturn"成年";})));System.out.println(map);} 字符串拼接 Collectors.joining() /*** 字符串拼接*/@TestvoidtestCollectorsJoining(){String str = empList.stream().map(Employee::getName).collect(Collectors.joining(",", "----", "----"));System.out.println(str);} publicstaticStream<Character> filterCharacter(String str) {List<Character> list= newArrayList<>();for(Character ch : str.toCharArray()) {list.add(ch);}returnlist.stream();} 以上,便是今天的分享,希望大家喜欢,觉得内容不错的,欢迎点击「在看」支持,谢谢各位 150页,8W字的Java知识手册 获取方式:1、公众号后台回复「手册」2、扫描下方二维码,回复「手册」 👆 长按上方二维码2 秒 回复「 手册 」即可获取资料 本文分享自微信公众号 - Java专栏(finishbug)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

最强整理:微信小程序的前世今生

微信小程序 一、小程序介绍 背景与趋势 小程序技术方案 公众平台注册及配置 开发工具的使用 MINA框架架构剖析 应用程序配置详解 逻辑与界面分离架构 单向数据流 二、UI开发 复杂的页面布局 文字图片等内容的呈现 用户交互表单开发 对话框等交互元素开发 下拉刷新和上拉加载 图形与动画操作 页面之间的跳转过渡 用户界面事件处理 三、小程序项目实战 3.1 微信小程序的文件结构 —— 教程系列(1) 微信小程序的生命周期实例演示 —— 微信小程序教程系列(2) 微信小程序的动态修改视图层的数据 —— 微信小程序教程系列(3) 微信小程序如何新建页面 —— 微信小程序教程系列(4) 微信小程序的如何使用全局属性 —— 微信小程序教程系列(5) 微信小程序的页面跳转和参数传递 —— 微信小程序教程系列(6) 微信小程序标题栏和导航栏的设置 —— 微信小程序教程系列(7) 微信小程序的作用域和模块化 —— 微信小程序教程系列(8) 微信小程序视图层的数据绑定 —— 微信小程序教程系列(9) 微信小程序之wx:if视图层的条件渲染 —— 微信小程序教程系列(10) 微信小程序视图层的列表渲染 —— 微信小程序教程系列(11) 微信小程序视图层的模板 —— 微信小程序教程系列(12) 微信小程序之wxss —— 微信小程序教程系列(13) 微信小程序的网络请求 —— 微信小程序教程系列(14) 微信小程序的百度地图获取地理位置 —— 微信小程序教程系列(15) 微信小程序使用百度api获取天气信息 —— 微信小程序教程系列(16) 微信小程序获取系统日期和时间 —— 微信小程序教程系列(17) 微信小程序之上拉加载和下拉刷新 —— 微信小程序教程系列(18) 微信小程序之组件 —— 微信小程序教程系列(19) 微信小程序之微信登陆 —— 微信小程序教程系列(20) 微信小程序之顶部导航栏(选项卡)实例 —— 微信小程序实战系列(21) 微信小程序之加载更多(分页加载)实例 —— 微信小程序实战系列(22) 微信小程序之自定义轮播图实例 —— 微信小程序实战系列(23) 微信小程序之仿android fragment之可滑动的底部导航栏实例 —— 微信小程序实战系列(24) 微信小程序之登录页实例 —— 微信小程序实战系列(25) 微信小程序之自定义toast实例 —— 微信小程序实战系列(26) 微信小程序之自定义抽屉菜单(从下拉出)实例 —— 微信小程序实战系列(27) 微信小程序之自定义模态弹窗(带动画)实例 —— 微信小程序实战系列(28) 微信小程序之侧栏分类 —— 微信小程序实战商城系列(29) 微信小程序之仿淘宝分类入口 —— 微信小程序实战商城系列(30) 微信小程序之购物数量加减 —— 微信小程序实战商城系列(31) 微信小程序之商品属性分类 —— 微信小程序实战商城系列(32) 微信小程序之购物车 —— 微信小程序实战商城系列(33) 最后 Alvin老师已经将精品网课、书籍、BAT面试文档、项目专题源码等资料已分享在网盘中,并在持续更新中。欢迎关注Alvin老师微信号VX:Android-Alvin 前往领取!

优秀的个人博客,低调大师

最强开源微服务框架,全网独家整理

诞生于 2014 年的“微服务架构”,其思想经由 Martin Fowler 阐述后,在近几年持续受到重视,理论与相关实践都不断发展,目前它已经成为了主流软件架构模式。 关于微服务架构是什么,没有一个明确的定义,每个实践者有自己的理解,但是有人给出的一个公式值得思考: 微服务架构 = 80% 的 SOA 服务架构思想 + 100% 的组件化架构思想 + 80% 的领域建模思想 微服务架构的优点很多,比如它解耦业务,提供更高的灵活性,允许在服务频繁发版的同时保持系统其它部分的可用性与稳定性;解耦编程语言,针对不同业务可以使用更加合适的语言进行开发;解耦开发团队,不同团队各自负责一个微服务,互不影响,加速交付。 关于微服务架构,网上资料相当多(因为现在很火,各家都有实践案例分享),读者可以另行查阅,这里不赘述。 下边为大家列举了当前最为火热,最常被人提及的开源微服务开发框架,希望对开发者有一定的帮助(点击项目名,可以直接跳转介绍页): Spring Cloud Spring Cloud 为开发者提供了分布式系统配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性 Token、全局锁、决策竞选、分布式会话与集群状态等的开发工具。使用 Spring Cloud 开发者可以快速实现上述这些模式。 Eclipse MicroProfile Eclipse MicroProfile 是一个 Java 微服务开发的基础编程模型,它致力于定义企业 Java微服务规范,MicroProfile 提供指标、API 文档、运行状况检查、容错与分布式跟踪等能力,使用它创建的云原生微服务可以自由地部署在任何地方,包括 Service Mesh 架构,如 Istio。 Dubbo Dubbo 是阿里开源的一款高性能 RPC 框架,特性包括基于透明接口的 RPC、智能负载均衡、自动服务注册和发现、可扩展性高、运行时流量路由与可视化的服务治理。 Tars Tars 是腾讯将其内部使用的微服务框架TAF(Total Application Framework)多年的实践成果总结而成的开源项目,在腾讯内部有上百个产品使用,服务内部数千名 C++、Java、Golang、Node.Js 与 PHP 开发者。其包含一整套开发框架与管理平台,兼顾多语言、易用性、高性能与服务治理,理念是让开发更聚焦业务逻辑,让运营更高效。 Helidon Helidon 是甲骨文开源的一个微服务框架,编写的微服务运行在由 Netty 提供支持的快速 Web 内核上。 SOFAStack SOFAStack™(Scalable Open Financial Architecture Stack)是由蚂蚁金服开源的一套用于快速构建金融级分布式架构的中间件,也是在金融场景里锤炼出来的最佳实践。 gRPC gRPC 是谷歌开源的高性能通用 RPC 框架。gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩与单 TCP 连接上的多路复用请求等特性,这些特性使得其在移动设备上表现更好,更省电和节省空间占用。 Thrift Thrift 是一个 RPC 框架,用来开发可扩展且跨语言的服务。它结合了功能强大的软件堆栈和代码生成引擎,以构建可以在 C++、Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk 与 OCaml 等语言间无缝结合的、高效的服务。 brpc brpc 是百度内部最常使用的工业级 RPC 框架,有 1000 000+ 个实例(不包含 client)和上千种服务,在百度内叫做“baidu-rpc”,目前只开源了 C++ 版本。 上边列出的主要是一些微服务架构的开发框架或者与微服务架构至关重要的RPC 框架,而其实微服务又涉及到分布式,这又会涉及到各种各样的中间件,数量太过于庞大,下回再议吧。 但是有一个方面是一定要在这里指出来的,那就是 Service Mesh。现在提到微服务架构,一般都会涉及到 Service Mesh 的相关内容,Service Mesh 被誉为“下一代微服务架构”,它源于对早期的服务代理模式 Sidecar 的扩展,其理念虽然由来已久,但是直到近两年随着微服务的火速兴起和 Buoyant 创建 Linkerd 并将其重新演绎,才逐渐以崭新的姿态呈现给世人。 Service Mesh 重点在 Mesh,它在 Sidecar 的基础上,强调了各个代理之间形成的有机网络。以通用组件的形式管控系统中所有服务通信流量,同时下沉了微服务开发的技术栈,可以做到语言无关、功能可扩展。 通过一个网格,Service Mesh 可以将服务治理的各个部分、微服务架构建设中的各个环节都不断延申,最终成为一套微服务开发完全解决方案。 这里也列出几个目前在 Service Mesh 领域稳坐主流地位的开源项目: Linkerd Linkerd是一个提供弹性云端原生应用 Service Mesh 的开源项目,也是面向微服务的开源 RPC 代理,它的核心是一个透明代理。 Envoy Envoy 是开源的边缘和服务代理,用于云原生应用,其最初是在 Lyft 构建的,它是为单一服务和应用程序设计的高性能 C++ 分布式代理,以及为大型微服务 Service Mesh 架构设计的通信总线和通用数据平面。 Istio Istio 项目能够为微服务架构提供流量管理机制,同时亦为其它增值功能(包括安全性、监控、路由、连接管理与策略等)创造了基础。这款软件利用久经考验的 Lyft Envoy 代理进行构建,可在无需对应用程序代码作出任何发动的前提下实现可视性与控制能力。 Conduit Conduit 是一个 Kubernetes 的超轻量级 Service Mesh,其目标是成为最快、最轻、最简单并且最安全的 Service Mesh。它使用Rust构建了快速、安全的数据平面,用 Go 开发了简单强大的控制平面,总体设计围绕着性能、安全性和可用性进行。它能透明地管理服务之间的通信,提供可测性、可靠性、安全性和弹性的支持。虽然与Linkerd 相仿,数据平面是在应用代码之外运行的轻量级代理,控制平面是一个高可用的控制器,然而与Linkerd 不同的是,Conduit 的设计更加倾向于 Kubernetes 中的低资源部署。 注:在发布 0.5 版本后,后续 Conduit 已经整合到了 Linkerd 2,详情查看: Conduit 0.5 成为终曲,后续并入 Linkerd 2.0 对 Service Mesh 的建设其实已经成为当前的业内共识,从下边这些项目都在往这个方向上演进就可以大致有所体会: WeiboMesh Motan 是新浪微博开源的是一套高性能、易于使用的分布式 RPC 框架,后来在 Motan Agent 的基础上演化出了 WeiboMesh。WeiboMesh 偏向服务治理方向,同时提供服务的动态管理能力,如服务降级、动态配置、权限管理、数据采集与服务指令处理等。 Dubbo Mesh Dubbo 在 v3 中发展 Service Mesh,官方希望 Dubbo Mesh 进入 Envoy 社区,目前 Dubbo 协议已经被 Envoy 支持,数据层选址、负载均衡和服务治理方面的工作还在继续,控制层目前在丰富 Istio/Pilot-discovery。 SOFAMOSN MOSN 是 SOFAStack 的组件,它一款采用 Go 语言开发的 Service Mesh 数据平面代理,功能和定位类似Envoy,旨在提供分布式,模块化,可观察,智能化的代理能力。MOSN 支持 Envoy 和Istio的 API ,可以和 Istio 集成。 nginMesh nginMesh 是 NGINX 开源的 Service Mesh 方案,它提供基于 NGINX 的 Service Mesh 实现。nginMesh 与 Istio 兼容,利用 NGINX 实现Sidecar 代理,集成在 Istio 中,可以标准、可靠和安全的方式促进服务之间的通信。 注:nginMesh 项目目前已经不再积极开发。 MicroProfile Service Mesh MicroProfile Service Mesh 是 MicroProfile 的Service Mesh 规范。MicroProfile 定义了用于开发云原生微服务的一系列规范,本质上它也是为 Istio 而生的微服务编程模型,而 Istio 本身就是 Service Mesh 的代名词。此规范关注 Service Mesh,并且更多地聚焦于Istio。 Ambassador Ambassador 是一个基于 Envoy 构建的Kubernetes 原生 API 网关,专为微服务而设计,它本质上是一个 Envoy 入口控制器,但具有更多功能,包括支持 gRPC、HTTP/2 与 WebSockets,支持 CORS、超时、加权轮询调度、粘性会话与速率限制等。 Gloo Gloo 是一个基于 Envoy 的 Kubernetes 原生入口控制器和下一代 API 网关。Gloo 在函数级路由方面表现卓越,它支持传统应用程序、微服务与 Serverless。Gloo 设计独特,可支持混合应用,其中的多种技术、架构、协议和云可以共存。 Kong Kong 在 1.0 GA 的时候带来了 Service Mesh 能力,用户不仅可以将 Kong 部署为 API 网关,还可以将其部署为独立的Service Mesh代理。Kong 插件能为 Service Mesh 提供开箱即用的关键功能,并能与其它云原生技术集成,包括 Prometheus、Zipkin、健康检查、canary 测试与蓝绿测试等。 Consul Connect Connect 是 Consul 中的 Service Mesh 方案,它可以自动将任何现有的 Consul 群集转换为 Service Mesh 解决方案。Connect 通过自动 TLS 加密和基于身份的认证实现安全的服务到服务通信。 借此机会特别感谢以 ServiceMesher 为代表的社区在国内普及与发展 Service Mesh 上的贡献。 当然,除了列出的这些框架值得期待,还可以在下边这几个分类中搜索、查看更多相关项目: 分布式:https://www.oschina.net/project/tag/191/distributed-and-grid 微服务:https://www.oschina.net/project/tag/461/microservice 容器/云原生:https://www.oschina.net/project/tag/406/paas RPC:https://www.oschina.net/project/tag/347/xmlrpc 中间件:https://www.oschina.net/project/tags 【感谢 ServiceMesher 社区 Jimmy Song 与罗广明对本文的审校】

优秀的个人博客,低调大师

笔记整理:数据处理方式Data Processing

1.批处理Batch Processing 定义:将任务成批地提交给系统,由系统自动完成后再输出结果。 举个例子,住在UIC新小镇的人去旧小镇上课,学校没造诺亚方舟,没办法哗啦一下送过去,只能用几辆大巴,将我们一批批送过去。 批处理模式中使用的数据集通常符合下列特征: 有界:批处理数据集代表数据的有限集合(新小镇宿位有限,人数肯定也是有限的) 持久:数据通常始终存储在某种类型的持久存储位置中(只要不来14级台风,宿舍楼都一直完好无损的在那里) 大容量:批处理操作通常是处理极为海量数据集的唯一方法(对于学校可借调交通工具的容量来看,新小镇学生人数算是大容量的) 批处理非常适合需要访问全套记录才能完成的计算工作,比如:在计算总数和平均数时,必须将数据集作为一个整体加以处理,而不能将其视作多条记录的集合。这些操作要求在计算进行过程中数据维持自己的状态(静态)。显然,批处理不适合对处理时间要求较高的场合(实时性任务)。 需要处理大量数据的任务通常最适合用批处理操作进行处理。无论直接从持久存储设备处理数据集,或首先将数据集载入内存,批处理系统在设计过程中就充分考虑了数据的量,可提供充足的处理资源。由于批处理在应对大量持久数据方面的表现极为出色,因此经常被用于对历史数据进行分析。 2.流处理Stream processing 定义:对随时进入系统的数据进行计算。流处理方式无需针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作。 吃栗子了:在首页上显示该网站的注册用户数 流处理中的数据集是无边界的,这就产生了几个重要的影响: 完整数据集只能代表截至目前已经进入到系统中的数据总量。(截至当前的的注册用户) 工作数据集也许更相关,在特定时间只能代表某个单一数据项。(某一时刻的注册人数) 处理工作是基于事件的,除非明确停止否则没有“尽头”(有人死去,有人出生) 处理结果立刻可用,并会随着新数据的抵达继续更新。 显然有近实时处理需求的任务很适合使用流处理模式。分析、服务器或应用程序错误日志,以及其他基于时间的衡量指标是最适合的类型,因为对这些领域的数据变化做出响应对于业务职能来说是极为关键的。流处理很适合用来处理必须对变动或峰值做出响应,并且关注一段时间内变化趋势的数据。 流处理系统可以处理几乎无限量的数据,但同一时间只能处理一条(真正的流处理)或很少量(微批处理,Micro-batch Processing)数据,不同记录间只维持最少量的状态。虽然大部分系统提供了用于维持某些状态的方法,但流处理主要针对副作用更少,更加功能性的处理(Functional processing)进行优化。 功能性操作主要侧重于状态或副作用有限的离散步骤。针对同一个数据执行同一个操作或忽略其他因素产生相同的结果,此类处理非常适合流处理,因为不同项的状态通常是某些困难、限制,以及某些情况下不需要的结果的结合体。因此虽然某些类型的状态管理通常是可行的,但这些框架通常在不具备状态管理机制时更简单也更高效。 大数据框架 大数据框架 支持批处理 支持流处理 Apache Hadoop √ Apache Storm √ Apache Samza √ Apache Spark √ √ Apache Flink √ √ Lambda 架构 实时大数据处理框架Storm作者Nathan Marz认为,数据系统的本质是“查询+数据”,用公式表达: Query = Function(All Data) 那么问题来了,如何实时地在任意大数据集上进行查询?如果单纯地对全体数据集进行在线查询,那么计算代价会很大,延迟也会很高,比如Hadoop。 为了解决这个问题,他提出了一个实时大数据处理Lambda架构。 Lambada有两个假设: 不可变假设:Lambda架构要求data不可变,这个假设在大数据系统是普遍成立的:因为日志是不可变的,某个时刻某个用户的行为,一旦记录下来就不可变。 Monoid假设: 理想情况下满足Monoid 的function可以转换为:Query = Function(All Data/ 2) + Function(All Data/ 2) Monoid的概念来源于范畴学(Category Theory)【是的没错,又多学了一个装逼的词】它有一个特别简单的重要特性:满足结合律。如整数的加法就满足Monoid特性:(a+b)+c=a+(b+c) 不满足Monoid特性的函数很多时候可以转化成多个满足Monoid特性的函数的运算。求多个数的平均值avg函数,多个平均值没法直接通过结合来得到最终的平均值,但是可以拆成分母除以分子,分母和分子都是整数的加法,从而满足Monoid特性。 Monoid的结合律特性在分布式计算中极其重要,满足Monoid特性意味着我们可以将计算分解到多台机器并行运算,然后再结合各自的部分运算结果得到最终结果。同时也意味着部分运算结果可以储存下来被别的运算共享利用(如果该运算也包含相同的部分子运算),从而减少重复运算的工作量。 lambda.png Lambda的做法是将大数据系统架构拆分成了三层:Batch Layer,Speed Layer和Serving Layer。 I. Batch Layer 既然对全体数据集进行在线查询,计算代价会很高,那么如果对查询事先进行预计算,生成对应的Views,并且对Views建立索引,这样,查询的速度会提高很多,这就是Batch Layer所做的事。 Batch Layer层采用不可变模型对所有数据进行了存储,并且根据不同的业务需求(这里体现了Batch的概念),对数据进行了不同的预查询,生成对应的Batch Views,这些Batch Views提供给上层的Serving Layer进行进一步的查询。另外,每隔一段时间都会进行一次预查询,对Batch Views进行更新,Batch Views更新完成后,会立即更新到Serving Layer中去。 II. Speed Layer 如上一节中提到,预查询的过程是一个批处理的过程,该过程花费的时间会比较长,在该过程中,Serving Layer使用的仍然是旧版本的Batch Views,那么仅仅依靠Batch Layer这一层,新进入系统的数据将无法参与最后结果的计算,因此,Marz为Lambda设计了Speed Layer层来处理增量的实时数据。 Speed Layer和Batch Layer比较类似,对数据计算生成Realtime Views,其主要的区别是: Speed Layer处理的数据是最近的增量数据流,Batch Layer处理的是全体数据集。 Speed Layer为了效率,接收到新数据时,就更新Realtime Views,并且采用的是Incremental Updates(增量计算模型),而Batch Layer则是根据全体离线数据集得到Batch Views,采用的是Recomputation Updates(重新计算模型)。 III. Serving Layer Serving Layer用于响应用户的查询请求,它将Batch Views和Realtime Views的结果进行了合并,得到最后的结果,返回给用户。 前面我们讨论了查询函数的Monoid性质,如果查询函数满足Monoid性质,即满足结合率,只需要简单的合并Batch View和Realtime View中的结果数据集即可。否则的话,可以把查询函数转换成多个满足Monoid性质的查询函数的运算,单独对每个满足Monoid性质的查询函数进行Batch View和Realtime View中的结果数据集合并,然后再计算得到最终的结果数据集。另外也可以根据业务自身的特性,运用业务自身的规则来对Batch View和Realtime View中的结果数据集合并。 Lambda架构组件选型 下图给出了Lambda架构中各个层常用的组件。 数据流存储:可选用基于不可变日志的分布式消息系统Kafka; Batch Layer数据集的存储:可选用Hadoop的HDFS,或者是阿里云的ODPS; Batch View的预计算:可以选用MapReduce或Spark; Batch View自身结果数据的存储:可使用MySQL(查询少量的最近结果数据),或HBase(查询大量的历史结果数据) Speed Layer增量数据的处理:可选用Storm或Spark Streaming; Realtime View增量结果数据集:为了满足实时更新的效率,可选用Redis等内存NoSQL。 举个例子 本案例为某省的智慧交通系统。 系统各层组件的选型 根据上面的介绍,Lambda架构包括三层,其中Batch Layer负责数据集的存储和批处理的执行,数据存储我们选择Hyperbase。Hyperbase支持快速高并发的查询,可以方便用户做一些精确类查询(如根据车牌号检索等)。由于此项目还有一些统计类的业务需求,我们选择将部分数据在HDFS上保留一份用作后期的分析之用,Inceptor的强大的数据分析能力可以帮助用户在任意维度上做复杂的数据分析工作。 Speed Layer主要负责对数据的实时处理,可以使用Transwarp Stream。此外,Kafka选择使用Transwarp Kafka 0.9版本,由于增加了Kafka队列内的kerberos安全认证功能,消息队列中的数据更安全。 HDFS和Hyperbase的数据通过SQL以及JDBC接口开放给用户,企业可以开发Serving Layer中自身需要的业务。由于这些应用程序是具体的企业内部业务,此处不做讨论。 系统各层机器规划 有了上面的组件选型,下面我们可以进行机器规划。主要考虑的是以下几个方面: 存储能力 就某地市而言,每天约有1000w的过车记录产生,高峰时期每秒能约有1w条过车记录产生,每条过车记录对应的结构化数据约有30个字段,大小为200Byte;每天还有50w张左右大小约为500KB的图片数据,按照规划数据需要存储的周期为2年,因此对集群容量要求如下: 结构化数据存储三份、图片数据存储两份,2年的数据总量约为: (1000w * 200B 3 + 50 w * 500KB * 2) * 365 * 2 = 344TB 每台机器有8个硬盘,每个硬盘容量为3TB,则需要数据节点数为: 344TB / (3TB8) = 15台 另外,Hadoop分布式存储集群需要2台管理节点。 实时计算的需求 目前需要进行实时处理的业务包括: a. 实时检测业务:逾期未年检、黑名单、逾期未报废、凌晨2点到5点上路行驶的客运车辆、车主驾驶证无效车辆等。 b. 实时分析业务:包括流量统计、旅行时间分析、套牌车检测、区间测速等。 其中实时检测业务以及套牌车检测等要求在秒级别反馈结果以对违法行为进行实时拦截;分析业务要求在分钟级别更新结果。 按照每秒1w条过车记录计算,总共有20+个流处理业务(比对和复杂分析)同时运行,预估需要实时处理集群机器6台。 另外,所有的过车记录都会预先被接入Kafka分布式消息处理集群,每条记录写入3份,保存7天,预估需要Kafka集群机器4台。 批处理分析要求 除了实时处理业务之外,还需要对历史数据进行统计分析,对于时间跨度在一个月内的统计分析需要在秒级返回结果;对于时间跨度在三个月以上的复杂统计分析需要在分钟级别返回结果。 依据上述的要求分析,给出机器数目和配置参考图如下: 某智能交通系统的配置情况 系统架构 智能交通的整体架构图 前端卡口会实时采集过往车辆信息,采集到的车辆信息首先被接入Kafka分布式消息总线。Kafka分布式消息总线,会对这些数据进行归类分拣,分发给不同的服务集群,比如实时入库服务集群、未年检车监控服务集群等。 假设有部分数据被送入到了未年检车监控服务集群中,该集群需要将待检查车辆与车辆数据库进行数据比对。为了减少数据比对时间,该系统预先根据历史数据生成了未年检车辆数据库,由Batch Layer层的批处理引擎完成。待检查车辆只需与未年检车辆数据库进行在线比对即可,如果发现违章车辆,则进行标记显示,并进行预警。 系统支持链接文字的业务 a. 实时监控预警业务 实时监控预警业务主要由Speed Layer层的Transwarp Stream负责,按照技术可以分为以下三类: 1) ETL功能 将实时采集的过车数据,按照一定的清洗转化规则进行处理,转化成规范的记录后写入后端存储Hyperbase和 Holodesk。其中Hyperbase为持久化的列式存储,保存所有的历史过车数据;Holodesk为临时存储,提供高速的分析能力,可以保存一周以内的短期数据。 2) 实时检测业务 最简单的检测规则可以直接根据过车记录判断,例如凌晨2点到5点行驶的车辆;其次是和一些基础表进行比对的业务,例如黑名单车辆/未年检车辆检测,需要事先进行预查询,生成并保存相应的黑名单车辆表/未年检车辆表。 3) 实时分析业务 实时统计业务如流量统计,通常基于窗口技术实现。例如需要统计分钟流量、小时流量,可以设定一个长度为1分钟的滚动窗口,统计每分钟的流量,并基于分钟流量对小时流量进行更新。 b. 数据统计分析业务 1) 基于全量历史数据的统计分析 通过Inceptor组件能够对存储在Hyperbase中的数据使用SQL语句进行统计分析,比如统计一天的车流量,一个月的碰撞次数等。Hyperbase的Rowkey具有去重的功能,可以帮助用户得到精准的统计结果。 2) 基于临时数据的交互式分析 除了一些固定的统计报表之外,还需要处理一些突发的临时性统计业务。例如伴随车分析,就是统计出一段时间内和某个车一同行驶的车辆,这在犯罪分析中有很大的作用。TDH中的Holodesk组件能够很好处理这部分业务需求,创建Holodesk上的一张有窗口限制的表(例如窗口长度为1周,超过1周的数据将被删除),通过Transwarp Stream将数据实时写入Holodesk,前端通过Inceptor的SQL实现交互式分析。 参考链接 技术|深入浅出解析大数据Lambda架构 用于实时大数据处理的Lambda架构

优秀的个人博客,低调大师

JavaEE PO VO BO DTO POJO DAO 整理总结

佩服能将复杂难懂的技术,抽象成简单易懂事物的人。 厌恶将简单易懂的技术,添加一堆专业术语将别人弄的头晕目眩的人。 PO VO BO DTO POJO DAO 总体一览: 回到顶部 1.DAO[data access object]数据访问对象 DAO层对开发人员黑盒,由架构师设计封装。 在很长一段时间内,我将它理解为对数据库的访问,后面随着项目的积累。 发现自己的理解相对狭隘,对数据访问不仅仅指的是对数据库的访问。 假如A系统调用B系统的服务获取数据,这时候A系统对B系统访问数据对象的封装也可以称为DAO。 回到顶部 2.DTO[data transfer object]数据传输对象 假设数据表中存在20个字段,但是在页面展示列表的时候,这20个字段显然都不会用到。 我想对其中的5个字段进行展示,而且这5个字段展示的时候,也并不是数据库中他们原有的样子。 还需要进行计算、截取、业务代码转名称 .....等等 数据传输对象因此而被诞生,一是能提高数据传输的速度,二能隐藏后端表结构。 回到顶部 3.PO[persistant object]持久层对象 持久对象属性和数据库中的字段是一一对应的,数据库中的一条数据可以理解为一个持久对象。 因ORM框架的广泛使用而被引入到 JavaEE 项目设计当中。 回到顶部 4.BO[bussiness object]业务对象 业务对象顾名思义是在业务处理中抽象出来的对象,里面除了get/set 方法外,也可以有对字段进行业务处理的方法。 假设你要对一个班级进行业务处理,其中的学生、教师、甚至是桌椅板凳都是业务对象的组成部分。 当然其中的学生、教室....都可以是和数据库对应的PO。 回到顶部 5.VO[value object]值对象 值对象也可以称做页面对象,如果称做页面对象,那门它所代表的将是整个页面展示层的对象。 可以由需要的业务对象进行的换算转换而来。 如果称呼他为值对象的话,那门他可以理解为存放业务对象的一个地方。 假设锅碗瓢盆分别为对应的业务对象的话,那门整个碗柜就是一个值对象。 回到顶部 4.POJO[plain ordiary java object] 简单java对象 简单java对象应该是JavaEE世界里面最灵活的对象。 在简单系统中,如果从数据库到页面展示都是POJO的话,它可以是DTO。 如果从数据库中到业务处理中都是POJO的话,他也可以是BO。 同样如果从数据库到整个页面的展示的话,它同样可以是VO。 小结: 各个数据对象之间的转换是相当灵活的,在项目中可以定义上述对象的全部和其中的几种类型,这取决与架构师和需求。 在大型项目中,架构师在项目初期的任务除了搭建起整个开发环境以外,定义在系统中流转的数据结构对象同样是重重之重。 这项工作需要许多项目的积累和长期对软件开发的思考,多实践,多思考,提供最合适的数据对象解决方法,方能展现架构师的魅力。 本文转自Orson博客园博客,原文链接:http://www.cnblogs.com/java-class/p/5439646.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

windows 7 Ultimate beta 试用问题整理进行时

试用windows 7 Ultimate beta到现在已经3天了 镜像文件名称: en_windows_7_beta_language_pack_dvd_x86_x15-29103.iso 以上是系统的可操作性展示,对窗口的处理,图标的处理,以及动态效果更加细致了。 windows 7对输入输出下了很大的功夫,比如输入的语音识别技术。早期在微软的其他产品中也应用了这项技术,但是此次我对语音识别的体验中感受到了,微软下的大功夫。 同时也找到了一些不足: 1、语音识别教程中的部分汉化不是很人性,另外在命令篇的显示编号这个操作项的第二步有个明显错误(已经提交),如下图: 2、在vpc2007中安装完毕windows 7后 再安装vpc自带的产品组件“virtual machine additions”后,系统启动时会蓝屏。 其他的功能正在测试。请见后续更新。。。 本文转自 angerfire 51CTO博客,原文链接:http://blog.51cto.com/angerfire/132939,如需转载请自行联系原作者

优秀的个人博客,低调大师

DELL EqualLogic PS数据恢复过程整理及小结

DELL EqualLogic PS4000采用虚拟ISCSI SAN阵列,为远程或分支办公室、部门和中小企业存储部署带来企业级功能、智能化、自动化和可靠性。以简化的管理、快速的部署及合理的价格满足了分支办公室和中小企业的存储需求,同时提供全套企业级数据保护和管理功能、可靠的性能、可扩展性和容错功能,是中型企业级存储的起点产品,但某些物理故障或其他操作都可能会对卷或存储造成破坏,因此对系列存储的数据恢复技术才有了用武之地。而发生这些故障之后只能找专业的数据恢复公司做数据挽救工作。北亚数据恢复中心宋工最近处理过一起DELL EqualLogic PS4000因磁盘故障导致存储不可用的案例: 故障描述: 一台DELL EqualLogic PS4000E的存储,其底层是16块600GB的SAS硬盘组成的RAID。是一组RAID5,这组崩溃RAID5划分的VMFS文件系统,其中存放的是虚拟机文件,在存储系统的上层一共分了4个卷,其中3个卷大小为1.5TB,1个卷大小为1TB。后因磁盘故障而导致存储不可用,且已经过保,客户便联系到北亚数据恢复中心请求恢复数据。 硬件检测: 宋工先对客户的16块硬盘做了硬件检测,发现客户的2块硬盘出现坏道、SMART的错误冗余级别已经超过阀值,把14块正常的硬盘进行全盘镜像,另2块有坏道的硬盘用专业工具进行了恢复并生成镜像文件。 图一 故障分析: 首先收集DEll equallogic ps4000存储日志信息。从存储上硬盘的指示灯看到有两块盘亮黄灯,对收集到的日志信息进行分析,分析两块硬盘的掉线时间,从而得知哪块硬盘里面的数据是最新,用最新数据的硬盘进行数据恢复。 解决方案: 北亚会对存储的所有硬盘都进行相应的备份。对镜像文件进行分析,保证用户的原介质的安全。首先对16块盘进行虚拟还原之前的RAID状态,通过位图信息在虚拟出来的RAID中把4个lun全部提取出来。根据底层结构分析,把4个VMFS的文件系统进行跨区卷组合,导出用户数据,并验证虚拟机是否正常。 图二 图三 数据恢复成功: 我们将卷里的文件都拷贝出来,通过网络共享的方式验证恢复出来的虚拟机,虚拟机都可以正常启动,之后把虚拟机文件移交给客户。经过漫长的底层分析,加上不断的测试。终于在用户需求的时间内将数据完整恢复,整个恢复过程一共历时3天。我们之前研究过DEll Equallogic的存储原理。知道了DEll Equallogic的存储原理以后,关于它的所有数据灾难都可以进行恢复。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。