
Java 8 发布三年多之后,即将快到2017年7月下一个版本发布的日期了。 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其它的更新。 这里有九个令人兴奋的新功能将与 Java 9 一起发布。 Java 平台级模块系统 Java 9 的定义功能是一套全新的模块系统。当代码库越来越大,创建复杂,盘根错节的“意大利面条式代码”的几率呈指数级的增长。这时候就得面对两个基础的问题: 很难真正地对代码进行封装, 而系统并没有对不同部分(也就是 JAR 文件)之间的依赖关系有个明确的概念。每一个公共类都可以被类路径之下任何其它的公共类所访问到, 这样就会导致无意中使用了并不想被公开访问的 API。此外,类路径本身也存在问题: 你怎么知晓所有需要的 JAR 都已经有了, 或者是不是会有重复的项呢? 模块系统把这俩个问题都给解决了。 模块化的 JAR 文件都包含一个额外的模块描述器。在这个模块描述器中, 对其它模块的依赖是通过 “ requires” 来表示的。另外, “ exports” 语句控制着哪些包是可以被其它模块访问到的。所有不被导出的包默认都封装在模块的里面。如下是一个模块描述器的示例,存在于 “module-info.java” 文件中: module blog {我们可以如下展示模块: 32130002475b31336ae7 请注意,两个模块都包含封装的包,因为它们没有被导出(使用橙色盾牌可视化)。 没有人会偶然地使用来自这些包中的类。Java 平台本身也使用自己的模块系统进行了模块化。通过封装 JDK 的内部类,平台更安全,持续改进也更容易。 当启动一个模块化应用时, JVM 会验证是否所有的模块都能使用,这基于 requires 语句——比脆弱的类路径迈进了一大步。模块允许你更好地强制结构化封装你的应用并明确依赖。你可以在这个 课程 中学习更多关于 Java 9 中模块工作的信息 。 如果你想学习Java可以来这个群,首先是二二零,中间是一四二,最后是九零六,里面可以学习和交流,也有资料可以下载。 Linking 当你使用具有显式依赖关系的模块和模块化的 JDK 时,新的可能性出现了。你的应用程序模块现在将声明其对其他应用程序模块的依赖以及对其所使用的 JDK 模块的依赖。为什么不使用这些信息创建一个最小的运行时环境,其中只包含运行应用程序所需的那些模块呢? 这可以通过 Java 9 中的新的 jlink 工具实现。你可以创建针对应用程序进行优化的最小运行时映像而不需要使用完全加载 JDK 安装版本。 JShell: 交互式 Java REPL 许多语言已经具有交互式编程环境,Java 现在加入了这个俱乐部。您可以从控制台启动 jshell ,并直接启动输入和执行 Java 代码。 jshell 的即时反馈使它成为探索 API 和尝试语言特性的好工具。 322d0003e3f6c42e3137 测试一个 Java 正则表达式是一个很好的说明 jshell 如何使您的生活更轻松的例子。 交互式 shell 还可以提供良好的教学环境以及提高生产力,您可以 在此 了解更多信息。在教人们如何编写 Java 的过程中,不再需要解释 “public static void main(String [] args)” 这句废话。 改进的 Javadoc 有时一些小事情可以带来很大的不同。你是否就像我一样在一直使用 Google 来查找正确的 Javadoc 页面呢? 这不再需要了。Javadoc 现在支持在 API 文档中的进行搜索。另外,Javadoc 的输出现在符合兼容 HTML5 标准。此外,你会注意到,每个 Javadoc 页面都包含有关 JDK 模块类或接口来源的信息。 321000048ba2cfe25db6 集合工厂方法 通常,您希望在代码中创建一个集合(例如,List 或 Set ),并直接用一些元素填充它。 实例化集合,几个 “add” 调用,使得代码重复。 Java 9,添加了几种集合工厂方法: Set ints = Set.of(1, 2, 3);除了更短和更好阅读之外,这些方法也可以避免您选择特定的集合实现。 事实上,从工厂方法返回已放入数个元素的集合实现是高度优化的。这是可能的,因为它们是不可变的:在创建后,继续添加元素到这些集合会导致 “UnsupportedOperationException” 。 改进的 Stream API 长期以来,Stream API 都是 Java 标准库最好的改进之一。通过这套 API 可以在集合上建立用于转换的申明管道。在 Java 9 中它会变得更好。Stream 接口中添加了 4 个新的方法: dropWhile, takeWhile, ofNullable 。还有个 iterate 方法的新重载方法,可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代: IntStream.iterate(1, i -> i < 100, i -> i + 1).forEach(System.out::println);第二个参数是一个 Lambda,它会在当前 IntStream 中的元素到达 100 的时候返回 true。因此这个简单的示例是向控制台打印 1 到 99。 除了对 Stream 本身的扩展,Optional 和 Stream 之间的结合也得到了改进。现在可以通过 Optional 的新方法 stram 将一个 Optional 对象转换为一个(可能是空的) Stream 对象: Stream s = Optional.of(1).stream();在组合复杂的 Stream 管道时,将 Optional 转换为 Stream 非常有用。 私有接口方法 Java 8 为我们带来了接口的默认方法。 接口现在也可以包含行为,而不仅仅是方法签名。 但是,如果在接口上有几个默认方法,代码几乎相同,会发生什么情况? 通常,您将重构这些方法,调用一个可复用的私有方法。 但默认方法不能是私有的。 将复用代码创建为一个默认方法不是一个解决方案,因为该辅助方法会成为公共API的一部分。 使用 Java 9,您可以向接口添加私有辅助方法来解决此问题: public interface MyInterface { void normalInterfaceMethod(); default void interfaceMethodWithDefault() { init(); } default void anotherDefaultMethod() { init(); } // This method is not part of the public API exposed by MyInterface如果您使用默认方法开发 API ,那么私有接口方法可能有助于构建其实现。 HTTP/2 Java 9 中有新的方式来处理 HTTP 调用。这个迟到的特性用于代替老旧的 HttpURLConnection API,并提供对 WebSocket 和 HTTP/2 的支持。注意:新的 HttpClient API 在 Java 9 中以所谓的孵化器模块 交付。也就是说,这套 API 不能保证 100% 完成。不过你可以在 Java 9 中开始使用这套 API: HttpClient client = HttpClient.newHttpClient();除了这个简单的请求/响应模型之外,HttpClient 还提供了新的 API 来处理 HTTP/2 的特性,比如流和服务端推送。
一. 什么是Code Splitting? 在最开始使用Webpack的时候, 都是将所有的js文件全部打包到一个build.js文件中(文件名取决与在webpack.config.js文件中output.filename), 但是在大型项目中, build.js可能过大, 导致页面加载时间过长. 这个时候就需要code splitting, code splitting就是将文件分割成块(chunk), 我们可以定义一些分割点(split point), 根据这些分割点对文件进行分块, 并实现按需加载. 二. Code Splitting的作用? 第三方类库单独打包: 由于第三方类库的内容基本不会改变, 可以将其与业务代码分离出来, 这样就可以最大化的利用浏览器的缓存机制, 减少请求. 按需加载: Webpack支持定义分割点, 通过require.ensure进行按需加载. 三. 如何进行Code Splitting? 下面的代码是基于vue-cli的webpack-simple模板生成的演示文档 //cmd vue init webpack-simple code_spliting_demo 复制代码 (一) 第三方类库单独打包 我们假设项目中引入了jquery.js和respond.js, 那么我们可以在webpack.config.js中配置多入口来进行将这两个第三方类库单独打包. 在webpack.config.js进行配置 //webpack.config.js //在entry中添加相应第三方类库 entry: { bundle: './src/main.js', vendor: ['./src/lib/jquery-1.10.2.min.js', './src/lib/respond.min.js'] } //在plugins中添加CommonChunkPlugin plugins:[ new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.bundle.js' }) ] 复制代码 执行npm run build, 此时dist目录下生成了两个文件, 分别是build.js和vendor.bundle.js npm run build后的生成文件 在index.html中引入, 注意: vendor.bundle.js优先于build.js引入 //index.html <script src="/dist/vendor.bundle.js"></script> <script src="/dist/build.js"></script> 复制代码 (二) 按需加载 我们可以在router中进行配置, 实现组件的按需加载, 在一些单个组件文件较大的时候, 采用按需加载能够减少build.js的体积, 优化加载速度(如果组件的体积较小, 那么采用按需加载会增加额外的http请求, 反倒增加了加载时间) 这里, 我们增加3个组件,分别是A.vue, B.vue, C.vue //A.vue <template> <h1>这里是A.vue组件</h1> </template> //B.vue <template> <h1>这里是B.vue组件</h1> </template> //C.vue <template> <h1>这里是C.vue组件</h1> </template> 复制代码 在路由中进行配置 (注意:这里是为了方便, 是在app.js中添加的路由, 在实际的项目中, 路由应该单独抽取出来) //app.js import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' Vue.use(VueRouter) //AMD规范的异步载入 const ComA = resolve => require(['./components/A.vue' ], resolve); const ComB = resolve => require(['./components/B.vue' ], resolve); const ComC = resolve => require(['./components/C.vue' ], resolve); const router = new VueRouter({ routes: [ { name: 'component-A', path: '/a', component: ComA }, { name: 'component-B', path: '/b', component: ComB }, { name: 'component-C', path: '/c', component: ComC } ] }) new Vue({ el: '#app', router: router, render: h => h(App) }) 复制代码 在webpack.config.js中进行配置output.chunkFilename, //webpack.config.js output: { path: path.resolve(__dirname, './dist'), publicPath: '/dist/', filename: 'build.js', //添加chundkFilename chunkFilename: '[name].[chunkhash:5].chunk.js' } 复制代码 执行npm run build, 此时dist目录下生成了5个文件, 多出的3个文件,就是对应的A.vue, B.vue, C.vue这三个组件 npm run build后生成的文件 CMD规范的异步载入 刚才在路由引入的时候, 使用的是AMD规范的异步载入. webpack提供了require.ensure()这个方法实现CMD规范的异步载入. 这同样也是webpack推荐的载入方式.想深入了解ensure, 请点击《webpack代码分离 ensure 看了还不懂,你打我》 下面的代码是使用require.ensure()方法对路由进行配置 //app.js import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' Vue.use(VueRouter) //AMD风格的异步加载 // const ComA = resolve => require(['./components/A.vue' ], resolve); // const ComB = resolve => require(['./components/B.vue' ], resolve); // const ComC = resolve => require(['./components/C.vue' ], resolve); //CMD风格的异步加载 const ComA = resolve => require.ensure([], () => resolve(require('./components/A.vue'))); const ComB = resolve => require.ensure([], () => resolve(require('./components/B.vue'))); const ComC = resolve => require.ensure([], () => resolve(require('./components/C.vue'))); const router = new VueRouter({ routes: [ { name: 'component-A', path: '/a', component: ComA }, { name: 'component-B', path: '/b', component: ComB }, { name: 'component-C', path: '/c', component: ComC } ] }) new Vue({ el: '#app', router: router, render: h => h(App) }) 复制代码 执行npm run build后, dist目录下同样生成5个文件 npm run build后生成的文件 按需加载效果演示: 按需加载效果演示 Lee_tanghui 发布在 https://www.jianshu.com/p/b3b8fb8a2336 原文发布时间为:2018年06月26日 原文作者:zhaiyy 本文来源掘金如需转载请联系原作者
如果你之前没有听说过CSS变量,那么现在我将告诉你:它是CSS的新特性,让你能够在样式表中使用变量的能力,并且无需任何配置。 实际上,CSS变量能够让你改变以往设置样式的老方法: h1{ font-size:30px; } navbar > a { font-size:30px; } 而使用了CSS变量之后: :root { --base-font-size: 30px; } h1 { font-size: var(--base-font-size); } navbar > a { font-size: var(--base-font-size); } 这样的词法有点奇怪,但它确实能够让你通过仅改变--base-font-size的值来改变app中所有原生的字体大小。 如果你想要学习CSS变量的知识,可以登录Scrimba看我的视频课程,或是阅读我在Medium上写的文章:如何学习CSS变量。 好了,现在让我们看看如何使用这个新知识来更加简单地制作响应式站点吧。 初始配置 让我们来把下面这个页面变成响应式的吧: 这个页面在PC端看上去很不错,不过你可以看到它在移动端的表现并不好。就像下面这样: 在下面这张图中,我们在样式上做了一些改进,让它看起来更好一点: 重新排列整个网格布局,使用垂直排列取代固定两列布局。 将框架整体上移了一点。 对字体进行了缩放。 目光转到CSS代码中,下面是我们要修改的代码: h1 { font-size: 30px; } #navbar { margin: 30px 0; } #navbar a { font-size: 30px; } .grid { margin: 30px 0; grid-template-columns: 200px 200px; } 更具体地说,我们需要在一个媒体查询中做出以下调整: 将h1的字体调整为20px; 减少#navbar的上外边距为15px; 将#navbar的字体大小减少到20px; 减少.grid的外边距为15px; 将.grid从两列布局变为单列布局。 注意:样式表里不仅仅是这些CSS声明,但是在这篇教程中我跳过它们,因为媒体查询并不影响它们的设置。你可以在这里获取完整的代码。 旧方法 不使用CSS变量确实可以做到同样的效果,但这样会增加许多不必要的代码,因为上面大部分修改都需要将声明在媒体查询中重写一遍。就像下面这样: @media all and (max-width: 450px) { navbar { margin: 15px 0; } navbar a { font-size: 20px; } h1 { font-size: 20px; } .grid { margin: 15px 0; grid-template-columns: 200px; } } 新的方法 现在让我们看看使用CSS变量是如何起作用的。首先,我们要声明需要更改或复用的变量: :root { --base-font-size: 30px; --columns: 200px 200px; --base-margin: 30px; } 然后,我们只需要在app中使用它们就可以了。非常简单: #navbar { margin: var(--base-margin) 0; } #navbar a { font-size: var(--base-font-size); } h1 { font-size: var(--base-font-size); } .grid { margin: var(--base-margin) 0; grid-template-columns: var(--columns); } 之后,我们可以在媒体查询中修改这些变量值: @media all and (max-width: 450px) { :root { --columns: 200px; --base-margin: 15px; --base-font-size: 20px; } 这样的代码是不是比之前要简洁多了?我们只需要专注于:root选择器就可以了。 我们将媒体查询中的4个声明减少到了1个,代码也从13行减少到了4行。 当然,这只是一个简单的例子。想象一下,在一个大中型网站中,有一个--base-margin变量控制着所有的外边距。当你想要在媒体查询时修改属性,并不需要用复杂的声明填充整个媒体查询,只是简简单单地修改这个变量值就可以了。 总之,CSS变量可以定义为未来的响应式。如果你想要学习更多的知识,我推荐你看我的免费教程。用不了多久你就能成为一个CSS变量大师。 原文发布时间为:2018年03月04日 原文作者:白吟灵 本文来源CSDN如需转载请联系原作者
什么是编码规范 编码规范就是指导如何编写和组织代码的一系列标准。通过阅读这些编码规范,你可以知道在各个公司里代码是如何编写的。 我们为什么需要编码规范 一个主要的原因是:每个人写代码的方式都是不同的。我可能喜欢这么写,而你喜欢用另一种方法写。如果我们只处理自己的代码,这样并没有什么问题。但如果有成千上万的程序员同时在一个代码库上面工作呢?如果没有规范,事情很快会变得一团糟。代码规范可以让新人迅速的熟悉相关的代码,并且也能写出让其他程序员简单易懂的代码。 Airbnb JavaScript Style Guide 号称是“最合理的编写 JavaScript 代码的方式”。 Airbnb 的这个代码规范可能是互联网最流行的 JavaScript 代码规范了,它在 Github 上足有 6 万 star,几乎覆盖了 JavaScript 的每一项特性。 地址: https://github.com/airbnb/javascript Google JavaScript Style Guide 只有遵守了这里的规则,一个 JavaScript 源文件才能被称为“Google Style”。很霸气,我行我素,同时也被不少公司沿用。 地址: https://google.github.io/styleguide/jsguide.html Idiomatic JavaScript Style Guide 符合语言习惯的 JavaScript 代码规范。 不管有多少人参与,不管是否在同一个代码库,所有的 JavaScript 代码风格都必须像同一个人写的。 另一个很强势的同时也很流行的 JavaScript 编码规范。它的野心也很大,不止想规范 JavaScript,其它语言也都想管起来。 地球上所有的代码都像同一个人写的?想想让人觉得不寒而栗啊…… 地址: https://github.com/rwaldron/idiomatic.js JavaScript Standard Style Guide 一个功能强大的 JavaScript 代码规范,自带 linter 和自动代码纠正,无需配置,自动格式化代码。可以在编码早期就发现代码中的低级错误。这个代码规范被很多知名公司所采用,比如 NPM、GitHub、mongoDB 等。 地址: https://github.com/standard/standard (这个 Github 地址霸气到不行。) jQuery JavaScript Style Guide jQuery 是多少人入门前端的好帮手啊,可惜如今只剩回忆了。它们的这个规范算是很早期的一个代码规范了,主要是针对它们的代码以及早期 JavaScript 版本进行规定。 地址: https://contribute.jquery.org/style-guide/js/ 你喜欢哪个代码规范,你的团队在用哪个规范呢?请留言告诉我们! 原文发布时间为:2018年01月29日 原文作者:JavaScript_w 本文来源CSDN如需转载请联系原作者
表格、表单、js常识 1.表格 - 在网页中可以通过表格来表示一些格式化的数据- 表格相关的标签- <table> 用来创建一个表格- <tr> 表示表格中的一行- <th> 表示表头中的单元格- <td> 表示表格中的单元格- 属性:colspan 横向的合并单元格rowspan 纵向的合并单元格- 例子:<table><tr><td></td><td></td></tr><tr><td></td><td></td></tr></table>- 长表格- <thead> 表格的头部- <tbody> 表格的主体- 注意:如果表格中没有写thead tbody tfoot,浏览器会自动向table中添加一个tbody并且将所有的tr都放到tbody中,tr是tbody的子元素,不是table的子元素- <tfoot> 表格的底部2.表单- 表单可以将用户的信息提交到服务器中- <form>- 用来创建一个表单- 属性:action:需要一个服务器地址,提交表单时表单中的内容将会被提交到该地址- 表单项- <input />- 它可以根据不同的type属性值,生成不同的表单项- type="text" 文本框 <input type="text" name="" />- type="password" 密码框 <input type="password" name="" />- type="radio" 单选按钮 <input type="radio" name="" value="" checked="checked" />- type="checkbox" 多选框 <input type="checkbox" name="" value="" checked="checked" />- type="submit" 提交按钮 <input type="submit" value="按钮上的文字" />- type="reset" 重置按钮 <input type="reset" value="按钮上的文字" />- type="button" 普通按钮 <input type="button" value="按钮上的文字" /> - <select>- 下拉列表- <select name=""><option value="" selected="selected"></option><option value=""> </option><option value=""></option></select>- <button>- 按钮功能input那几个按钮一样,但是它们要灵活一些<button type="submit">按钮的文字</button><button type="reset">按钮的文字</button><button type="button">按钮的文字</button>3.JavaScript- JavaScript负责页面中的的行为。- 它是一门运行在浏览器端的脚本语言。- JS的编写的位置1.可以编写到标签的指定属性中<button onclick="alert('hello');">我是按钮</button><a href="javascript:alert('aaa');">超链接</a>2.可以编写到script标签中 *****<script type="text/javascript">//编写js代码</script>3.可以将代码编写到外部的js文件中,然后通过标签将其引入 *****<script type="text/javascript" src="文件路径"></script>- 输出语句- alert("要输出的内容");- 该语句会在浏览器窗口中弹出一个警告框- document.write("要输出的内容");- 该内容将会被写到body标签中,并在页面中显示- console.log("要输出的内容");- 该内容会被写到开发者工具的控制台中- 基本的语法- 注释- 单行注释//注释内容- 多行注释/*注释内容*/- JS严格区分大小写 - JS中每条语句以分号(;)结尾,不写浏览器在解析的时候会自动加上- JS中会自动忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式化。- 字面量和变量- 字面量- 字面量实际上就是一些固定的值,比如 1 2 3 4 true false null NaN "hello"字面量都是不可以改变的。- 由于字面量不是很方便使用,所以在JS中很少直接使用字面量- 变量- 变量可以用来保存字面量,并且可以保存任意的字面量- 一般都是通过变量来使用字面量,而不直接使用字面量,而且也可以通过变量来对字面量进行一个描述- 声明变量- 使用var关键字来声明一个变量var a;var b;var c;- 为变量赋值a = 1;b = 2;c = 3;- 声明和赋值同时进行 *****var d = 456;var e = 789;- 标识符- 在JS中所有的可以自主命名的内容,都可以认为是一个标识符,是标识符就应该遵守标识符的规范。- 比如:变量名、函数名、属性名- 规范:1.标识符中可以含有字母、数字、_、$2.标识符不能以数字开头3.标识符不能是JS中的关键字和保留字4.标识符一般采用驼峰命名法 xxxYyyZzz 原文发布时间为:2018年04月21日 原文作者:Song-宋-Song 本文来源CSDN如需转载请联系原作者
#include<stdio.h>
int main()
{int i,j,k,a[5]={5,8,9,12,16},b[9]={1,3,5,5,7,8,9,12,16},c[14];
for(i=j=k=0;i<5&&j<9;)
if(a[i]<b[j])c[k++]=a[i++];
else c[k++]=b[j++];
for(;i<5;)c[k++]=a[i++];
for(;j<9;)c[k++]=b[j++];
for(k=0;k<14;k++)printf("%d ",c[k]);
return 0;
}
排序法可分为简单排序法和交替排序法。
简单排序法
简单排序法也称序列评定法,是指管理者把本部门的所有员工从绩效最高者到绩效最低者(或从最好者到最差者)进行排序,即对一批考核对象按照一定标准排出“1、2、3、4……”的顺序。
该方法也应用也工作评价上,由负责工作评价的人员,根据其对企业各项工作的经验认识和主观判断,对各项工作在企业中的相对价值进行整体的比较,并加以排队。在对各项工作进行比较排序时,一般要求工作评价人员综合考虑以下各项因素:工作职责、工作权限、岗位资格、工作条件、工作环境等。权衡各项工作在各项因素上的轻重程度并排定秩序后,将其划入不同的工资等级内。
简单排序法的优点:该方法的优点是简便易行,具有一定的可信性,可以完全避免趋中倾向或宽严误差。
缺点是考核的人数不能过多,以5—15人为宜,而且只适用于考核同类职务的人员,应用范围受限,不适合在跨部门人事调整方面应用。
交替排序法
交替排序法则是指管理者对被评估员工的名单进行审查后,从中找出工作绩效最好的员工列为第一名,并将其的名字从名单上划去。然后从剩下的名单中找出工作绩效最差的员工排为最后一名,也把其名字从名单中划去。随后,在剩下的员工中管理者再找出一名工作绩效最好的员工将其排为第二名,找出一名最差的员工列为倒数第二名,以此类推,直到将所有的员工排序完。