跳至主要内容

博文

目前显示的是 2017的博文

Docker in Windows 10

在 Windows 10 里头玩 docker,先安装 docker for windows 套件,然后直接可以用 PowerShell Console 来执行 `docker ps` 等指令。十分流畅地开始玩耍。 不过在尝试另一个 console - Windows 10 整合了 Ubuntu 的 bash,可以直接 Win+R 来执行 `bash` 打开命令行窗口。在里面就无法使用 docker,哪怕是 `sudo apt-get install docker` 也不成。 后来参考一个大牛的帖子 —— [Windows 10 bash & Windows docker 問題處理](https://blog.caesarchi.com/2017/05/15/windows-10-bash-windows-docker-intergrate_problem_solve/) 解决了。 摘录指令如下: ``` $ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" $ sudo apt-get update $ sudo apt-get install docker-ce ``` 总结一下:Win 10 总体来说比以前的 Windows (对Linux)友好了很多,但是小坑不少~

PowerShell Exercises - Merge files in folder

需要在Windows下做一些简单的文件操作,CMD显然已经过时了,开始试着用PowerShell。 如果是在Linux下面通常就是 find 之后 pipe 到 cat 完事。PowerShell的语法稍微复杂了点儿,不过也还是可以接受的: ``` Get-ChildItem -path . -recurse | ?{ $_.name.contains(".markdown") } | %{ Out-File -filepath ./cat-all.txt -Encoding UTF8 ` -inputobject (Get-Content $_.fullname -Encoding UTF8) -Append } ``` 『补充于2018年6月底』后来发现,`Get-Content` 的别名是 `cat`;还有一个与之对应的 `Set-Content` 别名是 `sc`,因此如果文件结构简单的情况下,可以把上面的命令简化为: ``` cat -Encoding UTF8 *.markdown | sc -Encoding UTF8 cat-all.txt ``` 另外如果需要执行类似于 `grep` 命令,例如,在 markdown 文件内使用正则表达式 `^## ` 查找二级 head : sls ^## .\cat-all.txt -ca

Create a docker image for coding (2)

