函数式编程
写在前面
从Java 8开始,Java语言添加了lambda表达式以及函数式接口等新特性。这意味着Java语言也开始逐步提供函数式编程的能力。
事实上,如果你熟悉Erlang、Scala、JavaScript或Python,那你或多或少对函数式编程相对熟悉。但如果你是一个通过常规路径学习的Javaer,可能对函数式编程思想不甚了解,相对的,你可能对面向对象编程思想会更熟悉。
先熟悉一下几个术语,有利于提升大家的逼格:
FP,Functional Programming,函数式编程;
OOP,Object Oriented Programming,面向对象编程;
虽然FP是在最近10年才流行起来的,但它的历史和OOP几乎等长。为什么FP突然流行起来了呢?
最主要原因是摩尔定律正在逐渐失效,单核CPU的计算能力在短期内无法有大的突破,计算机领域正在向“多核CPU和分布式计算”的方向发展。而FP则天然具备适合并发编程的优点:它不修改变量,不存在多线程间的竞争问题,因此也不需要考虑“锁”和“线程阻塞”,易于并发编程。在未来的大数据时代,函数式编程思想将会越来越重要。
其次,在现实的编码过程中 ...
函数式接口Functional Interface
写在前面
前面说过,判断一门语言是否支持函数式编程,一个重要的判断标准就是:它是否将函数看做是“第一等公民(first-class citizens)”。
函数是“第一等公民”,意味着函数和其它数据类型具备同等的地位——可以赋值给某个变量,可以作为另一个函数的参数,也可以作为另一个函数的返回值。
Java 8是通过函数式接口,赋予了函数“第一等公民”的特性。
本文将详细介绍Java 8中的函数式接口。
本文的示例代码可从gitee上获取:https://gitee.com/cnmemset/javafp
函数式接口
什么是函数式接口(function interface)?只有一个抽象方法的接口都属于函数式接口。
按照规范,我们强烈建议在定义函数式接口时,加上注解 @FunctionalInterface,这样在编译阶段就可以判断该接口是否符合函数式接口的规范。当然,也可以不加注解 @FunctionalInterface,这并不影响函数式接口的定义和使用。
以下是一个典型的函数式接口 Consumer:
123456789101112// 强烈建议加上注解 @Functional ...
计算机基础实验2:算术运算
整数加减法运算的电路:
相关知识:
补码运算:
减法器:当sub等于1,做减法。Y按位取反后送到加法段,同时加上Cin达到末尾加1的效果,这个步骤其实是求Y的补码。
补码加法运算中,不区分符号位和数值位。加法器执行的就是0,1序列的运算,没有符号区分。
实验程序:
实验过程:
1.编译程序和反汇编:
2.查看反汇编文件:
3.在IA-32中带符号整数的加法和无符号底层采用的机器级的指令是一样的。实现带符号整数的加减运行和去符号整数的加减运算电路只有一个。
MIPS指令系统中无符号加减运算指令不置溢出状态,也即输出的of都是0;
不同的指令体系都只有一个加减运算电路,只不过不同的指令体系的标志位的处理不一样。
4.调试该程序:
5.总结:当sub为0时做减法,当sub为1时做加法,带符号整数的加减法运算采用补码形式让加减运算可以用同一个电路实现,不管无符号还是有符号其加减运算的机械数是一样的。
整数加减运算的状态标志信息:
相关知识:OF:溢出标志,带符号整数是否超出范围;对于加法器来说只有同号相加有溢出;ZF:零标志位;SF:符号标志位,其结果为Sum的最高有效位;C ...
Web前端安全系列之:XSS攻防及Vue防御
前言 Web 安全的兴起
Web 攻击技术的发展也可以分为几个阶段。在 Web 1.0 时代,人们更多的是关注服务器端动态脚本的安全问题,比如将一个可执行脚本(俗称 webshell)上传到服务器上,从而获得权限。后续有出现了SQL注入,SQL注入的出现是Web安全史上的一个里程碑,SQL注入漏洞至今仍然是Web安全领域中的一个重要组成部分。再后续另一个里程碑的安全问题问世–XSS(跨站脚本攻击)。伴随着 Web 2.0 的兴起,XSS、CSRF 等攻击已经变得更为强大。Web 攻击的思路也从服务器端转向了客户端,转向了浏览器和用户。Web 技术发展到今天,构建出了丰富多彩的互联网。互联网业务的蓬勃发展,也催生出了许多新兴的脚本语言,比如 Python、Ruby、NodeJS 等,敏捷开发成为互联网的主旋律。而手机技术、移动互联网的兴起,也给 HTML 5 带来了新的机遇和挑战。与此同时,Web 安全技术,也将紧跟着互联网发展的脚步,不断地演化出新的变化。跨站脚本攻击(XSS)是客户端脚本安全中的头号大敌。OWASP TOP 10 威胁多次把 XSS列在榜首,该篇文章将重点介绍XSS ...
XSS系列一:什么是XSS攻击
1.关于XSS攻击
XSS全称Cross Site Scripting(跨站脚本),为了与“CSS”区别,就使用XSS作为简称。XSS攻击指恶意用户在html中注入含恶意的JavaScript代码或者恶意的HTML代码。在其他用户浏览该页面时,浏览器会直接编译处理所有代码包括恶意代码,从而作出损害用户利益的攻击。下面通过一个简单的前后端数据交互例子进行叙述,先贴上代码
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401 ...
八大排序算法稳定性分析
稳定性定义:排序前后两个相等的数相对位置不变,则算法稳定。稳定性得好处:从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用各排序算法的稳定性:1、堆排序、快速排序、希尔排序、直接选择排序不是稳定的排序算法;2、基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法。一冒泡排序1、小的元素往前调或者把大的元素往后调;2、比较是相邻的两个元素比较,交换也发生在这两个元素之间;3、稳定排序算法。二选择排序1、每个位置选择当前元素最小的;2、在一趟选择中,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了;3、举个例子,序列5 8 5 2 9, 我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了;4、不稳定的排序算法。三插入排序1、已经有序的小序列的基础上,一次插入一个元素;2、想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置;3、如果碰见一个和插入元素相 等的,那么插入元素把想插入的元素放在相等元素的 ...
如何设计一个高并发系统?
前言
1 页面静态化
对于高并发系统的页面功能,我们必须要做静态化设计。如果并发访问系统的用户非常多,每次用户访问页面的时候,都通过服务器动态渲染,会导致服务端承受过大的压力,而导致页面无法正常加载的情况发生。我们可以使用Freemarker或Velocity模板引擎,实现页面静态化功能。以商城官网首页为例,我们可以在Job中,每隔一段时间,查询出所有需要在首页展示的数据,汇总到一起,使用模板引擎生成到html文件当中。然后将该html文件,通过shell脚本,自动同步到前端页面相关的服务器上。
2 CDN加速
虽说页面静态化可以提升网站网页的访问速度,但还不够,因为用户分布在全国各地,有些人在北京,有些人在成都,有些人在深圳,地域相差很远,他们访问网站的网速各不相同。如何才能让用户最快访问到活动页面呢?这就需要使用CDN,它的全称是Content Delivery Network,即内容分发网络。使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN加速的基本原理是:将网站的静态内容(如图片、CSS、JavaScript文件等)复制并存储到分布在全球各地的 ...
第 1 章 研发自测基础 - 《Java 研发自测》
软件测试是一个非常专业的领域,甚至有一些大学也设置了软件测试课程。虽然大多数软件公司都会设置软件测试类的岗位,但是对于一个优秀的研发人员来说,保证软件质量也应该是份内的事情。研发人员如果从研发的角度关注测试,那么只需要一丁点投入,就可以换取巨大的价值。因为研发人员熟悉技术方案、编码的细节,甚至所有的分支流程,且了解基本的测试概念,在本地开发过程中就能发现大量的问题,这样就避免了反复移交测试等流程,极大地提高了效率。另外,编写出高质量的代码,可以给研发人员带来满足感和信心,避免了反复调试。而且交付高质量的程序后,研发人员也可以更好地集中精力进行下一段程序的开发,避免了因为被打断而造成的上下文切换带来的精力消耗。本章会介绍软件测试的一些基本概念和知识,由于本书是面向研发人员的,因此在内容组织上会主要关注在白盒测试上。本章涵盖的内容以及学习目标如下:
了解软件测试的基本概念。
理解常见的测试分类。
掌握测试用例设计的一般方法。
了解哪些类型的测试适合研发人员自测完成。
一些准备测试数据的技巧。
1.1 软件测试的基本概念
软件测试是一项专业的工作,里面涉及一些专业术语和概念,了解它们可 ...
第 2 章 代码评审 - 《Java 研发自测》
在软件开发过程中,除了可以从功能角度发现问题以外,还可以通过代码检视发现一些显而易见的问题,做好这部分工作带来的收益甚至比测试人员手动测试还高。在实践中,对代码进行评审可以从如下三个层面把控:
静态代码分析。
每日代码评审。
代码合入请求。
**静态代码分析 ** 是指在代码提交时使用工具自动扫描,或者在流水线中让构建服务器代为扫描。一般来说,大的公司会有专门的部门采购各种代码分析工具,我们可以从代码风格、潜在的缺陷、合规和安全等方面系统地检查代码中存在的问题。扫描不合格的代码不予发布,避免为产品带来潜在的风险。**每日代码评审 ** 是指团队每日一起评审当日或上一日的代码,一般在下午下班前进行,时间需要控制在 30~60 分钟。每日代码评审除了可以用于提高代码质量以外,也可以用于团队的技术交流和问题沟通,毕竟大家工作在同一个代码仓库里。代码评审一般由人工完成,可使用 Git、GitLab、IntelliJ IDEA 等工具。代码评审作为静态代码分析的补充方法,一般不会涉及已经被静态代码分析所覆盖的内容。**代码合入请求 ** 是指在必要时通过合入请求来合入代码。具体合入方式取决于 ...
第 4 章 测试替身 - 《Java 研发自测》
测试替身是单元测试中非常有用的一个概念,用来隔离组件之间的依赖关系,让不可测试的组件变得可以测试。
曾听很多朋友说,测试替身这个概念非常难理解,它有种浓浓的翻译味。我一直在尝试找一个合适的类比来说明这些概念,直到有一次我家的灯泡坏了,我带着这个灯泡到一家五金店购买新的灯泡。老板在柜子里翻出一个差不多的灯泡,然后插到门后预留的一个灯座上,灯泡亮了起来。我忽然灵光一闪,这不就是测试替身一个绝妙的类比么?代替真实灯座(基础设施)进行验证(单元测试)的装置就是测试替身。
合理运用测试替身可以在运行测试时去除对运行环境的依赖。这也给了我们一个启示,那就是尽可能地使用清晰的边界来设计代码,让编写单元测试更加容易。
编写单元测试有时候不是那么容易。对于前面提到的类比,假如灯泡是通过电线直接连接到供电系统的而不是灯座,那么测试就会变得非常困难。
本章的目标是解决单元测试在实际编写的过程中遇到的各种困难,通过测试替身让单元测试可以顺利进行。在 Java 技术栈中,我们可以使用 Mockito、PowerMock 这两种测试替身工具。
本章涵盖的内容有:
使用 Mockito 实现 public 方法的 ...