• 技术,  算法

    Java中数组操作的性能

    其实不同数据结构的性能差别还是很明显的,只是在实际使用中这种差别会被网络等各种开销所掩盖。所以这里看到的1000倍以上的差别可能在实际场景中并不那么明显。 下面写写出结果: 运行环境时m1 CPU的macbook mini。可以看到插入1000个int到数组是0.017ms, ArrayList是0.584ms, LinkedList是0.379ms,HashSet是5ms,LinkedHashSet是2ms。最好和最差之间相差500倍。 但是如果要在网络传输这么1000个integer对象,可能直接就是几十毫秒的花销了,存储的时间根据不同介质也要几毫秒不等。而且通常如果需要存储的话肯定也需要网络开销,本地存储的概率很低。 但是这些基础的性能开销上的差别在大数据处理的时候应该还是能显现出差别的。最慢的5ms 1k数据,如果数量级到1million的话,那么就是5s,1billion的话就是1个多小时。如果用int的话,那就是10s。1个多小时 VS 10s 还是很可观的差距。只是不知道把1billion的数据load到内存需要多久😂 在实际的项目中其实也从来没有遇到过这种内存计算开销导致的性能瓶颈。如果以后什么时候遇到了,我再回来update这里。。

  • Java,  技术

    Java Streaming Basic

    10年前加入现在的公司的时候公司的产品还在用JDK5,写code自然完全不会用Lamda,Streaming这些8才出现的特性。 后来开始做micro service了,用到新版本的JDK,但是我也很少写code了。中间看了一些书,不过一直是似是而非。是时间仔细看下了。 Intermediate Operations filter limit map flatMap Stream.map和Stream.flatMap的区别 先看signature. 区别是 flatMap穿进去一个Item,出来一个Stream: 这两个其实是完全不一样的东西,map就是把steam里面的item转换成另外一个,非常简单。flatMap是用来处理item也是list的情况,有时候我们想把两维列表转化成一个,就可以用这。下面是一个简单的例子: 下面是项目的一个更加实际的例子: 这个例子是拿到一个父对象,父对象里面有子对象,这样就能拿到所有的子对象。 总的来说stream就是一个循环,而flatMap就是一个嵌套循环。 下面是另外一个lamda的例子(不是method reference): Terminal Operation forEach forEach其实就是iterate.不用改被用作计算,就是用简单的report,或者简单的操作比如把结果加到另一个colection里面. –<Effective Java> collect 常用的的下面几种: toList toSet toMap:如果有重复key,会出错。第三个参数可以用来去重。比如可以选择最大,选择最后的一个。 groupingBy:Value可以是一个数组,也可以是summary,比如`counting()`. Joining: 三个参数,join的delimiter, start character,end character

  • Docker,  技术

    Docker的权限控制

    昨天晚上几个小时折腾一个docker上的mysql数据库的问题,最后发现根本原因是自己脑残把docker的目录的权限写成777. 由此导致了一系列问题。 事情的起因是想给mysql加一些参数,限制总的binlog的size。因为昨天发现磁盘空间被mysql用完然后导致这个网站down机。。 本来加一个参数很简单的事情,但是修改了/etc/my.cnf 之后发现参数并没有生效。于是各种研究,后来发现在log里面显示由于my.cnf的权限是全局可写,然后mysql自动忽略了这个配置文件而用缺省文件。所以所有的添加到my.cnf里面的信息自然不会生效。 在这里的时候完全没想到是因为自己把docker的目录改成777导致了,心里却在埋怨做image的人怎么留下了这个bug。于是上手又是用volume map本地的my.cnf到远程(我的docker daemon是run在远程linux下),又是直接修改my.cnf的权限。终于配置文件生效了。但是tungsten replicator怎么样也连接不到mysql。于是添加ssl=0 试图disablessl,但是又遇到无效caching_sha2_password的问题. 搜索文档还要修改用户的默认密码存放方式,想修改还是不成功,还要修改system db的engine。。 因为在这开始之前,我的tungsten replicator 通过修改ssl的方式就可以连接,完全没有做那些繁琐的操作,于是开始怀疑到底哪里出错,为什么这次需要这么复杂。 2个小时以后开始怀疑可能是/etc/my.cnf的权限问题不是image的问题,而是我做了777导致了。又做了一些尝试终于算是解释了所有的现象: 由于错误的使用777,导致mysql image初始化的时候使用了默认的参数配置,这就是为什么当我之后再修改my.cnf的配置的时候已经晚了,因为缺省配置很多时候是没办法初始化之后修改的。比如说创建用户的时候的密码设定( 应该是“mysql_native_password“而不是缺生的”caching_sha2_password”). Volume映射的时候文件权限默认使用的是宿主的文件权限。我的docker compose文件在mac,docker engine在linux。最终的映射是 mac -> linux host -> container. 这中间还有一个把nas的文件映射到linxus host上的过程(这里也出现了一些问题,docker后来莫名其面起不来某些container,原来是我的nas映射出问题了,重启mac电脑解决。。) 中间试图修改docker的文件目录权限,但是发现太麻烦,潜在的问题太多,因为我也不知道最早的文件的权限是啥。所以干脆删除所有的目录,让docker重现下载image,重建目录。问题解决。 经验总结 要及时document各种步骤。我之前通过ssl=0解决了tungsten的链接问题,但是昨晚改动,工作了就没有document。结果几天以后自己都忘了自己做了什么,只记得在mysql上改了一个配置。当后来出现问题的时候,因为不确定之前怎么工作的,导致浪费了很多时间。 现在的docker 貌似是run在linux,但是由于使用docker compose运行很多containers,而docker compose文件是在mac,而且volume的映射最终是在mac (mac->linux host),所以docker 还是没办法脱离mac电脑而在远程执行。只能说runtime的话有linux host就好了,但是要做操作修改,还是要在mac端完成。 用Docker也有几年时间,但是没有真的很系统的学习,其实可能只需要认真花一两天看看书,很多我今天遇到的问题都不会出现。与其花时间debug问题还不如把基础打牢啊。。