基本思路是基于alpine来安装一些软件,包括 zsh, tmux, vim 等。 ``` FROM alpine:latest RUN echo "start to build linux workspace" \ # Install Workspace related tools && apk add --update --no-cache git curl vim tmux zsh \ # Install VIM bundle && mkdir -p ~/.vim/bundle \ && git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim ``` 接着开始配置这些工具,像是 vim 和 tmux 最好使用 GitHub 上开放的配置文件,或者如果自己有偏好设置也行。我使用的就是自己定制的一些配置文件。 ``` COPY vimrc /root/.vimrc COPY tmux.conf /root/.tmux.conf ``` zsh 的配置就没有太多的花头,大名鼎鼎的 oh-my-zsh 足矣。 ``` RUN echo "then configure tools" \ # By default the login shell for root user is /bin/ash in alpine, replace with zsh && sed -i -e "s/bin\/ash/bin\/zsh/" /etc/passwd \ # Install oh-my-zsh and configure zsh && (sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)" || true) \ && sed -i -- 's/robbyrussell/w...

Docker for Oracle database

发现 docker hub 上居然有 [Oracle DB 的 docker image](https://hub.docker.com/r/sath89/oracle-12c/),而且看可以配置的参数应该是挺方便的。 ``` docker run -d -p 8080:8080 -p 1521:1521 \ -v /User/me/workspace/12c/data:/u01/app/oracle \ -e DBCA_TOTAL_MEMORY=4096 \ sath89/oracle-12c ``` 只是不知道它的许可是怎么用的~甲骨文的律师可是有名的喜欢找麻烦……

Create a docker image for coding (1)

玩了会儿 Alpine 发现短小精悍, > docker run -it --rm -t alpine:latest /bin/sh 于是开始基于这个image打造自己的coding environment。安装了 zsh, tmux, vim 等工具。启动一个 container 就直接进入 tmux 的界面,可以随意开多视窗或是切割视窗,丰俭由人。 参考资料: 0. [Docker run reference](https://docs.docker.com/engine/reference/run/) 0. [Dockfile](https://github.com/JAremko/alpine-vim/blob/master/alpine-vim-base/Dockerfile) 0. [Oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) 0. [Vundle for VIM](https://github.com/VundleVim/Vundle.vim) 0. [Making tmux Pretty and Usable](http://www.hamvocke.com/blog/a-guide-to-customizing-your-tmux-conf/)

从切尔诺贝利保护壳来看Architecture

今年在电视上看到过一则纪录片,是介绍在切尔诺贝利核电站搭建一个保护壳的工程。 由于核辐射的威胁,无法直接在原核电站上直接施工,工程小组采取了很多手段来完成设计,其中包括搭建了一个可以移动建筑的液压轨道,以及在缓慢移动建筑的过程中时刻探测位置偏差的系统。在去年年底的时候这个工程终于成功的将保护壳移到了目标之上并完成了设施的封闭。 非常精妙的设计,对Architecture这个概念做了诠释——并不是只有最终的完成品算作architecture,在整个建造过程中如何构建、如何测量、如何移动,以及每一个步骤与其他步骤的整合,都是architect必须考虑的事情。 网络上没能找到原片,不过在油管上找到了一个简短的片子分享。

Dev's Ranting - Map rendering in Freemarker

I’ve got a `Map ` and set it as model attribute in MVC Controller. Then I'd like to render this map in a loop in Freemarker view, e.g. ${key.prop} = ${myMap[key].fooProp} </#list> I have to loop through keys as they need to be displayed in a order. And surprisingly, it does NOT work!!! After searching dozens of stack overflow as well as Freemarker docs, I've learnt that: 1. If the map's key type is not `String`, you cannot utilise the sugar syntax like `map[key]`, actually you can but it would return null value... 2. It seems there is some way to re-configure the Freemarker to enable syntax like `map?api.get(key)`, but it’s not trivial. I tried a few changes but did not work (see the TLDR below). *TL;DR* 1. Need to set `api_builtin_enabled` to true, this can be done easily in our CustomFreemarkerConfiguration 2. After that it’s complaining "The value doesn't support ?api." and suggests to change another configuration on `object_wrapper` ...

Dev's Ranting - Collectors.toMap() in Java Stream

If you have a map and wants to convert into a different map, say mapping the value to something different, it would be sensible to utilise Java 8 Lambda, right? Map newMap = oldMap.entrySet() .stream() .collect(Map.Entry::getKey, entry -> someMapperFunc(entry.getValue())); Unfortunately the lambda does not ALWAYS Work, depends on whether there is any NULL value in the original map. As documented in JavaDoc, the intention of the `toMap()` is to "Returns a Collector that accumulates elements into a Map whose keys and values are the result of applying the provided mapping functions to the input elements." So why does it not want to accept null value? You'll have to be thorough and patient enough to read all the three overloaded versions of `toMap()` to be able to figure out that, `Collector.toMap()` relies on `Map.merge()`, which is designed to throw NPE when a NULL value is passed in. Who would expect that? Idiot library implementation ... Refer to: ...

Dev's Ranting - Hibernate Mapping Collections of Subtypes

Hibernate 作为ORM框架的中流砥柱被广泛地应用于企业应用程序开发中。从早期的XML配置到现在的Java Configuration,开发者早已习惯了使用各种 annotation 来配置 entity mapping。不过基础概念都是一样的。 为了展示用于一对多关系的多表映射,DZone上有一个[挺简单的例子](https://dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-one-to-many-using-annotations-1.html)。 @Entity @Table(name = "STUDENT") public class Student { private long studentId; private String studentName; private Set studentPhoneNumbers = new HashSet (0); @OneToMany(cascade = CascadeType.ALL) @JoinTable(name = "STUDENT_PHONE", joinColumns = { @JoinColumn(name = "STUDENT_ID") }, inverseJoinColumns = { @JoinColumn(name = "PHONE_ID") }) public Set getStudentPhoneNumbers() { return this.studentPhoneNumbers; } } 这两天遇到了一个定义映射关系的问题,与上面这个映射的区别在于,除了 Entity A 和 B 之间有 join table之外,Entity B 实际上是共享一个table的sub type,使用了 `@DiscriminatorColumn`...

阅读笔记:Git 源码 (0)

GitHub上检出代码,跳转到第一个commit,那是2005年4月提交的 `e83c5163316f89bfbde7d9ab23ca2e25604af290`。 需要认真复习我的C语言知识了,不过重点不是在于语言,而是这个工具本身的设计。 CACHE_H这个头文件就挺精彩,数据结构直接是基于硬件结构来设计的,注释写的很清楚“根本不考虑可移植性,因为这仅仅是个cache,一切以效率为优先考量”。 ``` /* * Basic data structures for the directory cache * * NOTE NOTE NOTE! This is all in the native CPU byte format. It's * not even trying to be portable. It's trying to be efficient. It's * just a cache, after all. */ #define CACHE_SIGNATURE 0x44495243 /* "DIRC" */ struct cache_header { unsigned int signature; unsigned int version; unsigned int entries; unsigned char sha1[20]; }; /* * The "cache_time" is just the low 32 bits of the * time. It doesn't matter if it overflows - we only * check it for equality in the 32 bits we save. */ struct cache_time { unsigned int sec; unsigned int nsec; }; ``` 此外,作为最基础的数据结构,CACHE_H也定义了一组接口函数。 ``` /* Initialize the cache information */ extern int read_cache(void); /* Return a statically all...

