博文

目前显示的是 2016的博文

Java 8的For与Stream的性能差距到底有多大?

Java 8开始引入了Stream流式操作,终于稍微可以像写Python一样写代码了,不用满大街写For语句了,但是因为 这篇文章 的缘故,导致我对它的性能一直抱有怀疑态度。 但是仔细分析示例中的代码,其实会发现虽然它的示例代码中使用了Stream但是其实那个很慢的结果真正大部分的时间都花在了Integer的自动装、拆箱操作上,真正的Java 8应该是怎么写这个代码呢,还是自己动手试验一下好了。 package org.acgeek; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.stream.IntStream; public class ForVsStream { public static void main(String[] args) { List<long> forTest = new ArrayList<>(); List<long> streamTest = new ArrayList<>(); IntStream.range(0, 100).forEach(n -> { int[] a = new Random().ints(5000000, 1, 99999999).toArray(); int e = a.length; int m = Integer.MIN_VALUE; long thisTime = System.nanoTime(); for (int i = 0; i < e; i++) if (a[i] > m) m = a[i]; System.out.println("MAX is " + m); Long testRes = System.nanoTime() - thisTime; forTest.add(te...

Centos7下安装ceph

本来ceph这货的安装简直是傻瓜到一塌糊涂的,但是仰仗于国内伟大的GFW,这安装过程变得极其曲折 以下仅列出最后所使用的手法: 删除Centos 7自带的的repo(都太慢) rm -rf /etc/yum.repos.d/*.repo 使用阿里云的repo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo 注意,epel源一定要打开,因为ceph依赖snappy之类的都在epel里面 添加一个用于安装ceph-deploy的源 vim /etc/yum.repos.d/ceph.repo 添加以下内容: [ceph] name=Ceph packages for $basearch baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/$basearch enabled=1 gpgcheck=1 type=rpm-md gpgkey=https://download.ceph.com/keys/release.asc yum makecache yum install ceph-deploy 接下来就按照 官方的教程 走就好了,就不大可能出现一大堆诡异的什么无法安装的错误了,这安装流程也异常的简单, 唯一注意的:当使用ceph-deploy install的时候,务必这样用:ceph-deploy install --repo-url http://mirrors.aliyun.com/ceph/rpm-jewel/el7  ceph-deploy install admin-node node1 node2 node3(官方的方法是: ceph-deploy install admin-node node1 node2 node3 )因为这个ceph-deploy在安装过程中会自动帮你修改repo,所以需要用--repo-url来拒绝这个改动,我安装的是jewel发行版,可根据实际需要修改为最新的 值得...

利用letsencrypt.sh脚本来获取Let'sEncrypt的SSL证书

Let's Encrypt是个好项目,但是问题是它的客户端太臃肿了,而且到目前为止还只支持Apache,相比之下github上letsencrypt.sh只用sh脚本就实习了足够的功能了。还能适配nginx。但是,它也有它的问题——文档太少且支离破碎,根本没有成体系的手册,只能自己看代码摸索。我也是花了老半天的时间才搞定它。 首先先clone下这个项目 git clone git@github.com:lukas2511/letsencrypt.sh.git 默认有两种办法在ACME服务器上获取授权注册,我用的是配合Nginx的HTTP模式 在nginx的对应的domain server字段下添加以下设置 location /.well-known/acme-challenge {     alias /var/www/letsencrypt; } 这个在http或者https下都没问题,哪怕你https的证书有问题也可以被识别,但是如果是第一次申请,还是老老实实地放http上省得麻烦 指向的地址是需要用的WELLKNOWN变量地址 在仓库下新建一个config.sh文件,内容如下: #CA = " https://acme-staging.api.letsencrypt.org/directory " CA = " https://acme-v01.api.letsencrypt.org/directory " WELLKNOWN =/var/www/letsencrypt 第一行的CA地址是调试用的,基本上你搞这个一次是很难搞定的,用调试地址可以有效的避免被远端屏蔽  WELLKNOWN就指向我们刚才nginx中设置的地址 继续新建一个domains.txt,格式类似 aaa.com www.aaa.com b.aaa.com bbb.com ccc.bbb.com www.bbb.com rr.bbb.com 一行一个域名,每个子域名空一格  接着运行  ./letsencrypt.sh -c --config config.sh 你会看到类似这样的输出 + Signing domains... + Generating pri...

解决自建docker registry客户端无法push的问题

按照官方推荐的方式,下载了registry的镜像,结果在另外一台电脑上镜像死活也推送不上去,持续报告这个错误: [root@localhost network-scripts]# docker push 192.168.120.129:5000/test The push refers to a repository [192.168.120.129:5000/test] (len: 1) unable to ping registry endpoint https://192.168.120.129:5000/v0/ v2 ping attempt failed with error: Get https://192.168.120.129:5000/v2/: dial tcp 192.168.120.129:5000: connection refused v1 ping attempt failed with error: Get https://192.168.120.129:5000/v1/_ping: dial tcp 192.168.120.129:5000: connection refused 其实就是docker尝试去使用https来增强安全性,但是我组建的docker registry是纯内网使用的,这种莫名其妙的增强安全性纯属浪费性能,所以直接禁用就好 直接禁用的办法也很简单,编辑/etc/sysconfig/docker,修改 OPTIONS='--selinux-enabled' 改为(后面的IP是你的registry所在的地址与端口) OPTIONS='--selinux-enabled --insecure-registry 192.168.120.129:5000' 当然,你也可以使用更为纯粹的方法,自己颁发证书或者是使用购买了的证书……方法见这里:https://docs.docker.com/registry/insecure/

最近的一些Python心得点

都是一些零散的东西,但是知识就是这么零散的积累起来的。 一、用dict的setdefault来给字典赋默认值,而不是去写if key not in: res = {} for i in music_tag_source: tag = res.setdefault(i.get('music_id'), []) tag.append(i.get(music_tag)) 二、批量生成拥默认值的dict,可以考虑使用defaultdict,这样的dict的任何key都是有自己的默认值的 from collections import defaultdict res = defaultdict(list) for i in music_tag_source: res[i.get('music_id')].append(i.get(music_tag)) 三、给类设置一个__slot__ 属性会导致实例化时不会自动分配 __dict__而只能设置__slot__中声明的属性 ,这样的小技巧可以用在那些写满了__getattr__的类中, class Foo(object): __slots__ = {'a', 'b'} if __name__ == '__main__': bar = Foo() bar.a = 1 try: bar.c = 2 except AttributeError as e: raise Excption('cannot set attrib c') from e 但是这东西有个奇怪的语法问题,就是你这样写是会报告语法错误的 class Foo(object): __slots__ = {'a', 'b'} def __init__(self): self.c = 1 但是你这么写就居然没问题 class Foo(object): __slots__ = {'a', 'b'} def __getattr__(sel...

最近遇到的两个JS的Tips

一个是HTML5规范的data标签,如果你想使用驼峰的话,记住是data-a-b,最后会自动变成aB,如果直接写data-aB是取不出来的,会变成ab的。 这个是写在HTML5规范中的,我想大概是因为XHTML中不不允许HTML标签有大写,所以不允许这样吧,至于驼峰估计是规则制定者的爱好了吧。 另外一个大概是JQuery的特性,如果写入在data属性的数值,取出来的时候是int,而不是str,这个特性其实挺莫名其妙的,因为这并不像html的input type=number中的元素的value属性,这个取出来一定是数值是因为我指定了它的Type是number,但是data明显可以是一个任意类型,总之,如果在jshint指定了一定要使用===进行类型判断比较的话,记得回避这个坑。