Flask日志级别的问题 (xnow.me)
这也是个老问题,很早之前发现使用logging模块在flask里记录info日志记录不上,没在意,但是有时候习惯拿info级别在线调试服务的时候没有日志就很苦恼,花了点时间来研究怎么设置flask的日志级别。
by @技术头条 2017-03-27 10:03 查看详情
Linux的进程间通信-消息队列 (liwei.life)
Linux系统给我们提供了一种可以发送格式化数据流的通信手段,这就是消息队列。使用消息队列无疑在某些场景的应用下可以大大减少工作量,相同的工作如果使用共享内存,除了需要自己手工构造一个可能不够高效的队列外,我们还要自己处理竞争条件和临界区代码。而内核给我们提供的消息队列,无疑大大方便了我们的工作。

Linux环境提供了XSI和POSIX两套消息队列,本文将帮助您掌握以下内容:

如何使用XSI消息队列。
如何使用POSIX消息队列。
它们的底层实现分别是什么样子的?
它们分别有什么特点?以及相关资源限制。
by @技术头条 2017-03-23 23:59 查看详情
PHP7与Swoole (rango.swoole.com)
可以预见PHP语言未来会在性能方面有明显的提升,越来越接近C/C++、Java等静态编译语言。再加上Swoole扩展,PHP的使用范围可以扩展到移动通信、云计算、网络游戏、物联网、车联网、智能家居等领域。
PHP虽然未必是最好的编程语言,但PHP在向着这个方向在发展。
by @技术头条 2017-03-23 23:58 查看详情
关于编程语言 (rango.swoole.com)
最近群里很多朋友询问我是如何学习编程的,今天抽个时间大致讲讲。

C语言

和所有人一样,上学学的第一门编程语言是C语言。我记得我当时学的很认真,非常认真。和别人最大的不同是我买了一本老外写的C语言编程书,没被谭浩强误导。另外还买了一本《现代操作系统》一书看了很久。学习期间写了不少读书笔记。真正要说学到什么了,这个还真不好说,到最后我对C语言也是似懂非懂的状态。

用学物理、数学的方法学编程语言是行不通的,编程需要的是实践。

Java

学Java的目的很明确,为了找一份好工作。面向对象、J2EE、Java设计模式、SSH的书买了好几本。最后还是没能够入门。原因我后来分析主要是2点,1、Java太复杂了,根本就不适合初学者。2、犯了和学习C语言同样的错误,读书太多,实践太少(主要是不会搭建Java的开发环境)。
PHP

偶然的机会了解到了PHP语言,按照网上的教程一搞,写了一个MySQL的网页程序,竟然运行成功了。这实在太神奇了。你们无法理解当时我的心情,可以说到了 高兴地3天不用吃饭的程度。呵呵,当时我就下定决心以后就是它了。PHP让我进入了一个新的境界,我可以大量地实践,写出各种程序。而且也顺利找到了工作,干的风生水起,一个接一个地做了很多项目。后来又进入腾讯,在腾讯有机会去开发维护一个超过2亿用户,日活超过8千万,机器规模超过1000多台的超大系统。我的人生的各种成果都归功于PHP这门伟大的编程语言。

重新回到C语言

当然后面也逐渐认识到PHP的不足,不过很快我就发现可以写C扩展来弥补。重新学起C语言,我发现竟然很顺利。原因应该是我在写PHP程序的过程中,工程实践能力已经磨练到非同一般。其实不只是C语言,只要我愿意,C++,Java,Python,Golang任何语言都可以快速掌握。然后就开始搞Swoole这个项目,边学边做。经过这2年的时间,现在可以说我已经掌握C语言了。
为什么会回到C语言,原因很简单:所有底层软件都是C语言写的,包括操作系统、底层库、驱动、其他编程语言本身。C语言一切现代软件技术的根源。

我的个人感悟