Dev's Ranting - OnCommittedResponseWrapper in Spring

一转眼已经到了十月,我的草稿箱里还存着一个八月遇到的诡异bug:在我们的Spring Boot应用程序里,用到了Spring Security和Spring Session,这两个modules一直以来相安无事,直到有一天…… 使用Hibernate的时候如果查询结果集合过大,会导致response无法迅速返回。这里有两个要命的问题,首先由于Query在执行的时候JDBC的block调用过长,HTTP Gateway会超时;其次结果集过大意味着Hibernate在真正写入response (例如将结果集转换为DTO再写入CSV)之前不得不在内存中持有所有结果的对象引用,最终会致内存占用的问题,要么GC要么OutOfMemory。 为了解决在查询结果下载时遇到的问题,我们用到了`StatelessSession`和`ScrollableResult`来获取一个相当大的`ResultSet`,通过Java 8 的`Stream` 来访问单个元素,从而实现stream downloading。但是在调试中发现无法得到完整的CSV结果,经常是写到半当中就EOF了?! 同事老R花了大半天的时间来debug,最终无比惊讶的发现是Spring在控制`HttpServletResponse`的committed事件时有隐藏手段——`OnCommittedResponseWrapper`。貌似这个class在 [Spring Session](https://github.com/spring-projects/spring-session/blob/master/spring-session-core/src/main/java/org/springframework/session/web/http/OnCommittedResponseWrapper.java) 和 [Spring Security](https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security/web/util/OnCommittedResponseWrapper.java) 内各自有一份copy,而且还并非完全一样。 /** * Imp...

科技和信任感

上周参加了2天的YOW Connected会议,主题大多与Mobile和IoT有关,其中[一位speaker](http://www.annaharrison.com)讨论的是UX,听到了几个比较有意思的观点: 1. 当人们掏钱购买科技产品的时候,买的并不是科技本身,而是科技所创造出来的信任感。 曾几何时,人们只有在电影或是小说中看到邀请陌生人住进自己的家里,或是乘坐陌生人开的车子,而今,前者是通过为人们提供有趣的旅行方式和独特的本地居住经验而蜚声全球背包客的Airbnb;后者是以让人们在任何地方出行都可以更方便为使命的Uber。 2. 很多时候信任感体现在产品设计的细节中。 以手机上的两个App为例,Anna对比了T记和F记的设计。如果需要分享手机上的照片,需要先打开图库选择照片,然后点击分享。但是T记分享后直接返回图库,用户无法确定到底发没发出去,于是强迫症的用户就不得不回到主界面选择T记App确认是否有新的帖子po出去。另一边F记直接在返回图库前加了一个界面告诉用户一切搞定,于是高下立现。

一波三折装锁记

客厅到厨房的一扇门上的球形锁坏了,而且坏的时候门是关着的,只好慢慢的拆。幸亏油管 上有这个视频可以参考,大致了解了锁芯的结构之后用螺丝刀勾着弹簧将门打开了。 门上的锁孔就这么空着大约有一周了,总算到了休假日,上网查了查冲到了Bunnings去寻找 可以替换的部分,一开始以为是连球形手柄一起更换的,后来一位工作人员提示说只需要 更换 latch (门闩)的部分,而且推荐了一个和我带去的部件同品牌的配件。 本以为一切如此顺利,结果将新部件同坏掉的那个一对比发现中心轴同边缘的距离不同! 这意味着门上现有的空洞无法工作!又询问了另一个工作人员,他介绍了另一款adjustable latch,轴心可以选择在60mm或是70mm,后者刚好是我的门板上开的孔的距离。这里说的 70mm实际上有个专用的术语,叫做[backset](https://www.lowes.com/projects/build-and-remodel/determine-the-backset-of-your-door/project): > The backset is the distance from the edge of the door to the center of > the bore hole. 于是拿着这个可调整的latch回家试了试,果然中心轴对的上,只是latch的直径比起原有的 槽略微大了那么几毫米,我的电动工具上的Spade bit只有一件22mm的,没法用来将孔槽开大。 只好拿了件锉刀,慢慢地锉啊锉,打磨一个稍微大一圈的边。 好不容易将latch装进去后,试着安装球形锁,又杯具了,发现原有的spindle尺寸又不符合!所谓的spindle是一根短短的棒子,连接前后两个球形并穿过门闩 的机构,在转动的时候可以拉动弹簧以达到开锁的目的。心中无数头羊驼汹涌奔过!!! 上网搜索的时候发现居然没有明确标示spindle的轴心尺寸,不甘心之下又一次冲到bunnings, 在一堆白色塑料袋中寻找能够匹配的零件,最后总算是觅得一个长度一致(适用于厚度 为35mm的门板)并且可以同时适配球形孔槽和轴心孔的spindle!! 在这么多的折腾之后总算是将新的机构安在了门上,虽然还有一点点小瑕疵,不过还是可以 使用的。谢天谢地~

终于用上了NBN

两周前TPG的客服主动联系了我们,说NBN在我的小区已经rollout了,问是否愿意将当前的ADSL套餐升级为NBN Plan。电话里介绍了一大堆,听得有点儿晕晕乎乎的。好在前一段刚好对NBN的速度、套餐价格等做了一些了解,基本上还算有数。在约四十分钟后搞定了升级计划。TPG还算厚道,说十刀可以邮寄一个新的猫,二话不说就准了。 三天后收到了邮件,让确认某一天有人在家里配合NBN公司的上门安装。这效率还挺高(不是反话,按照土澳的一贯拖沓这的确是不错的了)。请了假在家里侯着,不过由于尚未收到新的猫,心中不由得嘀咕“怎么安装啊?” 总算是到了这一天,说好的上午8点至12点之间有人上门,活生生等到了11:30还没有任何动静,差点将走到前院抄水表的小兄弟误认为NBN的亲……打电话一问,人家客服mm说没有看到任何计划的变化,建议我继续等,如果到12:30还没有人来再联系他们。 谢天谢地到了12:20总算是开来了两辆小皮卡,这是要搞出多大的动静啊??俩哥们过来一看,一个在外墙的connection box里头捣鼓了会儿,问借了个小梯子站上去,我也没看着他做了什么;另一个兄弟进屋来,看了看接线处,说不需要再用电话线了,直接在我的电视机后面找到了一个copper(之类的)接口,告诉我就用这个口连接诶NBN NTD (network termination device)。拿出一个黑乎乎都是小洞洞的盒子帮我接了上去,然后又等了十几分钟,说远程会激活这个设备,等到我受到猫以后直接用RJ45连接拨号就可以使用了,不仅是Internet,就连电话线也将从猫上连接到电话上。之后他用平板拍了照片算是证明已经安装了,请我签了字,前后大约半小时不到,就算安装好了。 Easter假期前,总算是收到了新的猫,TPG貌似和华为有deal,每次送的都是华为的设备。这回的HG659个头还挺大,看起来高大威猛,号称支持2x2 wifi,看得一阵窃喜。不过由于已经有了一组【小而美】的荣耀路由Pro决定暂时不用它做WIFI router,纯粹就拨个号。 周末有空测了几次速度,时好时坏,好在我的预期也不过如此——网上抱怨的帖子多了去了,都说速度不稳定,主要还是埋怨各个运营商从NBN那里买的带宽不够导致。最好的时候和我的TPG Boost SL Plan所标称的最大下行25Mbps最大上行5Mbps差不多。...

平板笔记本和智能手表

看了几个3C产品,包括号称可以和Surface Pro 4媲美的联想[Miix 720](http://www3.lenovo.com/au/en/tablets-and-2-in-1s/windows-tablets/Lenovo-MIIX-720-12IKB/p/80VV004WAU?cid=au:cse:5u1yk7&istCompanyId=4cfbbd80-66d6-4bc7-b8ed-208db253ae0d&istItemId=xpmtlwatim&istBid=xztt),就是tablet和笔记本二合一的产品,当前价格是1700澳刀。 然后看了一款户外运动手表[Suunto Traverse Alpha Foliage](http://www.suunto.com/en-AU/Products/sports-watches/Suunto-Traverse-Alpha/Suunto-Traverse-Alpha-Foliage/),液晶显示,没有花哨的功能但是足以满足户外活动,包括地图GPS记录、温度计、指南针等。电池可以使用一个多礼拜,开着GPS一直用也可以坚持15小时。 最后看的是三星的智能手表[Gear S3](http://www.samsung.com/au/wearables/gear-s3-frontier-r760/SM-R760NDAAXSA/?cid=au_ppc_google_pla-imecom-gear+s3+frontier-ecom-buy_20170323&s_kwcid=AL!281!3!188992799269!!!g!!&ef_id=Vf1MYQAABVutUyJ8:20170402095444:s),它是基于Tizen系统,外观上貌似比华为的Watch2 (Android Ware) 好一些,表盘可以旋转,比起完全通过手指在盘面滑动要方便不少。电池是无线充电,可以用上一天半也算是不错的。

Vocabulary about illnesses (Part 2)

1. 外伤 * cramp/crunch 肌肉紧缩,抽筋 * abrasion 擦伤、摩破 * bruise (soft issue injury) 挫伤 * fracture 骨折 2. 内伤 * tendinitis 肌腱炎 * snap MCL 膝关节韧带断裂 * stomachaches 肚子疼 * joint / muscle pain 关节或是肌肉疼痛 * dislocated knee/bone/finger * carpal tunnel syndrome 腕隧道症候群,也被称为“鼠标手” 3. 肠胃不适 * diarrhoea / gastro 腹泻 -> irregular bowel movement * gastroenteritis 肠胃炎 * constipation 便秘 -> laxative 泻药 * cork 软木塞

Vocabulary about illnesses (Part 1)

之前看医生的时候倾向于预约会说中文的physian,主要是担心表达方面有沟通障碍。 在同事的帮助下整理了一堆和头部有关系的疾病的词汇: 1. 眼部 * long sightedness 远视 * short sightedness 近视 * pinkeye 红眼病 2. 鼻子 * sneeze 打喷嚏 * running nose 流鼻涕 * blocking nose 鼻塞 3. 口腔 * toothache 牙疼 * gum infection 牙周炎 * tonsillitis 扁桃体发炎 4. 一般症状 * cough 咳嗽 * headache 头疼 * migraine 偏头痛 * sore throat 喉咙疼 * vertigo 眩晕 * dizziness 头晕 (待续)

几个新学的词汇

公司一位同事要离职了,大家在写卡片送给她。看见别人写的留言里有这么两个词汇: 1. bubbly personality 2. tupperware jokes 问了同事也自己查了查,前者多用来形容女孩子积极向上的、充满自信的性格。 > Someone who is bubbly is very lively and cheerful and talks a lot. Tupperware (特百惠)是一个以其代表产品塑料食品容器知名於全球的美国家居用品品牌。 在20世纪四五十年代,该品牌的一个销售技巧就是通过家庭主妇组织派对来推销产品。 > A social gathering at which the host (or more typically hostess) entertains > the guests, and provides them with an opportunity to order Tupperware. > This was used as an effective sales strategy by the Tupperware manufacturer, > and provided income to the host(ess) from commissions on sales. 所以 _Tupperware party_ 这个词是有引申含义的,而 _Tupperware jokes_ 在这里指的是以塑料容器为主题的玩笑话。