原力的黑暗面

2018-01-01 • 个人情感

在经典电影《星球大战》中,极具武士天赋的天行者因为在绝地长老院快速提升地位的不顺、寄希望于黑暗原力能够拯救自己的爱人而倒向了黑暗原力,最终毁了自己本可能辉煌的绝地武士生涯。

我们在工作和生活中,可能因为他人的原因而有诸多这样那样的不顺而产生非常大的情绪,情绪一旦释放,伤人亦伤己,伤人一时心中快,伤己形象被破坏。

在这个社会中,形形色色的人一起组成了团队和集体,我们无法强求每个人把事情都做得尽善尽美,对别人的不足要持多容忍的态度,即使心中非常不快或者不满意也要对人保持尊重、保持耐心,团结所有可能的力量,才能组成一个成功而有战斗力的团队,才有可能成为领导团队的人。

情绪管理和原力是一样的,皆有两面。情绪管理做得好可能促使你成为众人敬仰的一代绝地武士,做得不好滑落到黑暗面则可能成为众矢之的寸步难行难成大事。

从云计算发展路径看人工智能的短期发展

2017-10-02 • 业界评论

近来,人工智能技术越来越多地应用到我们的常见生活场景,逐渐成为当下最热门最受关注的技术。不少人的想象无边无际,认为人工智能可能产生达到甚至远远超过人类认知和智慧水平的机器。在遥远的未来,人工智能能够发展到怎样的水平仅作预言或预测无可厚非但现在还难以下结论。当下,最重要的还是要看清人工智能短期发展的趋势和前景。

我们不妨回顾下从云计算的提出到现在云计算行业发展的情况。在2010年的IT领袖峰会上,BAT三家的李马马三人对云计算分别发表了个人的看法,这段视频时常被人拿出来在社交媒体上发一发。李彦宏认为云计算是新瓶装旧酒,本质是客户端和服务端间关系的变化,对于某些大规模的分布式的网络应用更加适宜,传统应用上云并不是理想的选择,要改变的东西太多不太现实。马化腾认为很多应用服务像水电一样要通过云的方式来实现为时过早,大概还需要千百年才行。马云则认为在自己业务发展过程中有很多值得分享给他人的东西,能够促进别人的发展,相信云计算能够做这样的事情,并且可能是爆发性的变革。很多人对三人观点的看法是马云的观点领先于李彦宏和马化腾,但我并不这么看。李彦宏看的是云计算发展最初期的样子,卖网络服务器做托管没什么价值,云上卖服务又让人难以接受。马化腾看的是云计算中长期的发展,像水电一样即取即用,现在来看还太远。马云则仅仅是从理论层面上认为云计算的一些价值值得挖掘。李彦宏和马化腾二人都是从技术的角度看问题,其实观点都没有错,只是二人没看清云计算的整个发展路线,忽略了云计算所能带来的好处。今天阿里云的发展大家有目共睹,但是真可以说是发展到水电煤一样的水平,不仅仅对B同样对C也可以实现计算能力和衍生服务的共享了吗?其实仍然没有完全实现,所以马化腾当时认为短期实现不了是没错的,现在还是远没达到如我们理想预期中那样的水平。最初,也还不是先做弹性服务器托管,后来数据存储、中间件、安全才逐渐在云上服务于客户,慢慢地更多的具体性的行业性的服务才通过云来提供。云计算发展到今天,我们就可以看到,云计算所提供的是集约化的专业化的服务,提升效率,降低成本,价值体现出来,人们对云计算逐渐认可了,业绩也就自然而然有了。云计算的发展远还没有到头,现在依然还只能说是云计算的初级阶段,也许正在发展中级阶段,对B业务的大发展阶段,未来更通用更广谱更便利的应用依然还没有到来。