我的编程之路轨迹就是 C语言(起始) -> Java(过客)-> PHP(主)-> C语言(终点)。
编程语言专注于一个就行了,Java、PHP、Python、Ruby 任意一个都行。只要能把一门编程语言学精通,其他语言学起来也很容易。
工作时选择的编程语言,应该是一主多辅。做Web得了解Javascript,做APP需要掌握Android、Object-C,写桌面程序需要学习C++。带着问题去学就好了。
不要选择难或者复杂的编程语言作为入门,易于上手的编程语言更容易成功。公司有一个搞Java 9年的人,技术等级很低。很好的例子。另外一个只工作了5年的PHPer现在已经是T3-2的技术Leader了。
编程最核心的是动手实践
多看一看别的编程语言和技术,开阔一下视野
编程做到最后还是会回到C语言的,当然很多人中途就已经离开编程岗位了
by @技术头条 2017-03-23 23:58 查看详情
一个前端项目,到底要集成多少库和工具 (www.raychase.net)
最近忙于一些新做的项目,由于新入手,就想着往最佳实践去靠,也寻找一些可以借鉴的模板。其中前端的部分,有很成型的模板可以借鉴。大幅度减少了自己调查和集成的工作量。但是仔细看看,发现这里头的概念太多了,各种开源的库和工具,有人说“前端玩的是广度”是有道理的。

这个新项目并不算特别复杂,大致的技术是基于React+Redux的,但是大体上集成完毕以后,完成了几个demo的代码之后,粗粗地过了一遍,除了传统意义上的HTML+CSS+JavaScript(遵循ECMAScript 6的标准)三大件,居然涉及到了那么多技术,把自己吓了一跳。
by @技术头条 2017-03-23 23:57 查看详情
Android Debug 版本判断及为什么 BuildConfig.DEBUG 始终为 false (www.trinea.cn)
Android 开发中一般会通过 BuildConfig.DEBUG 判断是否是 Debug 模式,从而做一些在 Debug 模式才开启的特殊操作,比如打印日志。这样好处是不用在发布前去主动修改,因为这个值在 Debug 模式下为 true,Release 模式下为 false。
by @技术头条 2017-03-23 23:57 查看详情
【死磕Java并发】—–J.U.C之AQS:同步状态的获取与释放 (cmsblogs.com)
在前面提到过,AQS是构建Java同步组件的基础,我们期待它能够成为实现大部分同步需求的基础。AQS的设计模式采用的模板方法模式,子类通过继承的方式,实现它的抽象方法来管理同步状态,对于子类而言它并没有太多的活要做,AQS提供了大量的模板方法来实现同步,主要是分为三类:独占式获取和释放同步状态、共享式获取和释放同步状态、查询同步队列中的等待线程情况。自定义子类使用AQS提供的模板方法就可以实现自己的同步语义。
by @技术头条 2017-03-23 23:57 查看详情
数学之美-无限状态遇上质因数 (www.sunhaojie.com)
爱因斯坦:“美,本质上终究是简单性;”

为了满足准确性,我们可以为业务数据增加标记状态,用于表示数据已经被处理情况的描述,因为统计项的无限(在一个比较大的范围有限)增加,所以怎么用有限的字段表示无限的状态的标记;并且因为无序性,业务数据的状态不能限定统计项处理的次序。

质因数的定义:质因数在数论里是指能整除给定正整数的质数。除了1以外,两个没有其他共同质因子的正整数称为互质。因为1没有质因子,1与任何正整数(包括1本身)都是互质。正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以指数表示。根据算术基本定理,任何正整数皆有独一无二的质因子分解式。

我们可以使用质数作为每个统计项的编码,统计项编码的乘积合数作为业务数据的标记状态。
by @技术头条 2017-03-23 23:54 查看详情
sproto 的一些更新 (blog.codingnow.com)
sproto 是我设计的一个类 google protocol buffers 的东西。

在很多年前,我在我经手的一些项目中使用 google protocol buffers 。用了好几年,经历了几个项目后,我感觉到它其实是为静态编译型语言设计的协议,其实并没有脱离语言的普适性。在动态语言中,大家都不太愿意使用它(json 更为流行)。一个很大的原因是,protobuffers 是基于代码生成工作的,如果你不使用代码生成,那么它自身的 bootstrap 就非常难实现。

因为它的协议本身是用自身描述的,如果你要解析协议,必须先有解析自己的能力。这是个先有鸡还是先有蛋的矛盾。过去很多动态语言的 binding 都逃不掉引入负责的 C++ 库再加上一部分动态代码生成。我对这点很不爽,后来重头实现了 pbc 这个库。虽然它还有一些问题,并且我不再想维护它,这个库加上 lua 的 bind
by @技术头条 2017-03-23 23:53 查看详情
只是Flask-CAS的Demo而已 (xnow.me)
起了个轻松一点的标题,但其实是折腾CAS的心酸史,跨越大半年的时间,终于搞定了Flask-CAS这个模块。这是个悲伤的故事!

从头说起,CAS是central authentication service的缩写,也是一套单点登录协议标准。每个公司内部有很多自研的、商业的或者开源的系统,如果有了CAS,你只需要在某个接入CAS的站点登录,其它站点就可以自动登录了,不需要再单独验证。听起来很爽吧。这里不讲解具体原理,因为通过搜索引擎找到这篇文章的人应该都是和我曾经一样走投无路只想解决问题的人。。。

没错,我们公司里就部署了这么一套cas系统,我们采用了开源的企业级解决方案https://www.apereo.org/projects/cas, 后台采用OpenLDAP做认证,公司大多数系统都愉快的接入了这套cas。

大半年前,我用Flask写了一套web管理系统想接入公司的CAS做认证,使用Flask-CAS,不成功,太忙就放弃了,转而走上了HTTP Basic access authentication + LDAP的邪路。最近又遇到这么个问题,一个要修改状态的服务,为了防止用户伪造身份,所以还是想接入cas做下身份校验。走上了和Flask-CAS死磕的道路。

首先,不知为何,pip只能安装Flask-CAS的1.0.0版本,不信你看 https://pypi.python.org/simple/flask-cas/,但是为啥我又看到了1.0.1的版本,不信你看https://pypi.python.org/pypi/Flask-CAS。我也没太放在心上,反正先搭建起来再看呗。
by @技术头条 2017-03-23 23:53 查看详情
png的故事:获取图片信息和像素内容 (www.alloyteam.com)
前言

现在时富媒体时代,图片的重要性对于数十亿互联网用户来说不言而喻,图片本身就是像素点阵的合集,但是为了如何更快更好的存储图片而诞生了各种各样的图片格式:jpeg、png、gif、webp等,而这次我们要拿来开刀的,就是png。

简介

首先,png是什么鬼?我们来看看wiki上的一句话简介:
Portable Network Graphics (PNG) is a raster graphics file format that supports lossless data compression.

也就是说,png是一种使用无损压缩的图片格式,而大家熟知的另外一种图片格式——jpeg则是采用有损压缩的方式。用通俗易懂的方式来讲,当原图片数据被编码成png格式后,是可以完全还原成原本的图片数据的,而编码成jpeg则会损耗一部分图片数据,这是因为两者的编码方式和定位不同。jpeg着重于人眼的观感,保留更多的亮度信息,去掉一些不影响观感的色度信息,因此是有损耗的压缩。png则保留原始所有的颜色信息,并且支持透明/alpha通道,然后采用无损压缩进行编码。因此对于jpeg来说,通常适合颜色更丰富、可以在人眼识别不了的情况下尽可能去掉冗余颜色数据的图片,比如照片之类的图片;而png适合需要保留原始图片信息、需要支持透明度的图片。
by @技术头条 2017-03-23 23:50 查看详情
现代化的缓存设计方案 (ifeve.com)
缓存是提升性能的通用方法,现在大多数的缓存实现都使用了经典的技术。这篇文章中,我们会发掘 Caffeine 中的现代化的实现方法。Caffeine 是一个开源的 Java 缓存库,它能提供高命中率和出色的并发能力。期望读者们能被这些想法激发,进而将它们应用到任何你喜欢的编程语言中。