再回头来看人工智能,其并非全新的概念,只是最近伴随着机器学习尤其是深度学习的热潮,AI又来了新的一波,而且更多地应用在常见场景中了。关于人工智能,我认为可以分为近的和远的两个目标,近的是希望借鉴人类的智能行为研制更好的工具以减轻人类智力劳动,要实现弱人工智能或者称之为服务型人工智能,远的这是希望研制出达到甚至超越人类智慧水平的人造物,具有自我认知和学习能力,要实现强人工智能。国内的人工智能领域权威周志华老师认为主流人工智能学界的努力和目前所取得的成果都是朝向弱人工智能,强人工智能没有可靠的研究路径和扎实的研究而且我们也不应该去研究它。而未来学家雷·库兹韦尔则认为逆向人脑也许是可能的,未来可能出现人机结合的更高级物种,更强的人工智能。无论理论界如何争论,大众观点靠谱与否,这都不影响我们对短期发展趋势的判断。和云计算的发展一样,罗马非一日可建成,人工智能也是不可能在短期内就实现彻底的突破的,尤其是在强人工智能领域,一切都会循序渐进。现今在实现相对高级的人工智能技术之前,我们应该理性而简单地看待人工智能技术的发展。现在人工智能技术的突破仍然是在特定类型的行为上,比如在图像识别、语音识别、机器翻译、自动推理、游戏等等方面,人工智能或者说机器学习都取得了不错的成果,未来这种特定领域的技术还会不断演进,产品化做得越来越好,带动某些领域产生不错的商业产品和企业。人工智能技术的工程化、平台化和通用化将是其发展水平的一个重要里程碑,将人工智能所使用的算法、模型等抽象工程化,将自然语言处理、图像识别等特定领域技术标准化和接口化,能够供非人工智能领域的专业技术人员在平台上方便地基于云使用某种技术来完成某种功能,越来越多的人具备基本的人工智能技术应用水平,才能让人工智能给我们的生活、商业领域带来真正广泛的价值。未来几年,相信无论是学者还是工程师,都会继续在这样的思路和短期愿景下,本着严谨的态度继续改进我们的人工智能技术。同时,非人工智能专业科研和工程人员也应该关注和学习基本的人工智能技术,将人工智能作为工具广泛地应用在各类业务场景来取得更好的商业业绩会是以后对人员基本素质的要求。另外,从最近的招聘情况来看,很多刚刚了解机器学习一点基本概念的学生就敢于积极申请人工智能的职位,这是不太正确的态度,想要从事专业的人工智能技术还是需要比较深入的研究和基础的,就像申请普通业务功能研发职位一样也要求与之相匹配的能力,不分青红皂白就一拥而上在一定程度上反映了很多人的浮躁。

无论对哪种新出现的技术潮流,保持客观理性看待,顺势而为,才是正确的态度。

JavaWeb开发中的字符编码问题的直截了当解决方案

2017-01-11 • 技术文章

解决方案

从容器字符编码配置、响应头设置、Meta字符集设置全部统一为UTF-8,不要通过自己写代码做层层转码。

容器:URI_ENCODING=UTF-8,USE_BODY_ENCODING_FOR_QUERY_STRING=true

ContentType:text/html; charset=UTF-8

Meta:charset=UTF-8

当然,对于用户可以手动拼参数的场景,比如定制百度搜索,那么应该具备自动探测编码的能力,而不是仅固定支持,百度可以自动识别queryString的编码是个很好的范例。

备注

HttpServletRequest.setCharacterEncoding方法仅仅只适用于设置POST提交的RequestBody部分的数据的编码而不是设置GET提交的queryString的编码。

HttpServletRequest.getPathInfo和getParameter返回的结果是由Servlet服务器解码过的。

HttpServletRequest.getRequestURI返回的字符串没有被Servlet服务器解码过。

编码随谈:加号与空格

URI把允许出现的字符分为保留未保留。百分号编码一个保留字符,其实是在这个字符的16进制ASCII值前面加上转义字符%,未保留字符不需要被百分号编码。对于那些不在保留字符和未保留字符范围内的字符,先转换为UTF-8字节序列,然后对其字节值使用百分号编码。在正常的编码解码流程中,编码的时候先把加号替换为%2B,然后把空格替换为加号;解码的时候先把加号替换为空格,再把%2B替换为加号,就是正常的。但是在已经urlencoded的内容中如果使用这二者不慎,就很有可能造成编解码不正确的问题了。

SSH会话保持基本设置

2016-03-27 • 技术文章

配置文件

1
2
/etc/ssh/ssh_config(Linux)
~/.ssh/config(MacOS)

新窗口连接同一服务器免重登

1
2
3
host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

最后一行表示在指定目录下生成sock文件,保存会话记录。

避免SSH连接断开

为避免packet_write_wait: Connection to [IP]: Broken pipe连接断开的情况,可通过以下配置。

1. 客户端实现(其中55代表定时向SSH Server发送心跳的间隔秒数,下同):

1
2
host *
ServerAliveInterval 55

2. 命令实现:

1
ssh -o ServerAliveInterval=55 user@sshserver