驱逐策略

缓存的驱逐策略是为了预测哪些数据在短期内最可能被再次用到,从而提升缓存的命中率。由于简洁的实现、高效的运行时表现,以及在常规的使用场景下有不错的命中率,LRU(Least Recently Used)策略或许是最流行的驱逐策略。但 LRU 通过历史数据来预测未来是局限的,它会认为最后到来的数据是最可能被再次访问的,从而给与它最高的优先级。

现代缓存扩展了对历史数据的使用,结合就近程度(recency)和访问频次(frequency)来更好的预测数据。其中一种保留历史信息的方式是使用 popularity sketch(一种压缩、概率性的数据结构)来从一大堆访问事件中定位频繁的访问者。可以参考 CountMin Sketch 算法,它由计数矩阵和多个哈希方法实现。发生一次读取时,矩阵中每行对应的计数器增加计数,估算频率时,取数据对应是所有行中计数的最小值。这个方法让我们从空间、效率、以及适配矩阵的长宽引起的哈希碰撞的错误率上做权衡。
by @技术头条 2017-03-23 23:48 查看详情
线程亲和性(Thread Affinity) (ifeve.com)
如果你正在开发低延迟的网络应用,那应该对线程亲和性(Thread affinity)有所了解。线程亲和性能够强制使你的应用线程运行在特定的一个或多个cpu上。通过这种方式,可以消除操作系统进行调度过程导致线程迁移所造成的影响。幸运的是,刚好有一个这么一个java库 Java-Thread-Affinity ,并且很容易就可以整合到你的netty应用中。
by @技术头条 2017-03-23 23:47 查看详情
揭秘 Github 上那些开源项目的 star 数 (pingguohe.net)
前段时间团队内开源了两个小项目:vlayout和LazyScrollView,一般我们可以通过它们的 star 数(即被其他人收藏的数量)来了解它们的受欢迎程度。但是一个项目到底集齐多少个 star 才算受欢迎呢?Github 上那些开源项目的 star 分布是怎样的?……只有了解这些才能更好的评估一个项目的流行程度。好在 Github 有开放第三方接口,提供了足够多的有用信息,我稍微整理了一下,感觉有点意思,分享一下。(以下数据统计于2017年3月18日)
by @技术头条 2017-03-23 23:45 查看详情
更多关于Flexbox布局如何工作的 – 用大彩图和GIF动画解释 (www.css88.com)
我们入门了几个基本的 Flexbox 属性:flex-direction,justify-content,align-items和align-self。

这些属性对于创建基本布局非常有用。 但是一旦你开始使用Flexbox构建网页的时候,你需要更深入学习Flexbox 属性,以发挥它的潜力。

现在让我们深入了解 Flexbox 的缩放 – 以及如何利用它来构建漂亮的自适应布局。
by @技术头条 2017-03-22 00:14 查看详情
Flexbox布局是如何工作的 – 用大彩图和GIF动画解释 (www.css88.com)
Flexbox 布局将我们从CSS的邪恶(如垂直对齐)中拯救了出来。

很好,Flexbox 确实实现了这个目标。 但掌握新的弹性模型可能还是具有一点挑战性的。

所以,让我们以动图的形式来看看 Flexbox 的工作原理,这样我们可以使用它来构建更好的布局。

Flexbox 的基本原理是让布局变得灵活和直观。

为了实现这个目标,它让容器自己决定如何均匀分配它的子元素 – 包括子元素的大小和相互之间的间隔。

这听起来是很不错的原则。 但让我们看看它在实践中又会是什么样子的呢。

在本文中,我们将探讨 5 个最常见的 Flexbox 属性。我们将探索他们究竟做什么,如何使用它们,以及它们会产生什么实际效果。
by @技术头条 2017-03-21 23:59 查看详情
利用GDB、KGDB调试应用程序及内核驱动模块 (blog.nsfocus.net)
这几天看了一下linux内核提权的一个漏洞,里面涉及到了驱动程序漏洞及驱动调试内容,由于各类linux操作系统版本的不同,如果不能在自己机器上亲自调试驱动程序,可以说即使给了漏洞利用的POC源码也根本无法成功利用。因为内核漏洞的利用涉及到指令集的POC构造,不同内核版本模块加载指令地址不同,导致即使有POC也根本无法利用,只有在自己系统中亲自调试,才能做出相应的修改,达到内核漏洞利用的效果。这样就要求我们对linux内核驱动的调试过程,调试方法有个深入了解。经过两天的各处查找,配置,调试,终于弄清楚了内核调试的基本方法,为之后内核调试,漏洞分析提供技术支持。
目标

在驱动程序开发或是内核漏洞分析过程中经常需要对内核模块进行调试。在通常情下对于驱动程序的调试是利用最直接的方式即打印调试的方式,在驱动程序中通过printk,加入调试信息。同时通过动态加载模块的方式,即可实现对驱动的动态调试,这也是最简单的调试方式。而对于内核漏洞的分析,由于linux系统是开源项目,所有不管对于应用程序的调试还是对内核驱动程序的调试都可以通过查看源码找到漏洞的触发点。

那如果想像调试用户态应用程序一样对内核驱动做动态的源码即调试或是更进一步的对驱动程序进行汇编级调试或是开发内核漏洞利用程序那又该怎么办呢?也许有人会说一般没有必要进行汇编级调试。但是在对内核漏洞利用过程中经常需要调试内核驱动程序,并且需要对内核驱动进行汇编指令级单步跟踪,这样才能确定程序的走向。或是我们需要构造特殊的指令块来完成某项功能。这样就对我们调试内核带来的新的挑战。

那内核里面又是怎么实现的呢,又该如果能够去跟进内核内部去调试呢?

本文就是要解决这个问题:在动态汇编调试用户态应用程序的同时,能够跟进应用程序的的系统调用接口,直接源码级或是汇编级的调试(如果没有符号表)调试驱动程序。

本文演示的程序是通过一个应用程序demo,调用自己写的一个驱动程序接口,通过在调试应用程序的是时候能够跟进调试驱动程序。搭建这样的环境我们使用了vmware虚拟机,该虚拟机使用普遍,安装简单。为了能够调试程序,需要一个目标机和一个客户机。

目标机是用来安装驱动程序,同时运行应用程序,应用程序会调用驱动程序中的接口。同时目标机自己调试应用程序(用户态使用GDB调试)。

客户机是用来连接客户机,同时在客户机中调试目标机中的驱动程序(使用GDB调试)。

需要注意几点:
为了能够能够调试目标机的驱动程序,要求目标机需要支持KGDB调试。
为了能让客户机与目标机通信,我们在vmware中配置这两台机器通过串口通信调试。
客户机如果要支持驱动的源码级调试需要将驱动程序的符号表加载的客户机的调试器中。
本文用的vmware虚拟机需要将目标机和客户机同时安装在虚拟机中。
由于在文章中会包含客户机和目标机的操作过程和调试过程,本文中会使用绿框表示客户机相关操作,使用红框表示目标机上的相关操作。
by @技术头条 2017-03-14 18:55 查看详情
2017年值得关注的3个JavaScript库 (www.css88.com)
唷,2016结束了! 这一年对于世界和JavaScript领域来说都是疯狂的一年。 无数新的令人印象深刻的库和框架涌现,你可能不需要 JavaScript 展示了一些模式,提出了使用 JavaScript 的一些问题,和一张Nolan Lawson谈前端的幻灯片引起了业内牛人的一些骚动和响应,像 Jeremy Keith 和 Christian Heilmann ,NoLan总把这些讨论结成了一篇文章。我开始认为用”疯狂”用来描述这一年有点儿低调了,2016是发神经了。

这一年也包括JavaScript疲劳。许多开发人员正在经历JavaScript的生态系统疲劳,因为需要大量的工具和配置来设置一个“现代化”的JavaScript项目。关于这一点,许多开发人员分享了他们的想法,更多”JavaScript很累很累”类似的文章出现。