3. 也可以在服务端sshd_config中配置,避免客户端单独配置:

1
ClientAliveInterval 55

操作系统虚拟化与Linux命名空间

2015-11-22 • 技术文章

虚拟化的本质需求来源于任务的隔离,也就是资源的隔离。所以,很多时候我们不是要在OS上虚拟出一个独立的OS,而是希望让虚拟机共享操作系统内核而又保持隔离性。

chroot

诞生于1979年的chroot是资源隔离的一种方案,chroot使一个进程把某个特定目录作为根目录,所有文件系统操作都被限定在该目录里进行。

但是chroot仅仅做到了文件系统层面的隔离是远远不够的,我们希望对进程、网络等各种资源进行更深层次的隔离而且希望能够实现对这些资源的审计。

Linux命名空间

Linux的命名空间机制为实现基于容器的虚拟化技术提供了很好的基础。

命名空间建立了系统的不同视图,只使用一个内核在一台物理机上运作,将全局资源都通过命名空间抽象起来,每个命名空间中的资源对其它命名空间是透明的。LXC就是利用这一特性实现了资源的隔离,由于没有多余的一层操作系统内核,容器比虚拟机更加轻量,启动更快,内存开销、调度开销也更小,更重要的是访问磁盘等IO设备不需要经过虚拟化层,没有性能损失。

当我们用fork或clone系统调用创建新进程时,有特定的标志位可以控制是与父进程共享命名空间,还是建立新的命名空间。命名空间的实现需要两个部分:每个子系统的命名空间结构,将此前所有的全局组件包装到命名空间中;将给定进程关联到所属各个命名空间的机制。子系统此前的全局属性现在封装到命名空间中,每个进程关联到一个选定的命名空间。每个可以感知命名空间的内核子系统都必须提供一个数据结构,将所有通过命名空间形式提供的对象集中起来。nsproxy结构体用于汇集指向特定于子系统的命名空间包装器的指针。

1
2
3
4
5
6
7
8
9
10
struct nsproxy {
    // 注释仅为匹配该行对应命名空间的标志位注解,不是本处引用代码的说明
    atomic_t count; 
    struct uts_namespace *uts_ns;   // 标志位CLONE_NEWUTS
    struct ipc_namespace *ipc_ns;   // 标志位CLONE_NEWIPC
    struct mnt_namespace *mnt_ns;   // 标志位CLONE_NEWNS
    struct pid_namespace *pid_ns;   // 标志位CLONE_NEWPID
    struct user_namespace *user_ns;
    struct net *net_ns; 
};

uts_namespace包含了运行内核的名称、版本、底层体系结构类型等信息(UTS即UNIX Timesharing System);ipc_namespace包含所有与进程间通信(IPC)有关的信息;mnt_namespace包含了文件系统的视图信息;pid_namespace报行了进程ID相关的信息;user_namespace包含了用于限制每个用户资源使用的信息;net_ns包含所有网络相关的命名空间参数;count是引用计数。

clone(child_exec, child_stack + STACKSIZE, clone_flags, &args)其中的clone_flags即为设置不同命名空间的标志位的或运算结果。如同时设定CLONE_NEWPID和CLONE_NEWIPC,那么不同命名空间的进程彼此不可见,也不能互相通信,这样就实现了进程间的隔离;CLONE_NEWUTS和CLONE_NEWNET一起使用,可以虚拟出一个有独立主机名和网络空间的环境,就跟网络上一台独立的主机一样。

以上所有标志位都可以一起使用,为进程提供了一个独立的运行环境。LXC就是通过clone时设定这些flag,为进程创建一个有独立PID、IPC、FS、Network、UTS空间的容器。一个容器就是一个虚拟的运行环境,对容器内的进程是透明的,它会以为自己是直接在一个系统上运行的。

几种其它虚拟化方案

OpenVZ也是Linux内核里实现操作系统级虚拟化的解决方案之一,但相对LXC,可以分辨子系统中内存和磁盘的配额分配情况,可进行独立审计,且支持检查点、热迁移等更多特性,缺点是基于非常老的Linux内核设计,对新特性支持差。

Docker如今大红大紫,它将基础运行环境和依赖都打包在镜像中,且镜像是层次化的,基于增量修改(基于AUFS实现,基础目录A和增量目录B合并为目录C,冲突时以B为准,修改C写回B),低开销实现了版本控制和分发,软件运行在独立容器中避免冲突。Docker很好地解决了依赖与资源冲突的问题,大大降低了运维成本。