为了帮助你和我能在晚上睡个安稳觉,我整理了一个前端开发列表,包含的3个有前途的通用库/框架。
by @技术头条 2017-03-12 18:12 查看详情
Cgroup – Linux的IO资源隔离 (liwei.life)
跟内存管理那部分复杂度类似,IO的资源隔离要讲清楚也是比较麻烦的。这部分内容都是这样,配置起来简单,但是要理解清楚确没那么简单。这次是跟Linux内核的IO实现有关系。对于IO的速度限制,实现思路跟CPU和内存都不一样。CPU是针对进程占用时间的比例限制,内存是空间限制,而当我们讨论IO资源隔离的时候,实际上有两个资源需要考虑,一个是空间,另一个是速度。对于空间来说,这个很简单,大不了分区就是了。现实手段中,分区、LVM、磁盘配额、目录配额等等,不同的分区管理方式,不同的文件系统都给出了很多不同的解决方案。所以,空间的限制实际上不是cgroup要解决的问题,那就是说,我们在这里要解决的问题是:如何进行IO数据传输的速度限制。

限速这件事情,现实中有很多模型、算法去解决这个问题。比如,如果我们想控制高速公路上的汽车单位时间通过率,就让收费站每隔固定时间周期只允许通过固定个数的车就好了。这是一种非常有效的控制手段--漏斗算法。现实中这种算法可能在特定情况下会造成资源浪费以及用户的体验不好,于是又演化出令牌桶算法。这里我们不去详细分析这些算法,但是我们要知道,对io的限速基本是一个漏斗算法的限速效果。无论如何,这种限速都要有个“收费站”这样的设施来执行限速,那么对于Linux的IO体系来说,这个”收费站”建在哪里呢?
by @技术头条 2017-03-12 00:06 查看详情
史上最简单的Scala for推导教程 (growthprogrammer.com)
Scala 的 for 语法,本质上就是语法糖。并且十分简单,简单到简短的一篇文章,就可以说清楚。

Scala 中的 for 语句,都是帮你转换成类似 foreach、 map、 flatMap、 withFilter、 filter 之类的语法。并且整个转化过程是递归的,容易理解的。

看完下面是几个例子,你就能立马掌握。这几个例子,是结合了 Scala 官方的yield文档 改进过来的。

第一个例子,转换成 foreach

for(x <- c1) {...}
会被scalac翻译成

c1.foreach(x => {...})
注意,没有出现 yield 关键字。

再来一个:

for(x <- c1; y <- c2) {...}
会展开成:

c1.foreach(x => for(y <- c2) {...})
然后 scalac会再针对里面的 for 再进行转换,直到所有的 for 被转换完。

第二个例子,先 flatMap后 map

for(x <- c1) yield {...}
会被 scalac翻译成

c1.map(x => {...})
注意,这里出现了 yield关键字。

再来一个:

for(x <- c1; y <- c2) yield {...}

会展开成:

c1.flatMap(x => for(y <- c2) yield {...})

然后再展开成

c1.flatMap(x => c2.map( y => {...}))

注意这里多了一个 yield 关键字,所以会用 flatMap、 map 而不用 foreach。

并且,前面的都使用 forMap(比如 c1),最后面使用 map(比如 c2)。

好了,有无 yield的区别讲完了,这也是最重要的区别了,剩下的都很简单,而且不管有无 yield,概念都一样。

接着往下。

第三个例子,尝试 withFilter ,不行再 filter

for(x <- c; if cond) yield {...}
会翻译成

c.withFilter(x => cond).map(x => {...})
如果 c 没有 withFilter 方法,就使用 filter 方法:

c.filter(x => cond).map(x => {...})
第四个例子,加入其它值

for(x <- c; y = ...) yield {...}
会变成

c.map(x => (x, ...)).map((x,y) => {...})
结束

好了,scala 的 for 规则就结束了,就是这么简单。你肯定能记住。
by @技术头条 2017-03-12 00:06 查看详情