Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 11804 articles
Browse latest View live

在三家互联网巨头的年终视频里,我们看到了怎样的2015?

$
0
0

在三家互联网巨头的年终视频里,我们看到了怎样的2015?

每到年底,YouTube 和 Google 都会发布总结过去一年的创意视频,而今年,Facebook 也加入了这一行列。一起通过他们的视野,重温这颗星球的2015年。

来源: 睿士

Google:A Year in Search “2015年,我们提出的问题,反映了我们是怎样的人。”

在 Google 的年度视频里,他们用搜索框里出现的9个问题串联起了这一整年的热门事件。

Google 从来都不是一家苦大仇深的公司,但在纷扰不断的2015年,这个星球上发生过的苦难、灾祸和冲突依然在他们的年度回顾中占据了大量篇幅。

值得注意的是,Google 在呈现这些不快的事件时,所采取的都是“如何解决?我们能做什么?”的视角。这是一种十分积极而正面的态度,也是我们在面对此类事件是最应提倡的反应。作为一个为“解决问题”而存在的网站,Google 在这个短短的视频中作出了最好的示范。

当然,这一年的地球上不只有冲突,在很多争执已久的议题上,Google 的搜索框里都发生了积极的反馈。

比如在今年热议的女权问题上,有人向 Google 问了一个这样的问题 :为什么女性不能成为游骑兵?半年前,极具话题的变性勇士 Caitlyn Jenner 使更多人开始关注这个特殊的群体,于是有人开始在 Google 上提出这样的问题 :你是天生的跨性别人士吗?而这些话题归根结底,讨论的都是人类社会所固有的多样性。不同种族,不同宗教,不同性别取向的社群必然会有不同的观点和认知;就连一条裙子的颜色,也能引发一场互联网大战 :这条裙子是什么颜色?

  Facebook:Year in Review

Google 的年度视频是他们的传统项目,Facebook 则是头一年做。作为一家社交网站,他们的年度盘点显得更为感性和情绪化。

与 Google 不同,在那些热门的公共事件上,Facebook 所关注的不是事后的答疑解惑,而是在事件发生的当下,用户通过发文、表情、评论和点赞所表达的最直接的情绪。

比如尼泊尔地震,在社交网络上,各国志愿者在灾区的援助行为才是最容易引起转发的“正能量”。而在查理周刊事件中,如火如荼的游行不止发生在巴黎街头,也出现在了每位 Facebook 用户的 timeline 上。同样在巴黎,不久前的恐怖袭击后,#PrayforParis 和红白蓝三色在社交媒体上刷屏了数日。

但这一年的无数个悲情的告别中,最令 Facebook  用户心碎的还是 Jon Snow 的“横死”。但据可靠消息,这位《权力的游戏》中的人气王并没有死透。明年4月复活时,Facebook 上肯定又会热闹一阵子。

YouTube:Rewind 2015

视频做得最有诚意的其实还是 Youtube,他们找来100多位演员,把2015年所有的热门视频都统一风格翻拍了一遍。

比如火了一整年“百年时尚”系列,从100年来的妆容,到一百年来的发型、泳装、胡须,以及各种配饰,YouTube 用短短数秒将它们一网打尽。至于那条蓝黑/白金裙,YouTube 拍了一个今年最下成本的恶搞。如果你看过《疯狂麦克斯》,一定能认出这位吉他喷火的小哥。如果你对欧美这一年的娱乐事件足够了解,相信能在这个视频里找到更多彩蛋。

但怎么说呢,Youtube 这个年度视频的“观看门槛”其实还是有点高。与 Google 和 Facebook 注重情怀与时事不同,YouTube 这一次的年度回顾更多地是面向它的用户本身。如果你整天泡在 Youtube 上看热门视频,这个大混剪里的各种梗一定能让你如数家珍;反之,这一切就只是墙外的热闹而已。

互联网上的信息是速朽的,当我们现在聊起“查理周刊”之类的事件时,潜意识里会觉得那已经是多年前的旧闻了;而事实上,那不过才发生在2015年的年初。在这3支视频所回顾的那些事件中,你记得的有哪些?点过赞的又有哪些?


[原]MySQL批量快速写

$
0
0

MySQL写速度确实不敢恭维,但是通过MySQL自带的一些功能,可以提高其写的执行效率。

1、将insert into tab(col1,col2) value(value1,value2)的单条写修改为insert into tab(col1,col2) values(value1,value2),(value3,value4),...(valueN,valueN+1)批量写

2、如果一次需要写入上百万的数据,可以先将数据安装表字段,写成文件,然后LOAD DATA INFILE "./data.txt" INTO TABLE tab;直接导入,同时可以在导入开始前关闭表索引,导入成功之后,再开启索引,

3、如果上面两个方案还是觉得慢??那就来大招了,在写入数据钱,先将查看变量innodb_flush_log_at_trx_commit是否为0,如果不是则将变量innodb_flush_log_at_trx_commit修改为0,写入完成之后,在恢复到原来的值 ,该参数表示将MySQl产生的日志写入到磁盘的策略,0表示等待系统每秒写一次,1,表示每次事务都写,同时还要刷新到硬盘,2,表示每次都写,但是不刷新到硬盘,等待操作系统自己刷新

作者:yangfei001 发表于2015/12/17 15:38:49 原文链接
阅读:7 评论:0 查看评论

2015 年最简单粗暴的 PC 选购指南

$
0
0

2015 年是微软 Windows 操作系统和运行 Windows 系统的笔记本电脑的转折年——这一年,Windows 系统和运行这一系统的 PC 完成了华丽的转身,丑陋不再是二位的代名词。

首先,微软公司于 7 月下旬发布了 Windows 10 操作系统,这一系统是继辉煌巨作 Windows XP 之后,最好的操作系统。Win 10 修正了 Win 8 饱受诟病的一系列问题,提升了或任务操作的体验和性能,更快的搜索显著提升了用户的工作效率,收悉的操作方式使用户的学习成本显著降低。

其次,运行 Windows 系统的笔记本电脑发生了颇具里程碑意义的改变。为了「超越」苹果 MacBook 在设计、人体工学以及电池续航方面的独到之处,各大笔记本尝试追随和尝试了多年后,戴尔、惠普以及微软终于在 2015 年全面爆发。现在,你可以购买一台非常出色的、运行 Windows 系统的笔记本电脑——它可以满足一天的超长续航需求,以及一些无需键盘操作的混合 PC。

随着假期的临近,一大批搭载 Intel 全新处理器的笔记本不断上市,是时候买一款能够与苹果的 MacBook 媲美、运行 Windows 系统的笔记本电脑了。但是哪一款?在测试特 20 款笔记本电脑,评估了这些电脑的续航能力、整体性能、触控板以及键盘的用户体验之后,笔者给出如下建议:

机皇:戴尔 XPS 13(Dell XPS 13,售价 800 美元起)

多年来,笔者一直认为,不论你是 Mac 还是 Windows 系统用户,苹果 MacBook Air 是最好的笔记本,没有之一。这款苹果的经典之作的续航能力为 10 个小时,触控板的性能已经爆表,没有任何一台笔记本可以比肩,即使是安装 Windows,操作体验也非常赞。然而今年,笔者认为有一款产品可以与 MacBook Air 相媲美——Dell XPS 13。

相比 MacBook Air,Dell XPS 13 拥有较小的机身尺寸,较高的屏幕分辨率,然而续航时间和苹果的 MacBook Air 一样。在笔者进行的电池测试中,这款非触摸屏、1080p 分辨率型号的笔记本续航时间达到 10.5 个小时。配备 QHD 高清屏的型号,续航时间将减少 2 个小时,但也达到了惊人的 8 个小时。笔者测试的其他同类型的电脑,比如惠普 Spectre X360,联想 Yoga 900,以及宏碁 Zenbook UX303U 续航时间仅有 7 个小时,超高清的分辨率屏幕是造成续航不足的罪魁祸首。

在使用过程中,Dell XPS 13 的触控板表现非常出色,大大超出预期。这款触控板灵敏度更高,配合 Win 10 触控板软件,双指屏幕滚动以及其它手势操作的用户体验与 MacBook Air 的触控板没有太大的区别。

超窄边框是 XPS 的特色,因而虽然 2.7 磅的重量,但外形看起来要比其他同类产品小巧很多。然而与同价位的电脑相比,XPS 不具备可翻转的屏幕。如果需要一款既能够使用键盘,又能够翻转屏幕收起键盘,那么惠普推出的 Spectre x360 是非常不错的选择,售价 900 美元起,其电池的续航能力比其它变形本优秀许多。

性能之王:Dell XPS 15(1000 美元起),Surface Book(1500 美元起)

对于大多数多任务操作,轻度图片和视频编辑的用户而言,XPS 13 提供了足够的马力。但对于那些注重便携性和显卡性能,以及强大性能集于一身的用户而言,Surface Book 或 XPS 15 是相当不错的选择。

2015 年,微软推出的第一款真正意义上的笔记本,可以说从做工方面已经向苹果看齐。虽然「动态支点铰链」并非是每个人的所爱,然而铝合金材质,3000x2000 像素的超高清屏幕,重新设计的悬浮式键盘,反应更加灵敏的触控板,以及长达 9.5 小时的续航时间是大部分用户的所爱。此外,Surface Book 是市面上少有支持人脸识别系统登录系统的设备。然而这款设备的最大痛点是其 1500 美元的起售价!仔细想一下,很少有人会把它当做平板使用,因为单独作为平板使用时,起续航能力只有 2 个小时;而用户所花费的大部分钱仅仅是购买了一个可拆卸的触摸屏平板。

如果用户需要强大的处理器,更大的屏幕,Dell XPS 15 定是不二之选。与 XPS 13 一脉相承,出色的触控板、键盘以及外观设计,但 15.6 英寸的屏幕,以及可以自选配备最强大的组件。在测试中,笔者使用的是一款配备 4K 屏幕,英伟达显卡,8GB 内存,以及 i7 处理器(售价为 2099 美元)。由于配备 4K 显示屏的关系,该机的电池续航仅为 4.5 小时,然而如果选择 1080p 屏幕的基础款,续航时间将大大提升。

性价比之王:华硕 Zenbook UX305(售价 600 美元起)

笔者一再强调,购买 Windows 笔记本,最好不要购买售价 600 美元以下的产品。这些产品的内部工艺和人体工学设计非常差,在使用过程中的体验非常糟糕。在 600 美元这个档位,华硕 Zenbook UX305C 是目前市面上最具性价比的一款机器。

华硕 UX 305C 配备了一块 1080p 的高清显示屏,触控板的体验非常灵敏,8GB 内存,256GB 固态硬盘。虽然处理器为英特尔 Core M 系列处理器,但是应对日常办公、娱乐还是绰绰有余。

如果你打算选购一款 700 美元以下的笔记本,还可以考虑一下戴尔 Inspiron 13 700。这款笔记本配备了可翻转式触摸屏,如果选择 Core i3 处理器,4GB 内存的配置,售价大约在 600 美元。

脓肿羞涩:东芝 Chromebook 2(售价 230 美元起)

如果你的预算在 400 美元以下,那么你的选择真的不多,最适合你的 Windows 笔记本应该是一款 Chromebook!说实在的,400 美元甚至以下的 Windows 笔记本会让你有自杀的倾向。

售价 200 美元的联想 IdeaPad 100S,键盘非常难用,浏览网页时随时都有可能奔溃。售价 250 美元的华硕 EeeBook X205TA,表现稍微好一点,然而过于紧凑的键盘以及触摸板,使手腕处非常不舒服,严重不符合人体工学设计。

如果你需要一款具备浏览网页、收发邮件等基本功能的笔记本,而你的预算真的很少很少的话,运行谷歌 Chrome OS 的笔记本是最好的选择。Chrome OS 对于硬件的要求并不如 Windows 高,因而可以节省很大部分开支,即便是配备很好的显示屏,出色的外观设计,这样的产品售价也不会很高。长达 7 小时的续航时间,售价仅为 230 美元,13 寸东芝 Chromebook 2 是最棒的选择。

变形本不考虑?

配备键盘的平板电脑,比如 Surface 不值得考虑吗?

在考虑购买此类产品时,请先闭上你的眼睛,认真考虑一些你打算如何使用这些产品。如果你平时 90% 的时间都需要用到键盘,那么你最好购买一台常规的笔记本电脑,如果预算允许,你可以购买一台配备触摸屏的笔记本电脑。戴尔 XPS 13 系列就是非常不错的选择。如果你打算记笔记,看视屏,以及浏览网页,不希望产品过于沉重,并且有非常不错的续航和便携能力,那么这类变形本是非常不错的选择。

在笔者的测试中,微软自家推出的 Surface Pro 4 是最棒的选择。与惠普 Spectre x2、戴尔 XPS 12 相比,Surface Pro 4 是一款最轻,最便携的产品。出众的外观设计,便携式支架,高清的分辨率,流畅自如的手写笔,丰富的接口等都使这款设备成为出差、娱乐用户的首选。在测试中,Surface Pro 的续航时间达到了 6 个小时,比惠普和戴尔的都要出色。然而与 iPad Air 2 和 iPad Pro 的 10 个小时的续航时间相比,Surface Pro 4 的续航也不算出众。但由于运行 Windows 系统,在办公和处理公务方面的兼容性方面体现出诸多优势,而且可以实现苹果 iPad 系列产品无法替代的功能。

Windows 阵营一直没有非常出众的平板电脑,续航能力差,触摸式应用程序用户体验差是最主要的原因。然而随着 Windows 10 的发布,2016 年或许会有许多令人赞叹的产品出现。

文章来源: WSJ,由 TECH2IPO / 创见 孙朝 编译,首发于创见(http://tech2ipo.com),转载请注明出处。

Linux入侵检测基础

$
0
0

0x00 审计命令


在linux中有5个用于审计的命令:

  • last:这个命令可用于查看我们系统的成功登录、关机、重启等情况;这个命令就是将/var/log/wtmp文件格式化输出。
  • lastb:这个命令用于查看登录失败的情况;这个命令就是将/var/log/btmp文件格式化输出。
  • lastlog:这个命令用于查看用户上一次的登录情况;这个命令就是将/var/log/lastlog文件格式化输出。
  • who:这个命令用户查看当前登录系统的情况;这个命令就是将/var/log/utmp文件格式化输出。
  • w:与who命令一致。

关于它们的使用:man last,last与lastb命令使用方法类似:

last [-R] [-num] [ -n num ] [-adFiowx] [ -f file ] [ -t YYYYMMDDHHMMSS ] [name...]  [tty...]
lastb [-R] [-num] [ -n num ] [ -f file ] [-adFiowx] [name...]  [tty...]
who [OPTION]... [ FILE | ARG1 ARG2 ]

参数说明:

  1. 查看系统登录情况

    last:不带任何参数,显示系统的登录以及重启情况

    p1

  2. 只针对关机/重启

    使用 -x参数可以针对不同的情况进行查看

    p2

  3. 只针对登录

    使用 -d参数,并且参数后不用跟任何选项

    p3

  4. 显示错误的登录信息

    lastb

  5. 查看当前登录情况

    who、w

0x01 日志查看


在Linux系统中,有三类主要的日志子系统:

  • 连接时间日志: 由多个程序执行,把记录写入到/var/log/wtmp和/var/run/utmp,login等程序会更新wtmp和utmp文件,使系统管理员能够跟踪谁在何时登录到系统。(utmp、wtmp日志文件是多数Linux日志子系统的关键,它保存了用户登录进入和退出的记录。有关当前登录用户的信息记录在文件utmp中; 登录进入和退出记录在文件wtmp中; 数据交换、关机以及重启的机器信息也都记录在wtmp文件中。所有的记录都包含时间戳。)
  • 进程统计: 由系统内核执行,当一个进程终止时,为每个进程往进程统计文件(pacct或acct)中写一个记录。进程统计的目的是为系统中的基本服务提供命令使用统计。
  • 错误日志: 由syslogd(8)守护程序执行,各种系统守护进程、用户程序和内核通过syslogd(3)守护程序向文件/var/log/messages报告值得注意的事件。另外有许多Unix程序创建日志。像HTTP和FTP这样提供网络服务的服务器也保持详细的日志。

日志目录: /var/log(默认目录)

  1. 查看进程日志

    cat /var/log/messages

    p4

  2. 查看服务日志

    cat /var/log/maillog

    p5

0x02 用户查看


Linux不同的用户,有不同的操作权限,但是所有用户都会在/etc/passwd /etc/shadow /etc/group /etc/group- 文件中记录;

  1. 查看详细

    • less /etc/passwd:查看是否有新增用户
    • grep :0 /etc/passwd:查看是否有特权用户(root权限用户)
    • ls -l /etc/passwd:查看passwd最后修改时间
    • awk -F: '$3==0 {print $1}' /etc/passwd:查看是否存在特权用户
    • awk -F: 'length($2)==0 {print $1}' /etc/shadow:查看是否存在空口令用户

    注:linux设置空口令:passwd -d username

    p6

0x03 进程查看


  1. 普通进程查看

    进程中我们一般使用ps来查看进程;man ps

    • ps -aux:查看进程
    • lsof -p pid:查看进程所打开的端口及文件
  2. 检查隐藏进程

    • ps -ef | awk '{print }' | sort -n | uniq >1
    • ls /proc | sort -n |uniq >2
    • diff 1 2

    注:以上3个步骤为检查隐藏进程

0x04 其他检查


  1. 检查文件

    • find / -uid 0 -print:查找特权用户文件
    • find / -size +10000k -print:查找大于10000k的文件
    • find / -name "..." -prin:查找用户名为...的文件
    • find / -name core -exec ls -l {} \;:查找core文件,并列出详细信息
    • md5sum -b filename:查看文件的md5值
    • rpm -qf /bin/ls:检查文件的完整性(还有其它/bin目录下的文件)
  2. 检查网络

    • ip link | grep PROMISC:正常网卡不应该存在promisc,如果存在可能有sniffer
    • lsof -i
    • netstat -nap:查看不正常端口
    • arp -a:查看arp记录是否正常
  3. 计划任务

    • crontab -u root -l:查看root用户的计划任务
    • cat /etc/crontab
    • ls -l /etc/cron.*:查看cron文件是变化的详细
    • ls /var/spool/cron/
  4. 检查后门

    对于linux的后门检查,网络上有一些公开的工具,但是在不使用这些工具的前提时,我们可以通过一些命令来获取一些信息。

    首先就是检测计划任务,可以参考上面;
    第二:查看ssh永久链接文件:vim $HOME/.ssh/authorized_keys
    第三:lsmod:检查内核模块
    第四:chkconfig --list/systemctl list-units --type=service:检查自启
    第五:服务后门/异常端口(是否存在shell反弹或监听)
    其它:
    ls /etc/rc.d
    ls /etc/rc3.d

滥用Accessibility service自动安装应用

$
0
0

Author:逆巴@阿里移动安全

0x00 恶意应用简介


近年许多的android市场实现免root安装应用,也就是下载完成立即自动安装,而黑产界也同样利用该技术在进行恶意推广,静默安装。最近拦截到大量恶意应用利用系统AccessibilityService静默安装应用。一旦恶意的Accessibility服务被激活,恶意应用将弹出广告,即使用户关闭弹出的广告该应用程序也会在后台下载,随后自动安装推广的恶意应用。

0x01 AccessibilityService介绍:


AccessibilityService作用:

Android Accessibility用于那些由于视力、听力或其它身体原因导致不能方便使用Android智能手机的用户,Android提供了Accessibility功能和服务帮助这些用户更加简单地操作设备。开发者可以搭建自己的Accessibility服务,这可以加强应用的可用性。开启AccessibilityService后应用通过它能实时地获取当前操作应用的窗口元素信息,并能够双向交互,既能获取用户的输入,也能对窗口元素进行操作,比如点击按钮。

AccessibilityService的使用场景:

Android应用市场使用android Accessibility来免root安装应用;近来火热的抢红包应用也用使用AccessibilityService自动抢红包。

0x02 恶意应用分析


我们监测到一款名为“WiFi密码查看器(增强版)”的应用滥用AccessibilityService。应用启动后诱导用户开启“WIFI信号增强服”,其实就是开启恶意应用自身的AccessibilityService;以查看WIFI密码让恶意应用获得root权限,而这一切都是为该恶意自动安装做铺垫。下图是该应用运行图

p1p2图应用启动与引导开启wifi信号增强界面

应用启动后会引导用户开启WIFI信号增强服务。应用跳转到ACCESSIBILITY_SETTINGS界面,提示用户若要增强Wifi信号强度,请开启WIFI信号增强服务。用户启用恶意应用的该服务之后,手机将疯狂下载该应用云端准备的应用包,并且在手机上自动安装运行。

p3p4图启动Accessibilty Service界面

以下是恶意代码运行流程

p5图恶意代码云信流程

流程图解析

  1. Wifi_list模块,恶意应用利用wifi信号增强诱导用户开启 Accessiblity Service;查看Wifi密码诱导用户给该应用赋予Root权限。
  2. PushDownLoad模块,该模块由 PushCoreServiceChapingCoreService服务组成,它们利用后台服务上传设备信息,获取待Push的应用包,下载应用包。
  3. 安装模块,恶意应用解析下载成功的包,然后弹出 DialogPushActivity的广告框,非Root利用 AccessilbityService安装,root利用 pm install完成静默安装
  4. daemon模块, daemon是存放在raw目录下的elf文件,它是一个守护进程,保护应用不被杀死。daemon原理是fork出子进程之后,让子进程成为新的会话的领头进程,并与其父进程的会话组和进程组脱离,紧接着就是在子进程中定时去启动java层配置的任务。这里它保证 PushCoreServiceChapingCoreService一直在后台运行。

以下对核心服务 PushCoreService跟踪分析

首先向目标服务器Post设备的imei,wifimac,SerialNumber信息,服务器返回uuid,并记录在 DefaultSharedPreference文件的”uuid”字段

p6图请求服务器获取uuid

上图最后调用 this.m_context.handler.sendEmptyMessage(1),启动线程GetPushThread线程。该线程向 http://api.findzhibo.com/ad/open?appCode=1&appVersion=appVerion请求获取当前应用的“open_status”字段。只有“open_status”字段为True时,云端服务器才会继续运行,否则表示当前应用版本对应的云端关闭。开启状态向 http://api.findzhibo.com/index.php/ad/push,发送post请求,服务器返回待push的应用,写入“cc_push_sp.xml”的push_json字段

p7图云端恶意推广app的push_json

p8图云端请求获取恶意推广应用

上图最后调用 this.m_context.handler.sendEmptyMessage(2),解析push_json字段填充intent,启动 PushDownloadService进行应用下载和恶意广告页面弹出。 PushDownloadService解析appJson,获取下载信息,随后通过handler消息对应用下载安装。

p9图解析appJson,进行下载安装

Handler存在4个msg.what值,‘3’处理下载失败;‘4’下载成功;‘5’弹出DialogPushActivity广告框若开启Accessiblity Service,启动WifiZengQiangService; ‘6’弹出DialogPushActivity广告框,启动恶意推广的应用。 首先发送“4“表示开始后台下载,随后启动下载安装的线程。该线程检查本次推送的应用是否已经被下载到指定目录,sdcard/.wifi_ckq保存下载的应用包以及广告图片,appName经过md5加密。

p10图sdcard目录存放下载的推广应用包

p11图下载恶意推广应用

下载完成后发送对应用静默安装,设备非root发送‘5’,root使用 pm install安装应用随后发送‘6’启动应用。

p12图发送handler安装应用

handler ‘5’,’6’都会启动DialogPushActivity,

p13图启动DialogPushActivity

DialogPushActivity其实就是一个ImageView,用户在触摸该界面后推送的应用将被自动安装

p14p15图DialogPushActivity界面

启动WifiZengQiongService自动安装服务。之前的Ghosh Push,Kemoge等病毒家族,都是先对设备root然后植入推广应用。而该恶意应用的AccessibilityService一旦被启动,随后应用弹出恶意广告界面,即使受害者关闭弹出的广告,该应用程序也会被自动下载,随后成功安装。这个过程是调用系统的packageinstaller,获取安装界面的按钮位置,Accessibility提供的模拟用户点击功能,代替用户自动点击下一步,直到安装结束。下图是弹出的广告图,触碰后即可开始下载安装推广的应用。下图AccessibilityService里唤起安装界面

p16图调用系统packageInstaller

AccessibilityService的onAccessibilityEvent方法不仅处理’com.android.packageinstaller’ 的event,还处理一些安全软件,这样该恶意应用将会完全控制安全软件行为,也就意味着该应用可以自动安装,启动任意app,卸载任意应用,而且利用AccessibilityService控制安全软件进行免杀。

p17图AccessibilityService控制指定应用包

在推广的应用成功安装过后,系统将会发出 “android.intent.action.PACKAGE_ADDED”广播消息,AppListenerReceiver类接受该广播并启动应用。

0x03 总结与建议


到此滥用 AccessibilityService过程分析完毕。该应用已增强WIFI信号诱惑用户启用 Accessibility,以及查看WIFI密码是应用获取root权限。在此提醒用户谨慎给不受信应用开启 AccessibilityService,以免被恶意应用控制;最近火热的抢红包应用也会利用 AccessibilityService,实现自动抢功能,我们已发现黑客利用‘自动抢红包’诱导用户开启 AccessibilityService控制手机,建议用户在安全渠道下载抢红包软件,以免不必要的损失。

Spark生态圈之——Elasticsearch与Solr

$
0
0

搜索引擎选型调研文档

Elasticsearch简介 *

Elasticsearch是一个实时的分布式搜索和分析引擎。它可以帮助你用前所未有的速度去处理大规模数据。

它可以用于全文搜索,结构化搜索以及分析,当然你也可以将这三者进行组合。

Elasticsearch是一个建立在全文搜索引擎 Apache Lucene™ 基础上的搜索引擎,可以说Lucene是当今最先进,最高效的全功能开源搜索引擎框架。

但是Lucene只是一个框架,要充分利用它的功能,需要使用JAVA,并且在程序中集成Lucene。需要很多的学习了解,才能明白它是如何运行的,Lucene确实非常复杂。

Elasticsearch使用Lucene作为内部引擎,但是在使用它做全文搜索时,只需要使用统一开发好的API即可,而不需要了解其背后复杂的Lucene的运行原理。

当然Elasticsearch并不仅仅是Lucene这么简单,它不但包括了全文搜索功能,还可以进行以下工作:

  • 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。

  • 实时分析的分布式搜索引擎。

  • 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。

这么多的功能被集成到一台服务器上,你可以轻松地通过客户端或者任何你喜欢的程序语言与ES的RESTful API进行交流。

Elasticsearch的上手是非常简单的。它附带了很多非常合理的默认值,这让初学者很好地避免一上手就要面对复杂的理论,

它安装好了就可以使用了,用很小的学习成本就可以变得很有生产力。

随着越学越深入,还可以利用Elasticsearch更多高级的功能,整个引擎可以很灵活地进行配置。可以根据自身需求来定制属于自己的Elasticsearch。

使用案例:

  • 维基百科使用Elasticsearch来进行全文搜做并高亮显示关键词,以及提供search-as-you-type、did-you-mean等搜索建议功能。

  • 英国卫报使用Elasticsearch来处理访客日志,以便能将公众对不同文章的反应实时地反馈给各位编辑。

  • StackOverflow将全文搜索与地理位置和相关信息进行结合,以提供more-like-this相关问题的展现。

  • GitHub使用Elasticsearch来检索超过1300亿行代码。

  • 每天,Goldman Sachs使用它来处理5TB数据的索引,还有很多投行使用它来分析股票市场的变动。

但是Elasticsearch并不只是面向大型企业的,它还帮助了很多类似DataDog以及Klout的创业公司进行了功能的扩展。

Elasticsearch的优缺点 **:

优点

  1. Elasticsearch是分布式的。不需要其他组件,分发是实时的,被叫做”Push replication”。
  2. Elasticsearch 完全支持 Apache Lucene 的接近实时的搜索。
  3. 处理多租户( multitenancy)不需要特殊配置,而Solr则需要更多的高级设置。
  4. Elasticsearch 采用 Gateway 的概念,使得完备份更加简单。
  5. 各节点组成对等的网络结构,某些节点出现故障时会自动分配其他节点代替其进行工作。

缺点

  1. 只有一名开发者(当前Elasticsearch GitHub组织已经不只如此,已经有了相当活跃的维护者)
  2. 还不够自动(不适合当前新的Index Warmup API)

Solr简介 *

Solr(读作“solar”)是Apache Lucene项目的开源企业搜索平台。其主要功能包括全文检索、命中标示、分面搜索、动态聚类、数据库集成,以及富文本(如Word、PDF)的处理。Solr是高度可扩展的,并提供了分布式搜索和索引复制。Solr是最流行的企业级搜索引擎,Solr4 还增加了NoSQL支持。

Solr是用Java编写、运行在Servlet容器(如 Apache Tomcat 或Jetty)的一个独立的全文搜索服务器。 Solr采用了 Lucene Java 搜索库为核心的全文索引和搜索,并具有类似REST的HTTP/XML和JSON的API。Solr强大的外部配置功能使得无需进行Java编码,便可对 其进行调整以适应多种类型的应用程序。Solr有一个插件架构,以支持更多的高级定制。

因为2010年 Apache Lucene 和 Apache Solr 项目合并,两个项目是由同一个Apache软件基金会开发团队制作实现的。提到技术或产品时,Lucene/Solr或Solr/Lucene是一样的。

Solr的优缺点

优点

  1. Solr有一个更大、更成熟的用户、开发和贡献者社区。
  2. 支持添加多种格式的索引,如:HTML、PDF、微软 Office 系列软件格式以及 JSON、XML、CSV 等纯文本格式。
  3. Solr比较成熟、稳定。
  4. 不考虑建索引的同时进行搜索,速度更快。

缺点

  1. 建立索引时,搜索效率下降,实时索引搜索效率不高。

Elasticsearch与Solr的比较 *

当单纯的对已有数据进行搜索时,Solr更快。

Search Fesh Index While Idle

当实时建立索引时, Solr会产生io阻塞,查询性能较差, Elasticsearch具有明显的优势。

search_fresh_index_while_indexing

随着数据量的增加,Solr的搜索效率会变得更低,而Elasticsearch却没有明显的变化。

search_fresh_index_while_indexing

综上所述,Solr的架构不适合实时搜索的应用。

实际生产环境测试 *

下图为将搜索引擎从Solr转到Elasticsearch以后的平均查询速度有了50倍的提升。

average_execution_time

Elasticsearch 与 Solr 的比较总结

  • 二者安装都很简单;
  • Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能;
  • Solr 支持更多格式的数据,而 Elasticsearch 仅支持json文件格式;
  • Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供;
  • Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch。

Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用。

其他基于Lucene的开源搜索引擎解决方案 *

  1. 直接使用  Lucene

说明:Lucene 是一个 JAVA 搜索类库,它本身并不是一个完整的解决方案,需要额外的开发工作。

优点:成熟的解决方案,有很多的成功案例。apache 顶级项目,正在持续快速的进步。庞大而活跃的开发社区,大量的开发人员。它只是一个类库,有足够的定制和优化空间:经过简单定制,就可以满足绝大部分常见的需求;经过优化,可以支持 10亿+ 量级的搜索。

缺点:需要额外的开发工作。所有的扩展,分布式,可靠性等都需要自己实现;非实时,从建索引到可以搜索中间有一个时间延迟,而当前的“近实时”(Lucene Near Real Time search)搜索方案的可扩展性有待进一步完善

说明:基于 Lucene 的,支持分布式,可扩展,具有容错功能,准实时的搜索方案。

优点:开箱即用,可以与 Hadoop 配合实现分布式。具备扩展和容错机制。

缺点:只是搜索方案,建索引部分还是需要自己实现。在搜索功能上,只实现了最基本的需求。成功案例较少,项目的成熟度稍微差一些。因为需要支持分布式,对于一些复杂的查询需求,定制的难度会比较大。

说明:Map/Reduce 模式的,分布式建索引方案,可以跟 Katta 配合使用。

优点:分布式建索引,具备可扩展性。

缺点:只是建索引方案,不包括搜索实现。工作在批处理模式,对实时搜索的支持不佳。

说明:基于 Lucene 的一系列解决方案,包括 准实时搜索 zoie ,facet 搜索实现 bobo ,机器学习算法 decomposer ,摘要存储库 krati ,数据库模式包装 sensei 等等

优点:经过验证的解决方案,支持分布式,可扩展,丰富的功能实现

缺点:与 linkedin 公司的联系太紧密,可定制性比较差

说明:基于 Lucene,索引存在 cassandra 数据库中

优点:参考 cassandra 的优点

缺点:参考 cassandra 的缺点。另外,这只是一个 demo,没有经过大量验证

说明:基于 Lucene,索引存在 HBase 数据库中

优点:参考 HBase 的优点

缺点:参考 HBase 的缺点。另外,在实现中,lucene terms 是存成行,但每个 term 对应的 posting lists 是以列的方式存储的。随着单个 term 的 posting lists 的增大,查询时的速度受到的影响会非常大

 

转载:http://blog.csdn.net/jameshadoop/article/details/44905643

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Mesos上部署spark

$
0
0

还是回到之前一直持续的 Mesos话题。在之前的环节里,我们已经尝试了Mesos的安装,Marathon守护服务以及相对比较主流的Mesos作为Hadoop的资源管理器的实际操作。这次就说说同属于伯克利出品的Spark。

其实spark最初0.7以前的版本还没有自己的资源管理系统,资源的调度都是通过Mesos来执行的。甚至还有小道消息说spark本身就是Mesos用来作为测试的一个项目派生出来。所以说,相比Hadoop+mesos的组合,Spark+Mesos作为大数据分析平台是更为原生态的。

曾经有人一直问过类似于“spark是否可以完整的替代hadoop?”之类的问题,我想说的是,hadoop最强大的地方是它的hdfs,而对于spark来说,它的优势在于将大数据的计算做到了极致的简化,但对于大数据来说,大容量的存储和高IO的读写也是一个复杂的工程,这正是Hadoop的价值所在。恰恰相反的是spark的流行只会加速Hadoop的发展。

OK,回到正题,还是要准备一套Mesos的环境,请参照 此文档

这里下载一份spark的安装包,到你的Mesos Master节点上。个人的建议是你可以选择“pre-built for hadoop的版本”,比如我用的 spark-1.5.2-bin-hadoop2.6.tgz

wget http://d3kbcqa49mib13.cloudfront.net/spark-1.5.2-bin-hadoop2.6.tgz

照例的解包之后,开始配置

cd <YOUR_SPARK_PATH>/conf 之后,vi spark-env.sh,内容其实挺简单的:

#!/usr/bin/env bash

export MESOS_NATIVE_JAVA_LIBRARY=/usr/local/lib/libmesos-0.24.0.so
export SPARK_EXECUTOR_URI=/usr/local/spark.tar.gz
#export SPARK_EXECUTOR_URI=hdfs://spark.tar.gz

好吧,这个地方有一个很大的坑,官方文档上都没有任何的提及,直到我在踩了很久之后才从这里爬出来。vi spark-defaults.conf。

spark.io.compression.codec lzf

全部弄好之后,将你的spark目录重新打包成tar.gz,然后分发到每一个slave节点下的/usr/local。官方文档是将这个文件上传到hdfs上,这个默认的配置已经被我注掉了,这仅仅只是个测试,我没有HDFS。

应该就差不多了,回到spark主目录,冒烟测试:

/usr/local/spark# bin/spark-shell --master mesos://10.239.21.100:5050

Welcome to
 ____ __
 / __/__ ___ _____/ /__
 _\ \/ _ \/ _ `/ __/ '_/
 /___/ .__/\_,_/_/ /_/\_\ version 1.5.2
 /_/

Using Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.7.0_91)
Type in expressions to have them evaluated.
Type :help for more information.
I1218 16:00:58.975153 37814 sched.cpp:164] Version: 0.24.0
I1218 16:00:58.983880 37808 sched.cpp:262] New master detected at master@10.239.149.196:5050
I1218 16:00:58.985206 37808 sched.cpp:272] No credentials provided. Attempting to register without authentication
I1218 16:00:58.992024 37808 sched.cpp:640] Framework registered with 20151218-113549-3298160394-5050-19515-0052
Spark context available as sc.
....

....

scala> val a = sc.parallelize(2 to 1000) //手工输入
a: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:15

scala> a.collect //手工输入
res0: Array[Int] = Array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177...
scala> exit //退出scala界面

中途省略的部分可能有部分报错,以我的经验是换成了官方的jdk1.8之后就OK。看起来openjdk也不是一直都靠谱的。

实验下python调用吧,还是写一个并发版的经典 “羊群繁殖”算法,由于我的集群有96个core,而在一个时间片上一个core只能做一个job,所谓大数据中多于core的任务分配数就是耍流氓,所以这个节点数就设置了96。

vi hog.py

from pyspark import SparkContext

if __name__ == "__main__":
 sc = SparkContext(appName="PythonHog")

 def f(i):
 if i < 2: return 1
 if i < 5: return f(i-1) + f(i-2)
 return f(i-1) + f(i-2) - f(i-5)

 count = sc.parallelize(range(0,35), 96).map(f).reduce(lambda a, b: b-a)
 print(count)

 sc.stop()

提交一个任务

bin/spark-submit --master mesos://10.239.21.100:5050 hog.py

PS: 相比python/Java/R语言来说,最适合Spark的编程语言是Scala。支持全面而且代码简单明了。不过我对这种非常容易写出过于变态的语法还是持一种谨慎态度的。

如何判断一个行业的兴衰呢?

$
0
0
一般来说,任何行业的兴衰都有四个阶段。高速发展,平稳发展,发展停滞,衰退。

1,初期高投入高增长, 预期资本回报率高于整个经济体的平均水平,销售额增长率高于整体经济平均水平。最直观的例子就是互联网初期,每个网站都不赚钱,但是销售额增长率非常可怕,是以实体经济的倍数。这个时候,行业里的参与者很多,还没有一支独大。一般进入这个行业的资本是股权投资资本。由于行业是新兴行业,近乎所有的参与者都没有长期经验,所以犯错率,倒闭率很高。也没有太多的人造壁垒来阻止新人加入。还是用互联网来做例子,一个IT民工,只要他有技术,基本上不需要其他的条件就能加入一个互联网公司。他不需要走后门拉关系也可以加入行业里。

2,然后是平稳发展阶段,资本回报率依然高于整个经济体的平均水平,销售增长额略高于或相当于整体经济水平。这个时候,行业开始整合,有了盈利模式。行业依然值得投入股权投资,但也可以通过债权融资。行业有了一定的壁垒,行业领跑人出现,但未达至垄断地步。

3,发展停滞阶段,资本回报率等于或低于经济体的平均水平。销售增长额低于整体经济体水平。行业参与者人数逐渐减少。这时候行业只剩下巨头,基本上不会有新的股权投资进入这个行业,融资需求由债权融资主导。行业里参与者的增长来自于兼并收购而非行业总体增长。产能过剩,利润率下降等等

4。衰退。资本回报率低于经济体的平均水平,销售额增长为零或者负。行业参与者逐渐因为亏损而退出市场。参与者无法靠债权融资维持营运生产水平,行业的资产的清算余额大于营运收益。

每个阶段的时间不一定一样,但行业和人一样,生老病死都是必然的。

来源:知乎 www.zhihu.com
作者: Kingdom Central

【知乎日报】千万用户的选择,做朋友圈里的新鲜事分享大牛。 点击下载

此问题还有 21 个回答,查看全部。

iPhone不行了?越来越多美国人喜欢买安卓

$
0
0

iPhone不行了?越来越多美国人喜欢买安卓

  不久之前我们曾看到这样一则报道:2016 年将是 iPhone 自诞生以来首次销量下滑的一年。今天我们看到的一份报告似乎也印证了这种预测。威锋网消息,市场调研机构 Raymond James 在其最新报告中表示,现在有越来越多的美国消费者选择 Android 而不是 iPhone 作为他们的下一款智能手机。


  在美国地区,目前持有 iPhone 和 Android 手机的比例分别为 46.3% 和 49.3%,iPhone 稍微落后。而在下一款智能手机的购买意向调查中,Android 的比例同样也高于 iPhone,两者之间的比例分别是 48.7% 和 46.7%。根据 Raymond James 的预测,2016 财年的 iPhone 销量为 2.29 亿部,而 2015 财年(已于 10 月份结束)为 2.31 亿部。


  今年第三季度,中国正式超越美国成为 iPhone 的第一大市场。不过,虽然美国退到了第二位,但仍然是苹果的最大市场之一。如果想要购买 iPhone 的美国消费者越来越少,2016 年“首跌”的预测报告将很有可能成为现实。在上一季度财报会议上,苹果曾表示中国区的 iPhone 销量增长了 120%,市场需求依然强劲。

阅读全文

阿北:豆瓣电影评分八问

$
0
0

这是一篇豆瓣创始人&CEO 阿北(杨勃)刚刚发表的 长文,始终被认为理想主义的阿北,在文中阐明了豆瓣电影评分的原则和做法,用以保护公众对豆瓣评分的信任。随着“豆瓣的电影评分在影视行业的影响越来越大”,阿北说豆瓣收到的威逼利诱也多起来……以下为全文。

阿北:豆瓣电影评分八问

(豆瓣 CEO 阿北,图片来自 Qdaily)

这是篇长文,没空的话,看下大意:豆瓣电影评分在过去十年里一直中立地还原观影大众的平均看法,影视市场的爆发正给这一工作带来更大的外部压力,我们会继续满怀诚意地保护公众对豆瓣评分的信任。

我是豆瓣的创始人,也一直是豆瓣的 CEO。我还写过计算豆瓣评分的最早的几版代码(不难,加起来除下人数)。

除了最早的几年之外,我不直接负责豆瓣电影。但电影评分的大原则和策略,包括和商业独立的原则最早的时候是我定的,后来一直也没变过,期间少数个案也会被捅到我这里拍板。所以以下说的你可以认为是我的个人看法,也可以看作是豆瓣的“公司意志”。

因为用户的力量,豆瓣的电影评分在影视行业的影响越来越大。这两年电影的商业体量激增,评分的影响也跟着变得重要。无论雨点大小,“水军”的雷声越来越大。我们收到的威逼利诱也多起来,诸如“不开个价给水军放行,就找媒体黑你们”之类的。这些让我们觉得,不管愿不愿意,豆瓣的评分会更频繁地被推到风口浪尖。

我们一直认为提供一个真正可信的服务就好了,不需要整天说自己。但现在看起来保护公众对豆瓣评分的信任变成另一个工作,我们需要清楚明确地表达豆瓣的原则和做法,避免可能会出现的误解,让豆瓣评分对影视行业的成长继续有积极和健康的贡献。

一:豆瓣评分是谁定的?

很多评奖的场合有“专家评审团”和“大众评审团”。豆瓣没有专家评审,但有一个一亿多人的大众评审团。

豆瓣的注册用户看完一部电影,心情好的话会来打个一到五星的分(有时候心情不好也会来)。比方说一部电影有 42 万用户打分。我们的程序把这 42 万个一到五星换算成零到十分,加起来除以 42 万,就得到了豆瓣评分。这个评分会自动出现在豆瓣各处,中间没有审核,平时也没有编辑盯着看。每过若干分钟,程序会自动重跑一遍,把最新打分的人的意见包括进来。

那 42 万用户里可能包括资深电影评论家,可能包括你、你的亲戚、你的小学同学、早晨卖你油条的那个人,也可能包括阿北我个人。但每个人都是一票。这个是“大众评审团”应该的含义:不是说团里的人全都大众,而是说和大众一样一人一票。

豆瓣的工作人员偶然收到“我明明给这个片子打了五星,为什么评分一点没变”的投诉的时候,除了心里嘀咕一下“哎,你拿这些红人/独生子女/八零后/九零后/零零后/数学不好的人怎么办”以外,会(或者应该)这样耐心解释:评分实际是变了,只是在小数点后四位,被四舍五入掉了,但如果有几千个人和你一样都打五星的时候,分数就会变。

“一人一票”唯一的例外,是豆瓣的程序判断是“非正常打分”的帐号。这些打分会被排除在外。具体下面会说到。

豆瓣电影评分的主旨和原则,是“尽力还原普通观影大众对一部电影的平均看法”。这个主旨过去十年没变过,将来也不想变。

它并不是专家、影视从业人员或者资深人士对电影的看法,虽然这些看法会被豆瓣算在“普通观影大众”之内。所以有次听到“豆瓣电影评分不专业”的说法的时候,我的反应这是在说“大众不专业”,应该怪语文才是。个人认为汇总专家意见会是另一个很有价值的服务,但这个确实不是豆瓣评分的宗旨。

二:豆瓣评分反映文艺青年的喜好吗?

早已经不是了。

早些年可能是的,因为来打分的人里文艺的比例要比街上的比例高些。但是现在每个月有一亿上下的人会用到豆瓣的评分,我不觉得咱们文艺青年的势力变这么大了。基本能确定现在豆瓣评分反映了大众观点。只是这个“大众”更集中在一二线城市里,和豆瓣用户扎堆的地方一致。

换种说法,在所有去电影院看电影的“大众”和所有看电视的“大众”之间,当前(2015 年)在豆瓣打分的人更接近去电影院的那个。

有些独立电影只有文艺青年会找来看,所以得到的是文艺青年给的平均分。你又不文艺,就因为分数高也找来看,然后… 这不能怪豆瓣,更不能怪她们。但很多东西都是这样的,评分只是判断用到的一部分,经常更重要的是“听说”和“选择”。这个下面也会说到。

三:为什么我喜欢的/我讨厌的/我拍的/我导的/我投资的电影/电视剧会在豆瓣上的评分低得/高得不正常?

所有电影都有众口难调的问题。最好的不是所有人喜欢的,所有人喜欢的不是最好的。

人对一件事情有感情投入,或者有明确爱憎的时候,会投射到别人身上,认为别人应该会有同感。这个当爹妈的都知道。“别人”汇总起来就变成“多数人应该“或者是“正常人应该”。看到有同感的时候我们感觉好,没看到的时候我们不是一下子能接受。你我都这样,没什么奇怪的。

在评分这件事上,看到评分和自己想法一致,觉得豆瓣靠谱,看到不一致,觉得豆瓣不靠谱。这种反应也正常。但“豆瓣”后面只是很多个“别人”而已,不多不少。你和别人平均看法不一致,可以冷静下来再下结论。未必别人不正常,也未必背后有阴谋。这也不一定是坏事,大众经常是错的,至少你是有主见的。

我也是一个创造东西的人,做过一些个靠谱不靠谱的互联网产品。我非常明白自己的作品出来的时候,希望和相信别人会喜欢的心情。事实是,自己和别人的喜好都很难把握,碰壁难免,但下次我们还会“爱上自己的作品”。这是创造的代价,我们自找的,也是我们着迷于此的一个原因。

四:水军是怎么回事,豆瓣评分可刷吗?

水军是有的,但豆瓣评分很难刷得动。

电影这个行业大了,怪事就多。我们把“老子还就不信了,我就要把这个平均分抬高/拉低”动力之下的打分行为统称为“非正常评分”,或者说打分的目的是为了直接干预平均分数。我个人印象里,“非正常评分”大致有四类:注册/收购帐号刷高分的,注册/收购帐号刷低分的(这个我也百思不得其解过),明星粉丝团“进攻豆瓣”的,铁杆用户“捍卫豆瓣评分公正”反水行动的。应该还有别的,比方说行为艺术什么的。

以上听起来吓人,对豆瓣评分的影响其实没那么大,小影响还是短暂和个别的。因为正常打分的人实在太多了,也因为反刷分早已经是豆瓣电影日常工作的一部分,不少同事借助更多的程序一直默默在做。

豆瓣这两年的原则是“所有能判断属于非正常评分的一概不算”,不分高低贵贱颜色。(捍卫评分公正的用户,真的抱歉加感激。但这应该是我们的工作,不是大家的,一时没做好是我们失职。)。

“不算”非常简单可操作,但“判断属于非正常评分”不是那么直接。豆瓣一代接一代的算法工程师、程序员、编辑和产品经理在这件事上贡献过才智,最后都落实在二十四小时跑的大小程序上面。这确实是持续的、魔高一尺道高一丈的事情。但现在门槛已经很高,声称能刷分的基本是在骗人。

刷分基本无效之后,干扰豆瓣评分的努力在向“社会工程”进化:针对具体一部片子制造“豆瓣评分有问题”的舆论,想办法打击豆瓣评分整体的公信力,或者直接对豆瓣的工作人员施加心理压力。行业变化很快,不知道将来会变成怎样,但豆瓣自己的想法和立场可以是不变的。

五:有没有一劳永逸完全解决水军问题的办法?

一劳永逸的办法可能没有。但当下来说,水军的千军万马跳进来,让评分的湖面一点涟漪都不起的办法是有的,但对正常打分用户的感受可能略有影响。我们在积极地准备,需要的时候可以推出。

六:我可以做点什么让我的片子在豆瓣评分高一点?

“找豆瓣的人”是最没用的。不少人试过,大大佬托大佬也直接找到过我。江湖这么大,有用的话早会有人知道,你可以去四处打听一下。据我所知,整个豆瓣系统里没有“修改电影平均分”的后台功能。

刷分上面说过了,越来越没用。所以我确实不知道除了拍好电影,能做什么。

但是最近有转行做电影的老朋友问我同样的问题。直接回答“拍更好看的电影就是了”估计会被他扁。所以我第一次站在片方的立场想了这个问题,答案还是没有。但我给了些观察希望对他有用,以下是大致的意思。

一部电影的豆瓣评分是来评分的人群的平均意见决定的。按道理、平均来说、其他都一样的时候,不怎么宣传就会来看一部电影的人倾向于打高分,但人少;本来不会喜欢、因为大规模宣传建立了高预期来看的,倾向于打低分,但人多。这也是独立电影为什么有时候评分很高(只有粉丝来打分),而票房奇迹有时候评分很低(把不会喜欢的人也宣传来了)的原因。

所以叫好和叫座,高分和票房的确有一些本质的冲突,只有真正广受欢迎的电影能化解这个冲突。除了拍更好的电影永远是王道,把握好宣传的度也比较重要,过度宣传可能会拉低评分。

最后我问这位朋友:口碑还是票房,哪个对你更重要?他的回答比较吐血,这里就不复述了。但我觉得,他的电影好的话,到最后这不会是一个纠结的问题。

七:豆瓣电影评分和豆瓣电影商务是什么关系?

简单地说,没有关系,我们也不想有关系。具体可以分现在的商务和将来的商务看。

豆瓣目前来源于电影行业的主要营收渠道是电影的宣传广告。形式是广告 banner,卖点是“让更多人知道你的电影/电视剧”。经常需要电话里澄清“但是卖点不包括更高评分“,我觉得我的同事挺累的。这件事的收入也只是豆瓣整体收入的零头,如果容易起误会我们可以另作打算。

电影行业里更大的商业机会豆瓣会当仁不让地去争取,只要不会影响到公众对豆瓣评分的信任。内部做到真正的独立比较容易,可以用结构、制度和防火墙做到。稍难的是避免市场和公众的认知被轻易误导,或者说避嫌。只要新的模式依赖于豆瓣整体数据之上的宏观判断,而不是直接依赖评分,我们相信很多事可以做,也想很快开始做。

从管理和团队一致性的角度看,我在公司各种内部场合、在几百人的年会上讲过和这篇问答大同小异的东西(要精简一些,因为得站着讲),所以我的同事大都知道和评分中立原则偏离是极端严重的错误。在和评分有关的事情上,到今天我个人没有发现过一例本质的执行错误。更重要的是如果过去或将来有错误的话,豆瓣作为一个公司有诚意和意志保证发现后能马上得到纠正。

八:你为什么这个时候出来写这个东西?

我们以前认为提供评分服务需要保持中立和独立是天经地义的事情,没什么好公开标榜的。碰到有意无意曲解豆瓣评分原则的,我们也很少出来辩护,我们觉得只要每个月有上亿的人信任豆瓣就够了。但影视行业最近的变化,让我们直接感觉到低调在这个时候可能是不明智的。

但我确实看到行业中具体的个人,曾经都是有理想抱负的年轻人,所以除了沟通走样和误会的原因,我也猜测行业正在催生一些结构的问题。我直觉判断,今天可能是一个岔路口,现在有必要把豆瓣的立场一次表达清楚,以免猜测和误解引发的博弈把行业的一角推向我们最终都不喜欢的方向。

豆瓣一直是用户的朋友,我们希望一直也是影视行业的朋友。我很想看到行业能一直健康地发展下去,相信一个满怀诚意的、中立的评分服务对整个行业在结构上是长期有益的,也相信一个透明地传达观众看法的地方对行业里个人的职业成长也有微薄但是长期的帮助。

— 阿北

本文链接

涅槃重生:我的技术转管理之路

$
0
0

一个程序员的理想

我从高中就开始接触计算机并开始编程,我非常喜欢编程,我一直以为我会写一辈子代码。

我从毕业就一直做技术,开始一年是做 Java 语言的服务器开发,开发过网易邮箱和微博的后台,后来转而做 iOS 开发。

因为喜欢,我几乎把我所有的非工作时间也投入到技术中去。当然,并非是把工作带回家,而是专研技术或者从事技术写作。

于是这几年,我积累了超过 150 篇原创技术文章,在 iOS 技术圈子里面也小有名气,也出版了一本《iOS 开发进阶》的书,微博和微信公众号的粉丝数也都超过了 3 万。

我做得很开心。

我一直以为,我会是一个好码农,我会一直在技术上深入下去。

但是,改变有些时候就是来得那么突然。

涅槃重生

我还记得那一天,2014 年 7 月 17 日,我当时受到邀请,在广州的微信分享 iOS 开发技术。当天晚上,我接到郭常圳(我们的 CTO)的电话,知道要做小猿搜题这个项目,并且这个项目「由我负责」。

于是,我开始了技术转管理之路。

通过从以前的项目组中抽调人手,小猿搜题这个产品技术团队很快组建出来了。我在开发 iOS 版的小猿搜题客户端的同时,也开始了我的管理工作。

现在经过了一年半,我们不但组建成了一支充满战斗力的团队,成收获了不小的成绩:

  • 小猿搜题产品一年时间获得了 5000 万的用户。
  • 我们团队在开发上做到了每周一次迭代,两周一次版本发布。

技术管理的总结

在我的工作中,我慢慢总结出在创业公司中做技术管理工作的「方法论」。我把我的技术管理工作分成以下几个部分:管理业务,管理团队,管理技术。

管理业务

做为互联网公司,我们奉行简单直接的沟通,所以我很多时候并不需要涉及人员的管理工作,更多的时候是业务的管理工作。业务的管理工作主要是围绕着一个具体要做的技术开发功能点展开。具体包括:

  • 任务分解和分配
  • 制定大概的开发排期
  • 每天了解开发进度
  • 讨论和跟进各种具体的技术问题
  • 协调一些产品需求变更
  • 响应一些市场同事的需求
  • 跟进相关功能上线

在这方面,我们主要是采用 Scrum的开发方式,见 《适合码农工作时玩的游戏:Scrum》

我们在整个迭代(Sprint)过程中引入四个会议:计划会议,每日站会,评审会议和回顾会议。通过事先简单的计划,再加上这四个会议中的详细讨论,我基本能够做到:

  • 通过计划会议:比较合理的安排开发排期、分配任务。
  • 通过每日站会:每天了解开发进度,会后讨论和跟进各种具体的技术问题

对于产品需求变更和市场同事需求的响应,我主要利用自己在 Sprint 执行过程中的时间来展开。我会根据当前需求的大小和紧迫程度,来决定是否插入到当前的 Sprint 中。如果插入到当前的 Sprint 工作量太大,我会适当做一些 Sprint 内容的调整。

跟进相关功能的上线主要是开发快要结束的时期,我会和产品同事一起试用最新的功能,了解 Bug 修复的进度,上线的风险情况。在大部分出现风险的情况下,我们都希望用适度加班的方式解决,所以我们上线当晚有时候会工作得比较晚。在无论如何都搞不定的情况下,我们可能会调整上线时间。

在业务涉及跨部门合作的时候,相关的进度管理会更麻烦一些。因为各部门自己的进度安排不一致,所以就会存在「等着联调」的情况。另外联调时出现问题也容易出现没人主动出来解决的情况。这些都需要负责人更频繁地沟通和推进,以保证按时上线。

在每周的工作中,我的管理业务的工作大概花费是 2 天左右。

管理团队

刚刚也说到,互联网公司不怎么需要管人,那么管理团队主要是做什么事情呢?我认为主要是两件事情:招人和带人,所谓的搭班子和带队伍。

招人

招聘这事情实在太重要了,所以必须要团队负责人参与。人才的招聘除了从公开的渠道收取简历、从猎头或同事那里得到推荐以外,还包括定向的找一些自己熟悉的前同事或某个领域的知名大牛,这些工作都是非常花费时间的。

在招人上,我们主要用到了找前同事,内部推荐发伯乐奖,以及进行技术分享和开源代码来获得社区影响力的方式。

值得一提的是,我们对于开源社区的贡献也得到了肯定,我们的基础架构组负责人陈恒因为多次为 Hbase 贡献代码,所以成为了 Hbase 的 Committer,而全中国拥有 Hbase 的 Committer 的公司在此之前只有三家,而且中国的 Hbase 的 Committer 不到 10 人。

在每周的工作中,招聘大概会占用我半天到一天的时间。

带人

人才招进来了,能否顺利融入团队,团队负责人以及这个人的导师(mentor)非常重要。需要做的事情包括:

  • 平时多交流沟通。
  • 在新人遇到问题时,热心地解答。
  • 引导新人熟悉公司的工作方式。

一对一沟通来源于 Intel 公司,在最近很火的一本书 《创业维艰》中里面也提到过。《创业维艰》的作者本·霍洛维茨是被誉为「硅谷最牛的 50 个天使投资人」之一,先后在初期投资了 Facebook、Twitter、Groupon、Skype。

他在书中对一对一沟通介绍到,一对一沟通最主要的意义是:可以使得信息从下而上地传递。从而获得在其它渠道不易获得的信息,保证透明。

适合一对一沟通的内容有很多,包括:

  1. 不成熟的看法
  2. 迫在眉睫的问题
  3. 精彩的想法
  4. 倾诉焦虑
  5. 抱怨

这些内容都不适合在别的场景中出现,比如:不成熟的看法,如果在部门的正常会议或邮件中提出,会让人觉得未经过深思熟虑。又比如一些焦虑或抱怨,如果通过一些渠道宣泄给其他同事,其实也是不好的。一对一沟通让这些内容有了一个不错的出口。

5 年前我刚毕业加入网易有道的时候,我的老大,也是我现在创业公司的 CTO 郭常圳就开始和我做一对一沟通。我非常享受每次沟通的过程。现在我也开始和别人做一对一沟通,我也开始关注一对一沟通的技巧。我们认为最大的技巧是:作为管理者,要多听少说,让员工成为沟通的中心。郭常圳有一个特别「老土」的办法,就是:不主动说话。通过这种方式,强迫让员工选择他们想聊的话题。

在《创业维艰》一书中,也介绍了一些适合用来引导的问题:

  • 当前产品还有哪些可以提高的地方?
  • 我们部门的最大问题是什么,为什么?
  • 如果有,你觉得工作中有哪一点令你感觉不舒服?
  • 你觉得谁的工作最优秀,为什么?
  • 我们的产品哪方面不尽如人意?
  • 我们错失的最大机遇是什么?
  • 哪些是我们应该做而没有做的?
  • 你自己希望未来在哪些方面能有提高?
  • 有什么我能为你做的事情?

我大概保持每个月和每个组内同事都有一次一对一沟通,有很多时候,我是通过「请他们吃饭」来完成的。一对一沟通需要一个舒适的环境,所以在咖啡厅或饭桌上,可能都比在办公室的效果要好一些。

一对一沟通的另一个核心要素是要坦诚,这就像 Scrum 指南中用「游戏规则」来描述内容一样,如果管理者做不到坦诚,那么同事就不会把这当作是一次有效的沟通机会。坦诚的沟通方式是:所有问题都真诚的回答,不掩饰问题,也不回避问题。如果沟通双方能够做到坦诚,即使是一个棘手的问题,那么双方也会从「解决问题」的角度,尽量寻找可能的办法。

除此之外,定期组织一些团队活动,让团队每个人之间建立友谊,也是我努力在做的。这在很多大公司是 HR 部门做的事情,在我们创业公司里面,也变成团队负责人的工作之一了。

什么是领导力

关于管理团队,我也特别喜欢《成为技术领导者》一书中的观点,关于本书,更多的请见 《成为技术领导者》读书心得》。书中是这么说的:

所谓领导力,就是创造这样一个环境,每个人都能在其中发挥出更多的能力。

我想:在强调平等、创新、自由的互联网公司里面,这可能就是领导力最好的定义吧。

管理技术

作为一个技术负责人,产品在技术上的架构是否合理?随着用户量的增长,现有架构能否胜任?当运营活动发生时,突发的流量会有多少,服务器是否能够承受住压力?未来技术上的架构应该如何演进?除了服务器端,客户端应该在哪些技术方案上投入研究力量?这些都是技术负责人需要考虑和决策的。

我同时做过服务器端和移动端的开发工作,不过由于最近几年都是做移动端的开发,所以服务器端的架构技术细节我其实并不是专家。所以我在这方面做得算不上很好。可能是运气好吧,有几次服务器的压力问题,我们都及时发现并且解决了,但是时间都挺紧迫的。现在,我会花时间把服务器端的架构图画出来,然后一块一块考虑,看看有没有更优的方案,并且和服务器端的同学讨论。

在客户端上,我只是对 iOS 开发比较熟悉,对 Android 了解得并不深入。所以我会让技术同学自己提一些技术改进方案,我参与 Review,我想他如果能说得有理有据,还是可以授权他在技术上深入的。

其实每个平台的技术管理可能都需要更多的「授权」,因为具体做事情的人,会比技术管理者更清楚地了解细节。而对细节的深入了解,才是改进技术架构的方案来源。所以,尽量招靠谱的人,那么在管理技术上的工作就只需要遵守「尽量授权」的原则来就可以了。

管理技术还包括公司技术氛围的建立,我主要在以下这些方面下了一些工夫:

  • 推进技术 wiki 的使用
  • 推进 iOS 端每周一次的技术分享
  • 推进 Code Review 以及代码质量

Wiki 是一个非常好用的知识管理工具,前提是每个同事都参与贡献内容。所以作为一个管理者需要用言行来指导新同事学会用 Wiki。我会主动将重要内容记录在 wiki 上,对于一些同事发的邮件内容,我也会要求他整理到 wiki 上。

iOS 端的技术分享也是需要管理者推进的。我之前在网易有道的时候,这方面的活动基本上是大家自愿的方式来进行。这其实对分享者要求很高,一般的人很难达到这种意识,所以当时有道 iOS 端的技术分享很少。因此,我还是认为「半强制」的分享方式更适合当前团队。

「半强制」的分享规则需要大家认同,在一个相对轻松的环境下达成一致,为此我专门组织了一次交流会,大家相互认识一下,一顿吃喝之后,再约定分享规则。现在看起来,大家其实有很多想分享的内容,在 Wiki 上,很多一两个月才轮到他的人,都已经把分享的主题确定了。

Code Review 也是一个需要推动的事情,我们使用 Git 和 Gerrit,做到了所有的提交必须 review 通过之后,才能 merge 进代码仓库。另外我们也在 wiki 上规定了详细的代码风格要求。Code Review 如果做得好,不但可以在代码风格上达成一致,还能让新同事从中学习到一些良好的编程习惯,一些潜在的 Bug 也可能在 Code Review 中被发现,实在是值得坚持的事情。

产品负责人

除了技术负责人的管理业务,管理团队,管理技术工作外,我另外还是小猿搜题的产品负责人,所以我还承担着技术负责人之外的一些工作。这些工作最主要的就是对产品的管理工作。

产品工作看似简单,实则复杂,而我作为一个工作多年的程序员,在这方面的经验非常少。所以我在参与产品讨论时,一开始都比较惶恐。后来我慢慢发现,产品经理的思维还是有章可循,便开始总结和学习,我看了不少产品经理的书,而郭常圳的多次指导也对我的帮忙意义巨大。其实做产品的原则就那么多,重要的还是多思考和体会,把那些原则融入自己的理解。

「场景化思维」是我学到的第一点,我还记得郭常圳带着我们学习乔布斯推出第一代 iPhone 时的演讲,乔布斯非常会讲故事,在用户具体的场景中介绍自己的产品。好的产品经理会将自己「代入」目标用户的使用场景中,解决用户的主要痛点和问题。做为技术人员,我常常陷入产品逻辑完备的泥潭中,但是「场景化思维」使得我能够重新跳出细节,关注主要功能设计是否合理。

「关注数据」是我学到的第二点,产品经理在打磨细节方面,如果能够关注产品数据,那么就很容易找到改进的方向,并且在后期验证自己的想法。关于这个,详细的请看: 数据的秘密(上)- 为什么要关注数据数据的秘密(下)- 如何分析数据

我曾经犹豫自己是否应该学习写产品稿,郭常圳说不用,他说你只需要多看产品经理的产品稿,多思考和比较,慢慢就会有产品的感觉。我发现这一点还是管用的。以前用一个新的 App,作为开发者,我会关注它的功能在技术上如何实现,而我现在,不光会关注技术实现,还会想它的产品设计思路。打开了这扇窗户后,我就能在日常生活的每一天里,通过思考来提升自己的产品能力。

作为产品负责人,我主要的工作是参与产品稿的评审和美术稿的评审,同时会参与决定未来要做的功能,将其安排到产品工作中。另外,我也会关注产品的各项指标数据,保证重要的产品数据都是看过的。

我每周花在产品评审和美术评审大概是半天到一天,每周花在关注产品各项指标数据上的时间大概是半天到一天。

我做得不好的地方

做为一个技术转管理的新人,我觉得我的工作还是有挺多问题。

首先,我刚开始还是太迷恋技术了,有一些开发工作我仍然主动参与。但是实践之后发现,因为我的事情太多太杂,使得我很难保证自己承担的开发工作的进度。所以我现在学会主动把任务交给别人做,如果一件事情不是必须我才能做的,我就交给别人。所以现在技术上,我只参与 iOS 端的 Code Review 工作了。我将更多的精力,放在一些不得不由我做的沟通和项目推进方面的工作上。

接着,我有很长一段时间没能很好地安排好产品计划和研发的进度。好的产品计划应该要领先开发一个以上的迭代周期,这样在技术开发当前版本时,下一个版本功能就在设计和评审当中,使得大家的工作都不受影响。而小猿搜题的产品计划有一阵一直没能很舒服地领先技术,这让很多时候开发同事并不舒服。

解决的办法是我们让产品文档的完成时间点也尽量精准,对于一个大的产品功能设计,我们会定好初版(我们内部叫做 1 版本)、详细版(我们内部叫 5 版本)、完善版(我们内部叫 9 版本)的时间点。产品经理需要努力在时间点内保证产出,这样其实反倒使得大家会关注产品设计的主要问题,在细节上不过分纠结。

最后,我在招聘上的成绩也比较一般,没有能够为团队招来很多有经验的人,所以小猿搜题现有团队还是新人居多。新人的好处是容易和团队文化保持一致,但是在经验上,还是需要更多的锻炼。

总结

小猿搜题从 2014 年 7 月 17 日立项,到 10 月上线,再到元旦正式对外推广,到现在在不到一年的推广时间内,已经积累了超过 5000 万的用户。而我,也随着小猿搜题,从一个纯技术的 iOS 程序员,成长成为它的产品技术负责人,虽然也犯了一些错误,我感觉自己的进步还是很快的。

我也希望我的故事能够激励其他的技术同行,能够勇敢地接受新的挑战。在快速变化的移动互联网时代,快速迭代演进的不止有 App,也包括我们自己,愿大家都能活得精彩!

Posted by 唐巧 Dec 18th, 2015 summary

关注我的「iOS开发」微信公众号,每天获得精选的 iOS 开发文章和创业心得:

原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0

控制SKU数量,融入社交概念,生鲜团购电商拼好货是怎么火起来的?

$
0
0

国内各种电商不少,但大多品类繁杂,消费者在购物上的时间成本较高,因此,拼好货想做一个更像美国精选超市Costco一样的电商,能够持续为对生活品质有要求的人提供优质优价的货品,控制sku数量,保证产品质量,并将商品毛利率控制在5 %。而水果高频,又是刚需,因此成了拼好货最先切入的品类。

有趣的是,在拼好货创始人黄铮还没有完全想清晰该怎么走时,就在一天之内获得了高榕资本和IDG的投资。创业邦了解到,目前拼好货刚刚结束B轮融资,投资方和融资金额尚未透露。 

让购物好玩起来

拼好货的创始人黄峥离开谷歌后,创办了国内食品类电商代运营公司乐其,代运营超过150个国际大牌,后来还创办了一家游戏公司。而拼好货的初创人员,大都来自于这两家公司,这也让团队有了电商运营和游戏基因。

拼好货市场总监吴湄对创业邦说,2015年初,大家坐在一起讨论拼好货该怎么做,那时候她正玩“团购砍价”活动玩的很起劲儿,但需要参与的人数较多,而且砍价成功后付款的程序也很繁琐,当时的程序猿问她,如果让你先付款再团购你愿意吗?吴湄说,如果是普通的生活用品,她是愿意的,因为试错成本很低。于是,这位程序猿同学就很快做成了这款小游戏,这也成了拼好货的雏形。

2015年4月微信服务号上线后,拼好货的订单量快速增长,此后,根据7个大区,拼好货做了七个微信服务号,基本覆盖全国,微信粉丝数加起来近1000万。2015年7月底,拼好货App正式上线,在两个月后的一次促销活动结束后,拼好货连续3天位居IOS免费榜第一位,订单量也从600达到如今的日峰值60万。

吴湄说,能够有现在量,很大一部分都是靠拼团这种游戏形式,“买水果好像玩游戏一样,你想买就必须拉人成团,这受到了很多人喜欢,尤其是在一二线城市的白领和中产阶级女性。”

创业邦了解到,在拼好货买水果,用户下单后需要邀请3-5名用户完成“拼团”,24小时内如果拼团成功,参团的每个人就能够以优惠的价格购买,如果拼团失败,钱款会自动退回。这也就意味着,一个用户使用,会带动身边2-4个新用户进入。吴湄说,拼好货是第一家带有社交属性的生鲜电商平台。

严格的质量把控

另一方面,拼团方式因为是在熟人之间运作,这也意味着用户在为拼好货背书。吴湄说,拼好货很清楚这一点。因此,会在货品和服务质量上进行严格把控。

首先,目前拼好货是鲜电商中产地直采覆盖率最高的电商之一。所谓产地直采,就是平台去往产地亲自挑选,来保证果品质量和新鲜度。截至到2015年11月底,拼好货实现产地直采占到在售水果品种的一半,包括安岳柠檬、洛川苹果、嘉善黄桃、金艳猕猴桃、越南榴莲、越南红心火龙果、泰国椰青等在内的40余种。“秋冬季产地直采的大货之一赣南脐橙,拼好货11天就卖出了600吨。”吴湄说。 

其次,缩短水果从树上到消费者手中的时间和环节。吴湄说,传统的水果从树上到消费者手里,会经过果农、水果贩子、批发市场、经销商、水果店等至少五个环节,娇嫩的水果被搬运12次之后才能送到消费者手里。

但拼好货拼团的方法可以相对精确地预测出拼团成功的订单量(目前平均成功率在80%),采购者按照预测单量向果农进行采购,甚至可以实现“消费者A开团时,水果依然在树上,成团后24小时发货,水果从产地到仓库经过分拣的三四个小时,就直接送往消费者手中。” 也就是说,拼好货的水果从果农那完成采摘+挑选后,直接运送到各大区仓完成分拣+质检,再直接送到消费者手里,水果最多只需要被搬运4次。

更为重要的是,拼好货严格执行“坏果包赔”的售后服务。吴湄说,水果生鲜电商难免遇到品质的问题,拼好货的售后服务就印在包装盒上:“坏果包赔”。收到坏果之后,只要在相应区的微信号说明情况,就可以立刻得到赔付。“这也是社交电商至关重要的一环,品质如何、服务如何,都决定了消费者是否愿意持续为平台背书。”

程序员内部培训

$
0
0

1.前言

虽然题为培训,但我还是想说一句,程序员其实不需要培训,只需要指点。原因有三:

  1. 程序员的工作都必须去实践,几乎没有纯理论的领域。
  2. 由于互联网的开放性,程序员能找到大量的资源自学。
  3. 随着实践深入,会自然地遇到一些问题。解决这些问题除了靠智力外,大部分只需要知道答案的大致方位就能用时间来消灭掉。

大牛之所以能成为大牛,就是知道了很多答案存在的地方以及发现这些地方的方法。优秀的程序员培训师懂得教方法而不仅是教答案。可惜很多培训师不是这样的,公司内部的培训流于形式,大家听完后就知道这是个很牛b的技术,却不知道怎么令自己也牛b起来。
HR就算懂上面的道理,他们从根本上也没能力推动程序员的内部培训。HR能做的事是帮助管理者 在程序员心中培养技术为尊的意识,让他们有动力去自学并实践,并以公司内某位榜样为目标赶超他
HR无法有大作为,也令大多数公司很少重视培训。因为即使不培训也不会影响赚钱,工作效率的低下可以用加班来弥补。而且项目做到一定程度就会更新换代、推倒重来,原本写得多烂的代码都成过眼云烟。还有就是老员工们都有自己的习惯,较难通过培训来改变,基本都需要有人经常提醒。
在实际中有时候还是需要培训的,这其中多数是因为负责人懒得写文档,或者文档很容易过时而懒得更新,不如口头说一遍算了,╮(╯▽╰)╭。

2.技术培训

按内容区分,培训可分为业务技术培训和软技能培训,还有HR组织的集训。

大家对技术培训的第一反应都是PPT式会议,因为这种形式多,而且也是最最初级的培训。
PPT最大的意义在于做报告,内容凝练而简略,所以受众是没法得到很多的信息的。但是这并不等于没用。PPT式会议和网上的视频教程一样,能帮助零基础的人快速入门。这里需要解释一下何谓零基础,是指对这门知识几乎没接触过,但已有相近的知识。例如已知C学C++或已知C++学Java,也就是说,至少不用在培训中解释何谓关键字或者面向对象。连相近知识也没有的人,应该叫负基础,他们会连PPT式会议都听不懂,还是得回归书本。
书本不仅适合负基础的人,也适合高级读者。因为看书有时间细想琢磨,有助于吸收。专家级则是阅读各种SDK和API文档。大神级的就是看代码看出神的了。

搜遍互联网和各种书籍都找不到的东西,才是真正有意义做培训的,多数跟本公司密切关联:

  • 产品的整体架构、设计思路、业务逻辑,迭代历史
  • 各类工具/系统(IDE、需求、项目管理、测试与bug、文档等)的使用技巧
  • 解bug、做优化等的经验
  • 工作流程和制度
  • 本部门的知识体系梳理。直接用例子说明是什么吧,请点击《 iOS开发知识与能力体系 思维导图》。文章很久没更新,但能说明问题了,相信不做iOS的也能get√到。

能让受众最大程度吸收的培训应该是手把手地教,这个贯穿在设计和编码过程中。本人实践过,发现被培训的人确实能完整地吸收,而且时间长了他会有反馈并跟你讨论,你可能在讨论中反过来也学到东西。当然,这个很少发生在互联网公司里,大家都很忙碌。

3.软技能培训

大家能思考出这部分内容的意义吗?答案我写在最后吧。下面这些都是可培训的。

3.1高效会议

这一节放到前面很重要,因为不少人搞不清几种会议的差别。会议的主持人或主讲人对会议的高效性负有最大责任,如果都用同一种思路来召开,会议就变得没什么效果。IT界“尊崇”的会议是乔布斯的苹果发布会和各种技术大会上的交流演讲,可惜这些并不是公司内部会议的榜样,很多人找错了模仿对象。

会议类型用途特点和要求
产品发布会展示新产品算是一种表演,要声色俱全,多媒体设备只是一种道具。
目的是引起轰动,传播的内容要能煽动观众的情绪,不断制造高潮。
交流传播自己或本公司的经验
(技术大会属于这个性质)
展示个人、团队或公司的优秀技术或成果,间接地卖广告
讲授的内容具有高度概括性,不会讲细节
不会很在意观众是否都听懂,甚至怕泄密而有所保留
宣讲会传达信息或做动员观众可能是被要求来听的,这在宣讲本质上是一种命令,所以不用在意讲得怎么样
培训传播知识,提高工作效率引导听众记忆和会后探索,目标是让听众最大程度地记住传授内容
评审对方案的评审主持人讲述自己的方案,听众提出意见和建议
对方案的描述要尽可能地细致,目的是让听众都理解后能发现问题,减少实施过程中的返工
总结成果展示、述职为了提高绩效评级,在符合事实的前提下,能怎么吹就怎么吹,你懂的
研讨讨论、头脑风暴没有主讲人,而要有主持人。非主持人都可以随意发言,有专人做会议记录
主持人的最大职责是引导讨论有序进行且不偏离主题,并减少争论以至形成共识。
例会
(日/周)
日常的信息交换每个人都可发言,要尽量简短。发言内容只需在场有另外一个人听懂。
产生的问题会后再由各关联者自行讨论,不占用所有人时间

在日常工作中,一个会议的性质可能会包含以上多种,主持人需要在不同的阶段完成不同的职责。特别是主持人也是作为主讲人的时候,应该留意场景的切换,如培训完毕后的问答阶段。一般来说主持人都需要做到这几点:

  • 宣讲会议议程或子主题,让参会人做好准备配合
  • 尽量使会议达成目标
  • 按时开始,不超时结束
  • 帮助听众理解发言人(包括自己)的讲话内容
  • 提醒其他发言人注意时间、语气等。不要因为一个人而耽误了全部人的时间
  • 确保重要的人员都到齐
  • 引导会议中的讨论达成一致意见
  • 记录重要的发言和待跟进事项

3.2培训他人

好的程序员不一定是好的培训师,但好的架构师一定是合格的培训师,因为架构师必须向他人传达自己的思想。
做培训的首要目标是让听众完全吸收你所讲的内容,当然这很难做到,但做得到让人吸收大部分的也太少了。这是令多数公司不重视培训的重要原因,但也不能完全怪讲师,因为好的培训是需要花费大量时间和精力的。如果不是专门设立培训师岗位或者把培训职责写入KPI,没有几个人会对把培训做到极致。看看需要做多少功夫才能做好吧:
(交流演讲的要求比培训低,故也可参考)

会前准备:

  • 冥想和模拟训练。在脑子里演练完整个培训过程,或者找个地方(培训现场最佳)对着空气讲。这能减小忘词的概率和减轻现场讲演的紧张感,还能发现培训逻辑的疏漏。如果还不够,可以先让少部分人来听,然后再面向全体。
  • 如果怕会上遗漏一些事项没说,应准备一张小纸写上给自己做提醒的话语。非庄重场合写在手机里也行。
  • PPT的制作技巧,很多书可参考,不赘述了。特别提醒,如果确认这是一个培训而不是一个交流演讲,PPT上的字不应该追求简略,特别是重要到需要观众记忆或记笔记的内容(也可能把PPT交给他们)。甚至可以考虑用Word或网页而不是PPT。
  • 如果要讲到代码,不应该只用PPT。可以直接打开编辑器对着代码讲。在PPT里贴代码段的都是耍流氓,因为代码占用的篇幅大,而且信息量较多,很难短时间理解透。(这时候技术培训不如文档,但现实往往是相反的,本质原因是文档的糟糕。读者看不下去而希望能面授,集体的诉求自然转变成现场培训。)
  • 发邮件提醒培训的适用人群。如有需要,提醒参会者提前阅读一些基础知识。
  • 保证自己在培训过程精力充沛。为此,喝茶、喝咖啡、做几个俯卧撑什么的都行,用你喜欢的方式。
  • 选择观众注意力容易集中的时间段。不饿,不困,不忙等。
  • 选择好的场地,帮助观众集中注意力。不吵、无异味、气温适中(空调设好)、座位密度适中等。
  • 其实,你穿什么服装都会影响培训效果

进行时:

  • 帮助听众保持注意力集中:
    • 如果讲授的内容很繁重,可尝试分节,每节40分钟左右,中间休息10分钟。是的,培训的本质是上课。
    • 多微笑,声音洪亮。在旁人眼中,此刻的你应该比平常状态更兴奋和活跃。自己表现得越投入,观众就会越认真听,否则会变成一场催眠大会。
    • 提到他的名字,让他的注意力集中回来,或让他有更多的参与感。比如“某某肯定也是这样想的”,“某某曾经说(问)过”,“这样就能解决某某的问题了”。
    • 注意自己的姿势、手势,甚至发型、服装,不要喧宾夺主吸引走了注意力
    • 开始讲述的内容可以不怎么重要,例如做自我介绍或描述一些东西辅助今天培训的主题,帮助听众慢慢进入状态。
  • 演讲的技巧:
    • 克服和利用紧张与恐惧。要理解这是人的天性,被很多人围观而自然产生的防御心理,实际上这能帮助你更集中注意力做好培训。
      克服它们的方法有自我暗示(用特定的话语激励自己,想象过往成功的演讲,想象这只是普通的例会等)、深呼吸、转移注意力(喝口水,摆弄一下其他物品,跟别人说说话等)等。
      事实上无论你犯多大的错,观众过几天就淡忘了。
    • 不能用提问来考验人,更确切来说不能令被提问者尴尬而导致冷场,别学学校老师那套。提问可用于:现场调查,证明结论;开放式的,没有正确答案;让观众猜测,活跃气氛。
    • 重复以强调。讲完例子或论据后重复一遍观点,加深听众的印象。或者更直接地,“这个很重要,我再重复一遍”。
    • 不跑题。我就见过“我如何当好技术leader”这个主题花了三成时间讲“我如何当上技术leader”的人。
    • 让听众跟上你的节奏。“承上启下,伏笔,呼应”这些写作技巧,在演讲中表现为“前面我们讲的都是理论,下面我们看看如何应用”、“这点我们后面会有详细描述”、“我们前面讲到的XXX在这里就是最典型的应用”。
    • 幽默。注意幽默是为了加深记忆服务的,不要最终变成展示个人魅力。幽默感需要刻意地积累,而且要恰到好处地用在演讲上是需要锻炼的。这个学问比较深,不展开了,建议找书看。
    • 说服。最佳方式是列举好处,以利诱导,而不是把规矩硬塞入别人的思想。更厉害的方法是洗脑,这个也是可以找书看哦。
    • 要会讲故事,在故事中蕴含你观点。故事的形式比理论好。
    • 生动,运用打比方和对比、反比。听众一时难以理解你所描述的内容时,可以换一种角度来说。比如向不懂编程的家人解释架构设计是做什么,“就好比设计一辆汽车,要做到零件可拆卸组装(模块化),多个厂家都能帮助生产零件(可扩展性强),开起来省油又马力足(性能高)……”
  • 控制会场的一切:
    • 利用好你的权力。无论发生什么影响会议进程的事情,如何处理都以你的决策为主。即使你的上司在场也请记住,这个时候你最大。
    • 准备面对意外。比如投影仪或麦克风坏了你也能继续做培训;有人问你答不出的问题,你可以找后援团来回答或说会后私聊。
    • 现场环境的使用。灯光、投影仪、座位摆放、提词板、遥控器、激光笔、白板等。

会后:

  • 收集反馈。提醒大家可以随意批评这次培训中做得不好的地方。
  • 注意受众的当场反应
  • 观察受众的会后行为,是否有受你的培训影响而有所改变等

3.3写作

这里特指撰写技术文档和报告,其它文档都比这个的要求低。
写作是很多程序员的弱项,除了表达能力基本功缺乏锻炼外,最主要是忽略了文档的作用是给别人看的,不是给自己看的,无论内容多么有意义也得保证用户平均停留时间和留存率。这恰恰是产品经理熟悉的领域,好的文档也是追求用户体验的,所以想锻炼写作的话不妨用一下这个偏方——找产品设计方面的书看看。举个更形象的例子,电商网站(如淘宝)上的宝贝页面也算一个文档,你是怎么被吸引或引导去付费呢?当然,最好的模仿对象应该是Windows/iOS/Android的系统SDK文档。
(本文的主旨是列培训提纲,缺少更多示例说明,不是好的示范哈。培训和写作有部分技巧是相通的,这里不再重复)

保证读者有耐心从头到尾看完:

  • 读起来通顺,有一定的节奏感(长短句排布适中,合理使用标点符号断句;不是指押韵,但会有一点点韵律感)。
  • 有条理,有过渡,同级的子主题之间不跳跃
  • 由浅入深,不会突然遇到理解障碍。想想C++/C#/Java书籍的目录?
  • 选择不花眼、不太小的字体,排版好看,不凌乱
  • 如果是web文档,要注意让读者不需要点击太多链接,必要时自己总结链接文档的内容。
  • 一张图片内不要信息量太大。尺寸不要过大致无法一页看完,或作适当分割;Web文档的大图要做成竖型,不要产生横向滚动条。

保证“傻瓜”也能看懂:

  • 朴实。不要用口语,不要带非群众性的幽默甚至没有,这不是在写演讲稿,也不要写成内心独白。
  • 别卖弄知识和文采,也不要用偏门词汇和方言,会影响部分人的理解。比如有多少人知道银弹(silver builet)或者“抛书包”的意思?考考你粤语:撞板、撞彩。
  • 抽象或模糊的概念和观点有示例做进一步说明。(很可惜,本文因时间关系没做到,那能写成一本书了)
  • 考虑读者可能不具备一些基础知识而看不懂,要么在文章开头写明阅读基础,要么在文中加注释阐述。

专业性,保证处女座不会看疯:

  • 没有歧义。比如一个新闻标题叫“中国过早拆房1年浪费数千亿”,这里可以有三种歧义:“过早1年拆房,浪费数千亿”、“过早拆房,这一年浪费数千亿“、”过早拆房,每一年浪费数千亿“。改成这样就没歧义了:“中国过早拆房每年浪费数千亿”。
  • 简洁凝练,不要废话连篇。用最短的话说清楚问题。在技术领域,还可多用专业词汇来减少长篇描述,比如用“外观模式”代替“新增一个类统一封装这个模块的所有接口,对外屏蔽这个模块的复杂逻辑”。
    更高要求的简洁是在语文层面的,这方面的能力很多人在大学毕业就固定下来了,故不想多言,有兴趣请百度。
  • 精简掉冗余信息,不是必要的信息不写、简写、写在末尾,减少读者耗费的时间成本。
  • 关键的信息处不能有错别字。英文单词拼写也是哦。
  • 严谨,严密,有逻辑。不断论证,有理有据,不留疑问,无懈可击

技术文档会被多次查看,保证后续的阅读能迅速找到最可能感兴趣的点:

  • 能从几个维度方便查找。可参考论文、书籍的写法,有目录、摘要、关键字、前言、章节、参考文献等。
  • 重点的地方可改变字体(颜色、粗细、大小、字形等)
  • 按查看频率排章节。某些文档会把思考和论证过程写上去,最后写结论。这也意味着别人查看的时候,鼠标得滚好远,这时可考虑把结论放前面。
  • 合理地分章节。这里要很多例子才能帮助理解,时间关系只能讲一个。假如文档的主要内容是“在Windows、Mac OS、Linux下如何使用线程和进程”,那么:
    如果为了方便查找各操作系统下怎么使用,各节的标题应该是“Windows下的使用”、“Mac OS下的使用”、“Linux下的使用”,每节都是描述此操作系统下线程和进程的API;
    如果为了方便查找线程和进程的使用分别在不同系统有什么差异,那么各节的标题应该是“线程”、“进程”,每节都是同时列举三个操作系统下的API。
  • 内容多到一定程度,应分多篇文档。和上一点一样,同样有技巧。比如写Windows SDK的使用,可分为“初级篇、中级篇,高级篇”,每篇都可能讲到绘图框架,但难度不同;也可分为“……,I/O,绘图,网络……”,把所有的绘图框架知识写到同一章。具体的应根据目标读者的需求来划分。
  • 如果更新频率较高或是多人合作,能不用画图的尽量不画,或用 文字型图(点我看示例)。这样方便维护,无需额外的软件就能编辑。
  • 利用好Web文档的便捷性——超链接
    链接的目标网页如果不是最上面,应直接链接到锚点,不需要别人再拖动滚动条。
    链接过去的文档如果内容很多,一下子找不到你引用的信息,应该自己总结一下或复制核心的内容过来

如何具备写好文档的能力?多练。以及总结你看到的优秀文章的特点。
不过说实话,除非是写用户手册(说明书)的文档工程师,很少有公司对程序员有这方面的要求,或者说国内还没到这个境界。

3.4敏捷教练

Scrum Master是有认证体系的,可以派人去参加外训拿个证书,然后回公司推广。各种理论就不在此展开了,请百度。
补充一个点,教练的人选也很重要。最好是原本就在团队内,但不是团队leader,并且leader有当众声明教练的权责。这恐怕算是中国特色了。原因:

  • 如果leader是教练,那么大家都当是命令,会产生抵触心理,也不敢乱提反对意见,达成不了自组织状态
  • 如果教练是外来的,碍于情面,很多改革难以指正执行
  • 如果教练没有足够的权力(至少能合理地否决leader的意见),那会是个吃力不讨好的工作。想纯靠精神宣导,那是痴人说梦。

3.5沟通交流

在团队合作中总会遇到冲突,优良的沟通技巧能和谐掉很多不愉快的事情。

  • 对事不对人,不要对人进行评论。即使对方知道你的原则,也可以是事先再说一遍“我是对事不对人的”。讨论对方做得不好的地方时,应设法降低这种讨论的不良影响,尽量去除对方警戒心以避免升级为冲突。
  • 人多的场合,赞扬可点名,指出错误需匿名。
  • 幽默。它可以化解很多的问题。
  • 措辞。这个最好是向国家机关的发言人学习,但也不要太官腔。举个例子,“不够好”比“比较差”更少一点攻击性。
  • 随时敢于承认自己的错误,可以解释,但不要用来推翻结论。
  • 微笑。不建议伪装地笑,应发自内心。如果做不到,不严肃即可。
  • 理清概念,避免歧义。如果对话中有无法理解的词语,要问清楚什么意思,不要不懂装懂。
  • 不轻易打断别人,尊重发言欲。如果不赶时间,即使对方讲的话没意义也等他讲完吧,至少在别人停顿稍长的时候再插入而不要显得突兀。
  • 抓住重点。简单的事情不要用一大段话来说。当别人怎么做时,你可以用自己的话概况一遍并请对方确认是这个意思。
  • 精确传递信息,不要误传误报。
  • 用打比方来帮助别人理解你的话。比如向外行人解释“终于把bug解掉了的感觉”,就像“肚子疼时终于坐到了马桶上”。(哈,相信你会有更好的描述)
  • 转折话题时做好过渡,别人未必能反应过来,以为你还要争论。很经常用到的一句是:这部分是对的,还有一个问题是……”
  • 控制好自己和他人的情绪,也就是情商的锻炼。实际的锻炼过程是需要经常反思的,没有一个理论能帮助你应对所有状况。

3.6行为规范/职业素养

HR领域的正直、不干违法事情这类东西就摆一边去吧,先说说这里包括什么吧:

  • 做有利于团队合作的选择,但如果自己有牺牲也要表现出来。最简单的例子:多花点时间写注释和文档,方便后人维护。
  • 忠于自己的专业眼光,不轻易妥协,也不做消极对抗。例如,如果认定这样某段代码会有风险,在未验证前不同意发布产品。
  • 承诺的时间点都按时按质完成。
  • 传递前辈对你的帮助,激励后辈的成长。
  • 坚持学习。本文应该也有引导作用,除了学技术,还有很多可学呢。
  • 多观察,多自己解决问题

拥有的知识和技能越多,表现出来的素养应该越高,不再投机取巧。
(技术领域的不提了,比如遵守代码规范,多写注释方便Review和维护之类的)

3.7时间管理

“番茄工作法”和“重要&&紧急”这两个理论应该比较多人听过。但如何正确运用在日常工作中恐怕很多人没头绪。这也就是培训的重点,应结合实际工作举例。这个领域的学问也挺多,鼓励多看书。

3.8事务推进与思考

即使你不是leader,当由你牵头某个事务时就需要应用一些管理方法。举几个例子,不解释了,请点击链接:

3.9职业规划

这种培训少数公司才有,因为懂得越多,越会跟HR作对。呵,心大了就想升职或跳槽了。
问题大概有这些:

  • 选什么岗位,要不要转岗。开发、测试、产品经理、管理类等。
  • 选什么行业。传统软件型、硬件厂商、互联网、非IT业的IT部门等。
  • 选什么技术。前端、后台、移动开发……
  • 选什么类型的公司。外企、创业企业、国企等。
  • 选哪类城市。北上广深还是二三线?
  • 跳槽的时机。

公司组织的培训一般都是某些英雄人物讲自己在本公司的成长经历,受制于演讲水平,效果一般不佳。而且可以说这可能是特殊情况,套在自己身上不合适。所以基本上都需要多听几个人的演讲,由听众自己找出相似的点,这些点比较可能不是个案。
个人自学的话也差不多,多看些职业规划的理论、名人传记、网上写个人经历的文章(如《 非计算机类专业毕业生五年程序员职业生涯的回顾和思考》)等。先广泛收集,再从中挑选拼凑出合适的。也可以做做网上免费的职业评测。

3.10外面的世界

程序员可以终身都在学习,即使不跳槽,也要了解外面的变化,最起码要知道同行的情况。这些信息当然是很难打探到或者让对方告诉你了,主要靠同行跳槽过来后做分享。
也可了解下外国本土公司的特点,虽然能照搬过来的东西不多,但能借鉴的也是有的。例如:开发活动的形式本身也在进化,不仅仅是人在追求最大效益;英雄主义的竞争文化,崇尚以一敌百的能力。

题外话:培训自己

软技能都不会给公司带来直接明显的收益,所以大多数公司不会重视培训这些。实际上,软技能可以加倍工作效率,公司和个人是双赢的。就算公司不重视,自己一定要重视,没人培训你,那就自己培训自己。如果技术水平相等、资历相同的两个人选哪个当官,那自然是和领导最亲近的。哈,你觉得和领导亲近不是靠软技能在发挥作用?
软件工程的概念是借鉴工业工程的,程序员要发展也可从很多其它行业获取知识。就像编程能力之于程序员,以上每一种软技能都是某一种职业的核心技能。也许你无法和很多不同职业的人交友,但你能买到所有职业的专业书,这年头真的连如何当乞丐的教程都有。不要等着老师教你,推荐看看HR、管理学、心理学、销售、演艺、人物传记、科普、旅游、艺术设计等领域的书籍。
还有就是,锻炼好身体,革命的本钱啊。

作者:hursing 发表于2015/12/19 17:49:19 原文链接
阅读:481 评论:0 查看评论

致二十多岁仍迷茫困惑徘徊逃避的年轻柜员们--浅谈柜员的职业发展

$
0
0
每每看到年轻的柜员们在网上吐槽工作多苦多累,做了几年柜员感到很迷茫,如何逃离、如何规划未来的职业道路。这些最亲爱的小伙伴们似曾相似的迷茫,心中无解的困惑,看到后心中颇有感触,而你们所经历的,我都曾经一一经历过,彷徨过,呐喊过,没有拉下一点一滴。

荷马史诗《奥德赛》中有一句名言:"没有比漫无目的地徘徊更令人无法忍受的了。”

你做柜员这几年里的迷茫徘徊,很快就会造成你30岁时的恐慌,40岁时的挣扎,甚至一辈子的平庸。如果不能在柜员这几年时间尽快冲出困惑、找准自己的坐标,你未来几十年的职业生涯就很可能会面临较大的被动与波折。

思绪好像又飘到毕业在外省刚上班的时候,在分行营业部忙忙碌碌的那几年。和大多数普通的人一样,没有背景没有资源,从柜员做起,而且一干就是三四年。一年后,调至分行。及至又一年,至总行。其中的曲折波澜,有嘲讽,也有坚持,有误解,也有鼓励,好似南柯一梦。

就想用自己朴实无华的语言,写下自己的浅见,供年轻的“柜员们”参考。如果看后您有所启发,我觉得就值了。如果觉得纯属扯淡,权当博君一笑。

一、是否都要从柜员做起


1.在目前的国情下,没有背景没有关系的校招应届毕业生刚进银行都要从柜员做起,越是在三四线城市这种情况愈发明显。几乎所有银行都会宣称毕业生进行以后都要从基层柜台做起,但如果你的家庭本身在当地有很强的政商人脉,或许可以直接略过一线岗位,直接进分行机关甚至总行。这是国情,难易程度跟你的关系硬度成反比。

2.有些人会说管培生不用从柜员做起。是的,管理培训生就是以培养公司未来管理干部为目标的。大部分银行管培生入职后,都会去基层锻炼一两年,再根据期间的表现决定后面的部门岗位。至于能不能直接晋升从事管理岗位,那真要看机遇了,因人而异。

3.个人觉得,硕士研究生毕业做银行柜员有点可惜,大材小用。也许你们从象牙塔里刚走出来时,仍会带有天之骄子的骄傲,但对大部分股份制商业银行现有柜面运营体系要求来说,可能某些职业院校的专科生更适合柜员这个岗位,毕竟他们的打字点钞传票等柜面基本技能、存贷汇的柜面基础知识比科班乃至硕士生要强太多,而且服务意识也要更好。但研究生胜在专业知识,学习能力已经视野。

二、没有资源没有关系没有背景的“三无”小柜员

1.作为一名没有资源没有关系没有背景的“三无”小柜员,当你发现跟你一同进行一起做柜台的同事,只在柜面呆了一两个个月后就拍拍屁股潇洒的去了管理岗位,去了分行机关,甚至总行部室。请合起你张大的嘴巴,收起你惊讶的目光,因为这不光在银行,甚至在所有的企业都是很正常的现象。

请放弃你所谓天之骄子的身份,丢掉“千里马常有,而伯乐不常有”的陈词滥调,其实做柜员就是从事服务业。你要适应社会,几百年前,达尔文就曾告诉过我们一个血淋淋的道理,物竞天择,适者生存。

2.小柜员们,你刚参加工作。没有钱、没有经验、没有资历、没有关系,这些都不可怕。没有钱,可以通过认真工作去赚;没有经验,可以通过一个业务一个业务去学习;没有资历,可以一步一步去积累;没有关系,可以一点一点去编织。但是,没有目标才是最可怕的!

3.亲爱的“三无”小柜员,你必须有一个正确的方向。刚进银行的这几年,我们的生活、感情、职业等都存在很多不确定的因素,未来也充满了各种可能。这个时候,必须学会选择,给自己一个明确的定位,知道自己的优势所在,朝着一个方向努力。

丑小鸭变成白天鹅,只要一双翅膀;灰姑娘变成美公主,只要一双水晶鞋。

三、柜员岗位的价值与定位

1.银行柜员岗位是银行最基层的岗位,没有从事过柜员的人对这个岗位的评价容易走极端,认为一钱不值无关紧要。客观来说,从整个银行的岗位体系来看,柜员是处在金字塔的最低端,地位收入性价比都偏低。但不积蹞步,无以至千里;不积小流,无以成江海。如果能在这个岗位做好,多思考多学习,而不是只会简单机械的重复性操作,绝对会给你未来的银行职业生涯打下良好的基础。

2.同样条件同样学历的员工,入职都是从柜员坐起,未来的职业道路可以相差极大。一名优秀的员工可以从这个岗位学到银行很多基础的知识,如现金流通,支付结算,账户管理,电子银行,负责业务,资产业务乃至国际结算等等。是的,有人会说,柜员接触的每一方面都是基础,都是皮毛,没有什么价值。只要按照规范,一步一步操作不出错就行了。

但一开始,你就讲自己定位在简单的操作员上,只会机械呆板按照操作规范来,你未来的路就会越走越窄。如果你能深入的学习,不仅知道规范要求你这么操作,而且要去弄明白后面的原理,不能知其然而不知其所以然。

3.拿简单的企业结汇来说,你如果只知道死记硬背制度,从待核查账户结汇前要查企业在名录状态,而不去深入了解业务后面的政策制度,那真和富士康流水线上的操作工人没有区别。

你可以从这个细分结汇业务入手,先去了解即期结汇和远期结汇的区别,ABC三类企业的不同结汇要求。再深入学习,研究B类企业怎么核销结汇额度,没有额度怎么处理,C类企业结汇要求,如果是资本项下的结汇又该如何处理。

再往后,弄明白了代客结售汇,可以再去想想银行自身结售汇。除了结售汇,还有外汇买卖,外汇期权,有没有点差优惠,现汇还是现钞,是平仓还是展期,是直盘还是交叉盘,头寸不够怎么办等等。。。

只要你不满足于简单的操作,而会主动的深入学习,逐渐成长为某个细分领域的专家,你以后的职业道路会越走越宽。在这里顺便推荐用思维导图的学习方法,对于理清知识脉络,很有效率。

四、柜员的职业规划


1.柜员岗位虽然很重要,但是长时间从事基础工作而没有职业的提升,也会严重削弱你的职场竞争力。在这个小小的三尺柜台上,大家好像八仙过海各显神通,你要学会尽快脱颖而出,你要有自己的优点。最重要的是,你要知道你想要什么,朝哪方面努力。

2.有人柜面服务做的很好,成为服务标兵;有人头脑灵活转介营销做得好,转型做理财经理客户经理;有人技能突出获奖无数,转型做培训。有人接柜效率高差错少,逐渐成长为网点主管。有人精通某块业务,成长为业务管理人员,产品经理。。。

3.柜员岗位就像一块磨刀石,能不能快速的成长起来,能不能脱颖而出,就看你的态度,情商和机遇。

做银行柜员不可怕,可怕的是五年十年的做柜员而没有进步。


五、And the Winner Is

迷茫与困惑谁都会经历,恐惧与逃避谁都会面临,但不要把迷茫与困惑当作可以自我放弃、甘于平庸的借口。亲爱的柜员们,在你这几年坐柜台的时间里,越早找到方向,越早走出困惑,就越容易在银行职业道路上取得成就、创造辉煌。一个柜员找不到出路,才会迷茫、恐惧。

最后,送给所有曾经迷茫困惑徘徊逃避的年轻柜员们,一首经典法语歌,Gérard Darmon演唱的《 And the Winner Is 》。


是的,最终获胜者是:

爱。

(注:以上经验只适用应届毕业生,题图来源网络。)



附:

《And the Winner Is》歌词

Je voudrais remercier ma mère qui m'a nourri, qui m'a puni
我感谢我的妈妈喂养我,惩罚我
Je voudrais remercier Molière qui n'a jamais reçu son prix
我感谢莫里哀,他从未收到过以自己命名的奖
Dans cette cérémonie étrange où je suis nominé à vie
在这个陌生的仪式上,我提名生活
Je suis ému, tout se mélange, je me lève et je vous souris
我很感动,一切都顺利,我起立,我微笑
And the winner is : la vie, and the winner is : l'amour
获奖者是:生命,最终获胜者是:爱
Je voudrais remercier ma mort pour faire preuve d'autant de patience
我要感谢我的死神表现出很大的耐心
Façon de conjurer le sort d'avoir peur avec élégance
如何铤而走险,恐惧与更加优雅
Je voudrais remercier l'ami qui sait mieux que moi qui je suis
我想感谢我的朋友,他比我更清楚的知道我是谁
Je l'embrasse et je lui dédie mes cuites et mon enfance aussi
我搭着他的背,分享我童年最爱的熟食
And the winner is : la vie, and the winner is : l'amour
获奖者是:生命,最终获胜者是:爱
Je voudrais remercier les femmes et la mienne en particulier
我要感谢特别是女士们
Tant de bonheur et quelques drames mais je ne suis que leur moitié
这么多快乐的影视剧,但我只是其中一部分
Un clin d'œi à mes ennemis qui me font la gueule aujourd'hui
今天我对我的敌人点头示意
Sans eux, je crois que je m'ennuie, alors je vais leur dire merci
如果没有他们,我觉得我很无聊,所以我会说声谢谢
And the winner is : la vie, and the winner is : l'amour
获奖者是:生命,最终获胜者是:爱
Je porte la main sur le cœur et je vous salue encore une fois
我把手放在心上,我再次跟你打招呼
Je garde le sourire et mes larmes, je les garde pour moi
我保持笑容和眼泪,我一直对自己说
And the winner is : la vie, and the winner is : l'amour
获奖者是:生命,最终获胜者是:爱
And the winner is : la vie, and the winner is : l'amour.
获奖者是:生命,最终获胜者是:爱
And the winner is : la vie, and the winner is : l'amour.
获奖者是:生命,最终获胜者是:爱
And the winner is : la vie, and the winner is : l'amour.
获奖者是:生命,最终获胜者是:爱
And the winner is : la vie, and the winner is : l'amour.
获奖者是:生命,最终获胜者是:爱



-------------------------
梦里挑灯看剑 - -一枚来深务工的金融民工的微信公众号,有梦想有情怀也偶有失落,欢迎关注。
微信号: swordindream


来源:知乎 www.zhihu.com
作者: 知乎用户(登录查看详情)

【知乎日报】千万用户的选择,做朋友圈里的新鲜事分享大牛。 点击下载

elasticsearch原理之搜索与聚合之谜

$
0
0

满足海量数据实时聚合要求的数据库不多,比较常见的有这么几种:

其中Elasticsearch是目前市场上比较很少有的,能够在检索加载和分布式计算三个方面都做得一流的数据库。而且是开源并且免费的。它使用了很多技术来达到飞一般的速度。这些主要的优化措施可以列举如下。

  • Lucene的inverted index可以比mysql的b-tree检索更快。
  • 在 Mysql中给两个字段独立建立的索引无法联合起来使用,必须对联合查询的场景建立复合索引。而lucene可以任何AND或者OR组合使用索引进行检索。
  • Elasticsearch支持nested document,可以把一批数据点嵌套存储为一个document block,减少需要索引的文档数。
  • Opentsdb不支持二级索引,只有一个基于hbase rowkey的主索引,可以按行的排序顺序scan。这使得Opentsdb的tag实现从检索效率上来说很慢。
  • Mysql 如果经过索引过滤之后仍然要加载很多行的话,出于效率考虑query planner经常会选择进行全表扫描。所以Mysql的存储时间序列的最佳实践是不使用二级索引,只使用clustered index扫描主表。类似于Opentsdb。
  • Lucene 从 4.0 开始支持 DocValues,极大降低了内存的占用,减少了磁盘上的尺寸并且提高了加载数据到内存计算的吞吐能力。
  • Lucene支持分segment,Elasticsearch支持分index。Elasticsearch可以把分开的数据当成一张表来查询和聚合。相比之下Mysql如果自己做分库分表的时候,联合查询不方便。
  • Elasticsearch 从1.0开始支持aggregation,基本上有了普通SQL的聚合能力。从 2.0 开始支持 pipeline aggregation,可以支持类似SQL sub query的嵌套聚合的能力。这种聚合能力相比Crate.io,Solr等同门师兄弟要强大得多。

查询效率之快的三个重要技术:

mmap来加载单独需要索引的列(memory mapped byte buffer);

各种posting list的压缩方案来压缩;

Roaring Bitmap数据结构做逻辑操作;

 

参考:

1、 elasticsearch原理篇, 文章从检索、加载、分布式聚合三个方面,深入的剖析了es比mysql、opentsdb等数据查询、聚合更快速的原因;

1.1、时间序列数据库的秘密(1)—— 介绍
http://www.infoq.com/cn/articles/database-timestamp-01
1.2、时间序列数据库的秘密(2)——索引
http://www.infoq.com/cn/articles/database-timestamp-02
1.3、时间序列数据库的秘密(3)——加载和分布式计算
http://www.infoq.com/cn/articles/database-timestamp-03

 

 

 

 

 

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




【转载】单表60亿记录等大数据场景的MySQL优化和运维之道 | 高可用架构

$
0
0

此文是根据杨尚刚在【QCON高可用架构群】中,针对MySQL在单表海量记录等场景下,业界广泛关注的MySQL问题的经验分享整理而成,转发请注明出处。

MySQL的优点

 

  • 使用简单

  • 开源免费

  • 扩展性“好”,在一定阶段扩展性好

  • 社区活跃

  • 性能可以满足互联网存储和性能需求,离不开硬件支持

 

上面这几个因素也是大多数公司选择考虑MySQL的原因。不过MySQL本身存在的问题和限制也很多,有些问题点也经常被其他数据库吐槽或鄙视

 

MySQL存在的问题

 

  • 优化器对复杂SQL支持不好

  • 对SQL标准支持不好

  • 大规模集群方案不成熟,主要指中间件

  • ID生成器,全局自增ID

  • 异步逻辑复制,数据安全性问题

  • Online DDL

  • HA方案不完善

  • 备份和恢复方案还是比较复杂,需要依赖外部组件

  • 展现给用户信息过少,排查问题困难

  • 众多分支,让人难以选择

 

看到了刚才讲的MySQL的优势和劣势,可以看到MySQL面临的问题还是远大于它的优势的,很多问题也是我们实际需要在运维中优化解决的,这也是MySQL DBA的一方面价值所在。并且MySQL的不断发展也离不开社区支持,比如Google最早提交的半同步patch,后来也合并到官方主线。Facebook Twitter等也都开源了内部使用MySQL分支版本,包含了他们内部使用的patch和特性。

 

数据库开发规范

 

数据库开发规范定义:开发规范是针对内部开发的一系列建议或规则, 由DBA制定(如果有DBA的话)。

 

开发规范本身也包含几部分:基本命名和约束规范,字段设计规范,索引规范,使用规范。

 

规范存在意义

 

  • 保证线上数据库schema规范

  • 减少出问题概率

  • 方便自动化管理

  • 规范需要长期坚持,对开发和DBA是一个双赢的事情

 

想想没有开发规范,有的开发写出各种全表扫描的SQL语句或者各种奇葩SQL语句,我们之前就看过开发写的SQL 可以打印出好几页纸。这种造成业务本身不稳定,也会让DBA天天忙于各种救火。

 

基本命名和约束规范

 

  • 表字符集选择UTF8 ,如果需要存储emoj表情,需要使用UTF8mb4(MySQL 5.5.3以后支持)

  • 存储引擎使用InnoDB

  • 变长字符串尽量使用varchar varbinary

  • 不在数据库中存储图片、文件等

  • 单表数据量控制在1亿以下

  • 库名、表名、字段名不使用保留字

  • 库名、表名、字段名、索引名使用小写字母,以下划线分割 ,需要见名知意

  • 库表名不要设计过长,尽可能用最少的字符表达出表的用途

 

字段规范

 

  • 所有字段均定义为NOT NULL ,除非你真的想存Null

  • 字段类型在满足需求条件下越小越好,使用UNSIGNED存储非负整数 ,实际使用时候存储负数场景不多

  • 使用TIMESTAMP存储时间

  • 使用varchar存储变长字符串 ,当然要注意varchar(M)里的M指的是字符数不是字节数;使用UNSIGNED INT存储IPv4 地址而不是CHAR(15) ,这种方式只能存储IPv4,存储不了IPv6

  • 使用DECIMAL存储精确浮点数,用float有的时候会有问题

  • 少用blob text

 

关于为什么定义不使用Null的原因

 

* 1.浪费存储空间,因为InnoDB需要有额外一个字节存储

 

* 2.表内默认值Null过多会影响优化器选择执行计划

 

关于使用datatime和timestamp,现在在5.6.4之后又有了变化,使用二者存储在存储空间上大差距越来越小 ,并且本身datatime存储范围就比timestamp大很多,timestamp只能存储到2038年

 

 

索引规范

 

  • 单个索引字段数不超过5,单表索引数量不超过5,索引设计遵循B+ Tree索引最左前缀匹配原则

  • 选择区分度高的列作为索引

  • 建立的索引能覆盖80%主要的查询,不求全,解决问题的主要矛盾

  • DML和order by和group by字段要建立合适的索引

  • 避免索引的隐式转换

  • 避免冗余索引

 

关于索引规范,一定要记住索引这个东西是一把双刃剑,在加速读的同时也引入了很多额外的写入和锁,降低写入能力,这也是为什么要控制索引数原因。之前看到过不少人给表里每个字段都建了索引,其实对查询可能起不到什么作用。

 

冗余索引例子

 

  • idx_ ab c(a,b,c)

  • idx_ a(a) 冗余

  • idx_ab(a,b) 冗余

 

隐式转换例子

 

字段: remark varchar(50) NOT Null

 

MySQL>SELECT id, gift_code FROM gift WHERE deal_id = 640 AND remark=115127; 1 row in set (0.14 sec)

 

MySQL>SELECT id, gift_code FROM pool_gift WHERE deal_id = 640 AND remark=‘115127’; 1 row in set (0.005 sec)

 

字段定义为varchar,但传入的值是个int,就会导致全表扫描,要求程序端要做好类型检查

 

SQL类规范

 

  • 尽量不使用存储过程、触发器、函数等

  • 避免使用大表的JOIN,MySQL优化器对join优化策略过于简单

  • 避免在数据库中进行数学运算和其他大量计算任务

  • SQL合并,主要是指的DML时候多个value合并,减少和数据库交互

  • 合理的分页,尤其大分页

  • UPDATE、DELETE语句不使用LIMIT ,容易造成主从不一致

 

数据库运维规范

 

运维规范主要内容

 

  • SQL审核,DDL审核和操作时间,尤其是OnlineDDL

  • 高危操作检查,Drop前做好数据备份

  • 权限控制和审计

  • 日志分析,主要是指的MySQL慢日志和错误日志

  • 高可用方案

  • 数据备份方案

 

版本选择

 

  • MySQL社区版,用户群体最大

  • MySQL企业版,收费

  • Percona Server版,新特性多

  • MariaDB版,国内用户不多

 

建议选择优先级为:MySQL社区版 > Percona Server > MariaDB > MySQL 企业版

 

不过现在如果大家使用RDS服务,基本还以社区版为主

 

Online DDL问题

 

原生MySQL执行DDL时需要锁表,且锁表期间业务是无法写入数据的,对服务影响很大,MySQL对这方面的支持是比较差的。大表做DDL对DBA来说是很痛苦的,相信很多人经历过。如何做到Online DDL呢,是不是就无解了呢?当然不是!

 

 

上面表格里提到的 Facebook OSC和5.6 OSC也是目前两种比较靠谱的方案

 

MySQL 5.6的OSC方案还是解决不了DDL的时候到从库延时的问题,所以现在建议使用Facebook OSC这种思路更优雅

 

下图是Facebook OSC的思路

 

 

后来Percona公司根据Facebook OSC思路,用perl重写了一版,就是我们现在用得很多的pt-online-schema-change,软件本身非常成熟,支持目前主流版本。

 

使用pt-online-schema-change的优点有:

 

  • 1.无阻塞写入

  • 2.完善的条件检测和延时负载策略控制

 

值得一提的是,腾讯互娱的DBA在内部分支上也实现了Online DDL,之前测试过确实不错,速度快,原理是通过修改InnoDB存储格式来实现。

 

使用pt-online-schema-change的限制有:

 

  • 改表时间会比较长(相比直接alter table改表)

  • 修改的表需要有唯一键或主键

  • 在同一端口上的并发修改不能太多

 

可用性

 

关于可用性,我们今天分享一种无缝切主库方案,可以用于日常切换,使用思路也比较简单

 

在正常条件下如何无缝去做主库切换,核心思路是让新主库和从库停在相同位置,主要依赖slave start until 语句,结合双主结构,考虑自增问题。

 

 

MySQL集群方案:

 

  • 集群方案主要是如何组织MySQL实例的方案

  • 主流方案核心依然采用的是MySQL原生的复制方案

  • 原生主从同步肯定存在着性能和安全性问题

 

MySQL半同步复制:

 

现在也有一些理论上可用性更高的其它方案

 

  • Percona XtraDB Cluster(没有足够的把控力度,不建议上)

  • MySQL Cluster(有官方支持,不过实际用的不多)

 

 

红框内是目前大家使用比较多的部署结构和方案。当然异常层面的HA也有很多第三方工具支持,比如MHA、MMM等,推荐使用MHA

 

sharding拆分问题

 

  • Sharding is very complex, so itʼs best not to shard until itʼs obvious that you will actually need to!

  • sharding是按照一定规则数据重新分布的方式

  • 主要解决单机写入压力过大和容量问题

  • 主要有垂直拆分和水平拆分两种方式

  • 拆分要适度,切勿过度拆分

  • 有中间层控制拆分逻辑最好,否则拆分过细管理成本会很高

 

曾经管理的单表最大60亿+,单表数据文件大小1TB+,人有时候就要懒一些

 

 

上图是水平拆分和垂直拆分的示意图

 

数据库备份

 

首先要保证的,最核心的是数据库数据安全性。数据安全都保障不了的情况下谈其他的指标(如性能等),其实意义就不大了。

 

备份的意义是什么呢?

 

  • 数据恢复!

  • 数据恢复!

  • 数据恢复!

 

目前备份方式的几个纬度:

 

  • 全量备份 VS 增量备份

  • 热备 VS 冷备

  • 物理备份 VS 逻辑备份

  • 延时备份

  • 全量binlog备份

 

建议方式:

 

  • 热备+物理备份

  • 核心业务:延时备份+逻辑备份

  • 全量binlog备份

 

借用一下某大型互联网公司做的备份系统数据:一年7000+次扩容,一年12+次数据恢复,日志量每天3TB,数据总量2PB,每天备份数据量百TB级,全年备份36万次,备份成功了99.9%。

 

主要做的几点:

 

  • 备份策略集中式调度管理

  • xtrabackup热备

  • 备份结果统计分析

  • 备份数据一致性校验

  • 采用分布式文件系统存储备份

 

备份系统采用分布式文件系统原因:

 

  • 解决存储分配的问题

  • 解决存储NFS备份效率低下问题

  • 存储集中式管理

  • 数据可靠性更好

 

使用分布式文件系统优化点:

 

* Pbzip压缩,降低多副本存储带来的存储成本,降低网络带宽消耗

 

* 元数据节点HA,提高备份集群的可用性

 

* erasure code方案调研

 

数据恢复方案

 

目前的MySQL数据恢复方案主要还是基于备份来恢复,可见备份的重要性。比如我今天下午15点删除了线上一张表,该如何恢复呢?首先确认删除语句,然后用备份扩容实例启动,假设备份时间点是凌晨3点,就还需要把凌晨3点到现在关于这个表的binlog导出来,然后应用到新扩容的实例上,确认好恢复的时间点,然后把删除表的数据导出来应用到线上。

 

性能优化

 

复制优化

 

MySQL复制:

 

  • 是MySQL应用得最普遍的应用技术,扩展成本低

  • 逻辑复制

  • 单线程问题,从库延时问题

  • 可以做备份或读复制

 

问题很多,但是能解决基本问题

 

 

上图是MySQL复制原理图,红框内就是MySQL一直被人诟病的单线程问题

 

单线程问题也是MySQL主从延时的一个重要原因,单线程解决方案:

 

  • 官方5.6+多线程方案

  • Tungsten为代表的第三方并行复制工具

  • sharding

 

 

上图是MySQL5.6 目前实现的并行复制原理图,是基于库级别的复制,所以如果你只有一个库,使用这个意义不大

 

当然MySQL也认识到5.6这种并行的瓶颈所在,所以在5.7引入了另外一种并行复制方式,基于logical timestamp的并行复制,并行复制不再受限于库的个数,效率会大大提升

 

 

上图是5.7的logical timestamp的复制原理图

 

刚才我也提到MySQL原来只支持异步复制,这种数据安全性是非常差的,所以后来引入了半同步复制,从5.5开始支持

 

 

上图是原生异步复制和半同步复制的区别。可以看到半同步通过从库返回ACK这种方式确认从库收到数据,数据安全性大大提高

 

在5.7之后,半同步也可以配置你指定多个从库参与半同步复制,之前版本都是默认一个从库

 

对于半同步复制效率问题有一个小的优化,就是使用5.6+的mysqlbinlog以daemon方式作为从库,同步效率会好很多

 

关于更安全的复制,MySQL 5.7也是有方案的,方案名叫Group replication 官方多主方案,基于Corosync实现

 

 

主从延时问题

 

原因:一般都会做读写分离,其实从库压力反而比主库大/从库读写压力大非常容易导致延时。

 

解决方案:

 

  • 首先定位延时瓶颈

  • 如果是IO压力,可以通过升级硬件解决,比如替换SSD等

  • 如果IO和CPU都不是瓶颈,非常有可能是SQL单线程问题,解决方案可以考虑刚才提到的并行复制方案

  • 如果还有问题,可以考虑sharding拆分方案

 

提到延时不得不提到很坑人的Seconds behind master,使用过MySQL的应该很熟悉

 

这个值的源码里算法

 

long
time_diff= ((long)(time(0) – mi->rli.last_master_timestamp) –
mi->clock_diff_with_master);

 

Seconds behindmaster来判断延时不可靠,在网络抖动或者一些特殊参数配置情况下,会造成这个值是0但其实延时很大了。通过heartbeat表插入时间戳这种机制判断延时是更靠谱的

 

复制注意点:

 

  • Binlog格式,建议都采用row格式,数据一致性更好

  • Replication filter应用

 

主从数据一致性问题:

 

  • row格式下的数据恢复问题

 

InnoDB优化

 

成熟开源事务存储引擎,支持ACID,支持事务四个隔离级别,更好的数据安全性,高性能高并发,MVCC,细粒度锁,支持O_DIRECT。

 

主要优化参数:

 

  • innodb fileper_table =1

  • innodb bufferpool_size,根据数据量和内存合理设置

  • innodb flushlog_at trxcommit= 0 1 2

  • innodb logfile_size,可以设置大一些

  • innodb pagesize

  • Innodb flushmethod = o_direct

  • innodb undodirectory 放到高速设备(5.6+)

  • innodb bufferpool_dump

  • atshutdown ,bufferpool dump (5.6+)



 

 

 

上图是5.5 4G的redo log和5.6 设置大于4G redo log文件性能对比,可以看到稳定性更好了。innodb logfile_size设置还是很有意义的

 

InnoDB比较好的特性:

 

  • Bufferpool预热和动态调整大小,动态调整大小需要5.7支持

  • Page size自定义调整,适应目前硬件

  • InnoDB压缩,大大降低数据容量,一般可以压缩50%,节省存储空间和IO,用CPU换空间

  • Transportable tablespaces,迁移ibd文件,用于快速单表恢复

  • Memcached API,full text,GIS等

 

InnoDB在SSD上的优化:

 

  • 在5.5以上,提高innodb writeio threads和innodb readiothreads

  • innodb iocapacity需要调大

  • 日志文件和redo放到机械硬盘,undo放到SSD,建议这样,但必要性不大

  • atomic write,不需要Double Write Buffer

  • InnoDB压缩

  • 单机多实例

 

也要搞清楚InnoDB哪些文件是顺序读写,哪些是随机读写

 

随机读写:

 

  • datadir

  • innodb data file_path

  • innodb undo directory

 

顺序读写:

 

  • innodb loggroup homedir

  • log-bin

 

InnoDB VS MyISAM:

 

  • 数据安全性至关重要,InnoDB完胜,曾经遇到过一次90G的MyISAM表repair,花了两天时间,如果在线上几乎不可忍受

  • 并发度高

  • MySQL 5.5默认引擎改为InnoDB,标志着MyISAM时代的落幕

 

TokuDB:

 

  • 支持事务 ACID 特性,支持多版本控制(MVCC)

  • 基于Fractal Tree Index,非常适合写入密集场景

  • 高压缩比,原生支持Online DDL

  • 主流分支都支持,收费转开源 。目前可以和InnoDB媲美的存储引擎

 

目前主流使用TokuDB主要是看中了它的高压缩比,Tokudb有三种压缩方式:quicklz、zlib、lzma,压缩比依次更高。现在很多使用zabbix的后端数据表都采用的TokuDB,写入性能好,压缩比高。

 

下图是我之前做的测试对比和InnoDB

 

 

 

 

 

上图是sysbench测试的和InnoDB性能对比图,可以看到TokuDB在测试过程中写入稳定性是非常好的。

 

tokudb存在的问题:

 

  • 官方分支还没很好的支持

  • 热备方案问题,目前只有企业版才有

  • 还是有bug的,版本更新比较快,不建议在核心业务上用

 

比如我们之前遇到过一个问题:TokuDB的内部状态显示上一次完成的checkpoint时间是“Jul 17 12:04:11 2014”,距离当时发现现在都快5个月了,结果堆积了大量redo log不能删除,后来只能重启实例,结果重启还花了七八个小时

 

MySQL优化相关的case

 

Query cache,MySQL内置的查询加速缓存,理念是好的,但设计不够合理,有点out。

 

锁的粒度非常大MySQL 5.6默认已经关闭

 

When the query cache helps, it can help a lot. When it hurts, it can hurt a lot.明显前半句已经没有太大用处,在高并发下非常容易遇到瓶颈。

 

关于事务隔离级别 ,InnoDB默认隔离级别是可重复读级别,当然InnoDB虽然是设置的可重复读,但是也是解决了幻读的,建议改成读已提交级别,可以满足大多数场景需求,有利于更高的并发,修改transaction-isolation。

 

 

 

 

 

上图是一个比较经典的死锁case,有兴趣可以测试下

 

关于SSD

 

关于SSD,还是提一下吧。某知名大V说过“最近10年对数据库性能影响最大的是闪存”,稳定性和性能可靠性已经得到大规模验证,多块SATA SSD做Raid5,推荐使用。采用PCIe SSD,主流云平台都提供SSD云硬盘支持。

 

 

 

最后说一下大家关注的单表60亿记录问题,表里数据也是线上比较核心的。

 

先说下当时情况,表结构比较简单,都是bigint这种整型,索引比较多,应该有2-3个,单表行数60亿+,单表容量1.2TB左右,当然内部肯定是有碎片的。

 

形成原因:历史遗留问题,按照我们前面讲的开发规范,这个应该早拆分了,当然不拆有几个原因:

 

  1. 性能未遇到瓶颈 ,主要原因

  2. DBA比较“懒“

  3. 想看看InnoDB的极限,挑战一下。不过风险也是很大的,想想如果在一个1.2TB表上加个字段加个索引,那感觉绝对酸爽。还有就是单表恢复的问题,恢复时间不可控。

 

我们后续做的优化 ,采用了刚才提到的TokuDB,单表容量在InnoDB下1TB+,使用Tokudb的lzma压缩到80GB,压缩效果非常好。这样也解决了单表过大恢复时间问题,也支持online DDL,基本达到我们预期。

 

今天讲的主要针对MySQL本身优化和规范性质的东西,还有一些比较好的运维经验,希望大家能有所收获。今天这些内容是为后续数据库做平台化的基础。我今天分享就到这里,谢谢大家。

 

QA

 

Q1:use schema;select * from table; 和select * from schema.table;两种写法有什么不一样吗?会对主从同步有影响吗?

 

对于主从复制来说执行效率上差别不大,不过在使用replication filter时候这种情况需要小心,应该要使用Replicate WildIgnore Table这种参数,如果不使用带wildignore,第一种方式会有问题,过滤不起作用。

 

Q2:对于用于MySQL的ssd,测试方式和ssd的参数配置方面,有没有好的建议?主要针对ssd的配置哈

 

关于SATA SSD配置参数,建议使用Raid5,想更保险使用Raid50,更土豪使用Raid 10

 

 

上图是主要的参数优化,性能提升最大的是第一个修改调度算法的

 

Q3:数据库规范已制定好,如何保证开发人员必须按照规范来开发?

 

关于数据库规范实施问题,也是有两个方面吧,第一、定期给开发培训开发规范,让开发能更了解。第二、还是在流程上规范,比如把我们日常通用的建表和字段策略固化到程序,做成自动化审核系统。这两方面结合 效果会比较好。

 

Q4:如何最大限度提高innodb的命中率?

 

这个问题前提是你的数据要有热点,读写热点要有交集,否则命中率很难提高。在有热点的前提下,也要求你的你的内存要足够大,能够存更多的热点数据。尽量不要做一些可能污染bufferpool的操作,比如全表扫描这种。

 

Q5:主从复制的情况下,如果有CAS这样的需求,是不是只能强制连主库?因为有延迟的存在,如果读写不在一起的话,会有脏数据。

 

如果有CAS需求,确实还是直接读主库好一些,因为异步复制还是会有延迟的。只要SQL优化的比较好,读写都在主库也是没什么问题的。

 

Q6:关于开发规范,是否有必要买国标?

 

这个国标是什么东西,不太了解。不过从字面看,国标应该也是偏学术方面的,在具体工程实施时候未必能用好。

 

Q7:主从集群能不能再细化一点那?不知道这样问合适不?

 

看具体哪方面吧。主从集群每个小集群一般都是采用一主多从方式,每个小集群对应特定的一组业务。然后监控备份和HA都是在每个小集群实现。

 

Q8:如何跟踪数据库table某个字段值发生变化?

 

追踪字段值变化可以通过分析row格式binlog好一些。比如以前同事就是通过自己开发的工具来解析row格式binlog,跟踪数据行变化。

 

Q9:对超大表水平拆分,在使用MySQL中间件方面有什么建议和经验分享?

 

对于超大表水平拆分,在中间件上经验不是很多,早期人肉搞过几次。也使用过自己研发的数据库中间件,不过线上应用的规模不大。关于目前众多的开源中间件里,360的atlas是目前还不错的,他们公司内部应用的比较多。

 

Q10:我们用的MySQL proxy做读负载,但是少量数据压力下并没有负载,请问有这回事吗?

 

少量数据压力下,并没有负载 ,这个没测试过,不好评价

 

Q11:对于binlog格式,为什么只推荐row,而不用网上大部分文章推荐的Mix ?

 

这个主要是考虑数据复制的可靠性,row更好。mixed含义是指如果有一些容易导致主从不一致的SQL ,比如包含UUID函数的这种,转换为row。既然要革命,就搞的彻底一些。这种mix的中间状态最坑人了。

 

Q12: 读写分离,一般是在程序里做,还是用proxy ,用proxy的话一般用哪个?

 

这个还是独立写程序好一些,与程序解耦方便后期维护。proxy国内目前开源的比较多,选择也要慎重。

 

Q13: 我想问一下关于mysql线程池相关的问题,什么情况下适合使用线程池,相关的参数应该如何配置,老师有这方面的最佳实践没有?

 

线程池这个我也没测试过。从原理上来说,短链接更适合用线程池方式,减少建立连接的消耗。这个方面的最佳配置,我还没测试过,后面测试有进展可以再聊聊。

 

Q14: 误删数据这种,数据恢复流程是怎么样的(从库也被同步删除的情况)?

 

看你删除数据的情况,如果只是一张表,单表在几GB或几十GB。如果能有延时备份,对于数据恢复速度是很有好处的。恢复流程可以参考我刚才分享的部分。目前的MySQL数据恢复方案主要还是基于备份来恢复 ,可见备份的重要性。比如我今天下午15点删除了线上一张表,该如何恢复呢。首先确认删除语句,然后用备份扩容实例启动,假设备份时间点是凌晨3点。就还需要把凌晨3点到现在关于这个表的binlog导出来,然后应用到新扩容的实例上。确认好恢复的时间点,然后把删除表的数据导出来应用到线上。

 

Q15: 关于备份,binlog备份自然不用说了,物理备份有很多方式,有没有推荐的一种,逻辑备份在量大的时候恢复速度比较慢,一般用在什么场景?

 

物理备份采用xtrabackup热备方案比较好。逻辑备份一般用在单表恢复效果会非常好。比如你删了一个2G表,但你总数据量2T,用物理备份就会要慢了,逻辑备份就非常有用了



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Android实现语音识别

$
0
0

关注微信号:javalearns   随时随地学Java

或扫一扫

 

 

随时随地学Java

苹果的iphone的语音识别功能使用的是Google的技术,做为Google力推的Android自然会将其核心技术植入到Android系统里面,并结合google的云端技术将其发扬光大。

所以Google Voice Recognition在Android中的实现就变得非常轻松。

android语音识别

Android语音识别,借助于云端技术可以识别用户的语音输入,包括语音控制等技术,下面我们将利用Google提供的Api实现这一功能。

功能点为:通过用户语音将用户输入的语音识别出来,并打印在列表上。

功能界面如下:

语音识别界面

用户通过点击speak按钮显示界面:

点击speak按钮

用户说完话后,将提交到云端搜索:

将提交到云端搜索

在云端搜索完成后,返回打印数据:

返回打印数据

 

关注微信号:javalearns   随时随地学Java

或扫一扫

 

 

随时随地学Java



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



lucene-对多个索引的搜索和多线程搜索

$
0
0

1、如果应用程序架构由多个LUCENE索引组成,则可以通过MutltiSearcher把所有索引搜索。也可以通过ParallelMultiSearcher进行多线程搜索。在单核的情况下,MultiSearcher比ParallelMultiSearcher性能更高。

2、MultiSearcher

搜索2个搜索,把动物按首字母在字母表中的位置分成2部分,一部分一个索引

public class MultisearcherTest extends TestCase{

   private Indexsearcher[] searchers;

   public void setUp() throws Exception{ 

        String[] animals={"aardvark","beaver","coati","dog","lemur",

                          "python","vicuna","zebra"};

        Ananlyzer analyzer=ne WhitespaceAnalyzer();

        Directory aTomDirectory =new RAMDirectory();

        Directory nTOzDirectory=new RAMDirectory();

//建立2个索引

        IndexWriter aTomwriter=new IndexWriter(atomDirectory,analyzer,true);

        IndexWriter nTozwriter=new IndexWriter(aTozDirectory,analyzer,true);

        

        for (int i=0;i<anaimals.length;i+){

            Document doc=new Document();

            String animal=animals[i];

            doc.add(Filed.Keyword("animal",animal));

            if (animal.compareToIgnoreCase("n")<0){

               aTomWriter.addDocument(doc);//前半部分索引a-m

            }else{

               nTozWriter.addDocument(doc);//后半部分索引 n-z

            }

        }

       

        aTomwriter.close();

        nTozwriter.close();

        searchers=newIndexsearcher[2];

        searcher[0]=new IndexSearcher(aTOmDirectory);

        searcher[1]=new IndexSearhcer(nTOzDirectory);

 

      

        }

        public void testMulti() throws Exception{

            MultiSearcher searcher=new MultiSearcher(searchers);

            //对2个索引进行搜索

            Query query=new RangeQuery(new Term("animal","h"),new Term("animal","t"),true);

            Hits hits= searcher.search(query);

        }

 }

3、ParallelMultiSearcher多线程搜索

    搜索操作为每个Searchable分配一个线程,直到所有线程都完成其搜索。基本搜索和进行过滤的搜索是并行执行的。

   lucene通过RMI为用户提供搜索远程索引功能。

   RMI服务器绑定了一个RemoteSearchable的实例,它和IndexSearcher、MultiSearch一样,实现Searchable接口

 

1)把文档按26个字母切分为26个索引。服务器端向客户端提供2个RMI调用

public class SearchServer{

    private static final String ALPHABET="abcdefghijklmnopqrstuvwxyz";

    public static void main(String[] args) throws Exceptino{

        if (args.length!=1){

            System.err.printLn("Usage:Searchserver<basedir>");

            System.exit(-1);

        }

        String basedir=args[0];

//为每个索引建立一个IndexSearcher对象

        Searchable[] searchables=new Searchable[ALPHABET.length()];

        for (int i=0;i<ALPHABET.length;i++){

             searchables[]=new IndexSearcher(new File(basedir,""+ALPHABET.charAt(i)).getAbsolutePath());              

        }    

//注册可供客户端调用服务的端口

        LocateRegistry.createRegistry(1099);

//使用     multiSearcher完成所有索引的搜索  

        Searcher multiSearcher=new MultiSearcher(searchables);

        RemoteSearchable multiImpl=new RemoteSearchables(multiSearcher);

        Naming.rebind("//localhost/LIA_Multi",multiImpl);//注册RMI方法

//使用   parallelSearcher   完成搜索 

        Searcher parallelSearcher=new ParallelMultiSearcher(searchables);

        RemoteSearchable parallelImpl=new RemoteSearchables(parallelSearcher);

        Naming.rebind("//localhost/LIA_Parallel",parallelImpl);//注册RMI方法       

        System.out.println("server started");

        }

    }

2)客户端

public class SearchClient{

   private static HashMap searchercache=new HashMap();

  

   public static void main(String[] args) throws Exception{

      if (args.length!=1){

         System.err.println("Usage:SearchClient <query>");

         System.exit(-1);

      }

      String word=args[0];

      for (int i=0;i<5;i++){

          search("LIA_Multi",word);//调用服务器的multi方法搜索

          search("LIA_Multi",word);//调用服务器的multi方法搜索       

      }      
  }

  private static void search(String name,String word) throws Exception{

      TermQuery query=new TermQuery(new Term("word",word));

      MultiSearcher searcher=(MultiSearcher) searcherCache.get(name);//检查缓存中是否有该搜索器,该搜索器是带缓存功能的

      if (searcher==null){//没有该搜索,则生成新的搜索

           searcher=new MultiSearcher(new Searchable[]{lookupRemote(name)});

           searcherCache.put(name,searcher);

      }

//统计时间

      long begin=new Date().getTime();

      Hits hits=searcher.search(query);

      long end=new Date().getTime()

     

      ...........

      ...........

      //不要关闭searcher对象

     }

     private static  Searchable lookupRemote(String name) throws Exception{

          return (Searchable) Naming.lookup("//localhost/"+name);

     }

 

http://blog.sina.com.cn/s/blog_3dc2673e0100c3ok.html

}



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



关于UED团队管理的那点事

$
0
0

昨天晚上跟几个做设计leader的朋友聊天,对方谈起目前的工作情况和难处,我听了后觉得很有感触。如果换做一年前的我在这里,也一定也会遇到同样的处境。

“产品经理觉得交互设计师的出现增加了一个环节,效率降低了”;

“我们设计好的方案产品经理挑了一部分做,然后功劳就变成他们的了”;

“我们辛辛苦苦设计的方案产品经理总是不采用,等上线后发现体验不好大领导又责怪我们,说UED是怎么做的设计”;

“我们想致力于用户体验的改进,比如整体统一弹框效果等等,但是产品经理觉得优先级不高,无限期的拖后”;​

“我们的人手总是不够,一跟领导提领导就很不高兴,让我们想办法提升效率”;​

“我们特别的辛苦,经常九点以后下班,周六还要上班,但是大领导觉得体验上并没有得到明显的提升。我觉得特别没有价值感”

“​UED的kpi该如何设定,如何衡量工作成果?”

……

​这些问题无非就是在说一件事: 设计leader在业务导向的部门找不到自己以及团队存在的价值。我介绍了一些自己在阿里的管理经验,给了他们一些建议(当然很多都是阿里倡导的设计文化)。

一、以业务为出发点,而非设计

其实做设计管理和做设计一样,都不能靠拍脑袋或是个人喜好,而是要先了解产品、业务方向,再制定合理的规划。明显感觉到​朋友多少还是站在设计师的角度上考虑问题,而不是从业务的角度考虑,也没有想去了解产品经理的目标是什么。这样团队的辛苦产出经常被产品经理无限期押后,或是根本不采用也就不足为奇了。

对业务部门来说,业务的高速发展是最重要的,能排在最高优先级的都是生死攸关的问题。设计师最重要的是发挥自己的专业能力,帮助业务方解决业务问题,和业务共同成长。

在阿里,我们的工作并没有受到特别的限制:视觉设计师可以做用户调研;交互设计师可以提出业务方向的建议;产品经理可以画原型;技术可以去见客户。​只要你有兴趣和能力,做任何事情都有机会,前提是围绕部门的业务目标。

那么怎样了解业务情况呢?我建议朋友​找各条业务线的产品经理了解近期的业务发展情况,产品经理的业务目标、优先级判断标准以及短期、中期、长期的计划等,还有就是他们希望UED能够支持些什么。可以定期把这些内容汇总成表格的形式,这样对业务会有一个通盘的了解,制定设计方向才会心中有数。

二、整体的规划,而非零散的执行

对业务情况有足够的了解后,设计管理者要结合具体专业能力、围绕业务目标制定相关策略(任何岗位都适用)。比如我们在设定目标时不仅考虑对业务的支持情况,还要考虑UED的公共支撑能力(规范、组件库、培训等),以及设计创新和沉淀(最好是和业务相关的,比如我们最近在做的B端产品设计研究)。

我给朋友讲了最近我正在做的团队规划:从团队目标(围绕业务的项目支持、公共支撑、设计创新、设计沉淀等等)到具体事情、人的分配、时间规划、再到对人的培养计划。​这样既体现了UED的专业能力,又强调了对业务的重要作用。朋友说他们现在就是缺乏这种整体的规划,而是散点式的执行,所以效率不高又非常累,每个设计师的目标也不够明确,大家都做得非常盲目。​所以作为管理者,心中不仅要有张业务大图,更要有张围绕业务目标的设计策略图。

三、提升附加值,砍掉价值低的工作

好了,现在有了业务大图,有了设计策略,还有了具体的工作规划,后面就要看怎么安排设计师的工作了。在这里我提几点和工作优先级相关的建议。

阿里一直强调设计师要做高附加值的工作。在阿里,运营类的工作基本上都是外包出去的,一些简单的banner可以通过在线工具快速配置,不需要设计师亲自动手。未来,设计师也会逐渐减少对创意要求不高的界面设计工作,取而代之的是利用设计规范、使用组件库等方式。设计师会把更多精力集中在难以被替代的高附加值事情上,比如品牌设计的研究及落地、通过沉淀能力及规范做好公共支撑等。

​另外,对于一些业务探索期的产品,建议由产品经理来做交互设计,设计师可根据情况给予建议。因为对于一个新业务来说,理解成本是比较高的,产品经理要反复对设计师讲解自己的理念(有这个功夫都不知道自己做了多少版demo了),最后得到的结果还不见得是正确的,然后又要反复讲解;而对于一个全新的事物,设计师想一步到位设计好也是不太可能的。但如果有一个粗糙的产品或原型摆在那里,优化起来就简单多了,也便于参考前后数据对比来验证设计师的价值。所以在业务探索期,不建议交互设计师全程参与,性价比不高。

再有,不建议设计师长期加班。设计是一件充满创造性的事情,太劳累必然影响效率及质量。如果一个团队整天都在加班,领导就要想想工作安排是否合理了,是不是可以考虑像我前面所说的,把一些收效不大又很占用时间的工作砍掉,把精力放到更有价值的事情上。​

四、平衡产品经理和设计师的关系

我很庆幸在我们部门,产品经理和设计师是完全平行、平等的关系,因为只有老板说了算。当然这种情况有利有弊,好处是每个人都是平等的,都有机会展示才华、实现价值,不会因为产品经理个人能力欠缺而导致巨大的失误,设计师也不必处处受产品经理压制;但坏处也显而易见:职责不清晰,事情推动起来效率较低,工作积极性受影响等等。

但可以肯定的是,不管任何一种组织形式,都不是完美的,适合业务情况的就是最好的。​设计师是产品经理的下游环节也好,不是也罢,只要记住用ceo的心态围绕业务目标统筹规划,利用自己的专业能力为组织做出最大的贡献,那一切问题定能迎刃而解。所以在工作的过程中,要把产品经理当作最好的合作伙伴,而不是敌人或是竞争者。如果你觉得很难融入到产品团队,对产品经理有很多怨言,那很可能是因为你对业务的贡献还不够大,或是你没有想过如何通过你的能力帮助他让业务进展得更顺利,而只是从自己的专业角度考虑。

最后想说的是,人如鱼,组织如水。把水当作赖以生存之根本才能如鱼得水。设计师说到底是通过服务好内部组织来服务好外部客户,否则专业能力再强价值也无法得到体现。希望未来所有的设计师都能真正的在工作中体会如鱼得水的美妙感觉!

欢乐关注公众号“津乐道”


 

Spring单实例、多线程安全、事务解析

$
0
0
 在使用Spring时,很多人可能对Spring中为什么DAO和Service对象采用单实例方式很迷惑,这些读者是这么认为的:
    DAO对象必须包含一个数据库的连接Connection,而这个Connection不是线程安全的,所以每个DAO都要包含一个不同的Connection对象实例,这样一来DAO对象就不能是单实例的了。
    上述观点对了一半。对的是“每个DAO都要包含一个不同的Connection对象实例”这句话,错的是“DAO对象就不能是单实例”。
    其实Spring在实现Service和DAO对象时,使用了ThreadLocal这个类,这个是一切的核心! 如果你不知道什么事ThreadLocal,请看 深入研究java.lang.ThreadLocal类》:。请放心,这个类很简单的。
    要弄明白这一切,又得明白事务管理在Spring中是怎么工作的,所以本文就对Spring中多线程、事务的问题进行解析。

Spring使用ThreadLocal解决线程安全问题:

    Spring中DAO和Service都是以单实例的bean形式存在,Spring通过ThreadLocal类将有状态的变量(例如数据库连接Connection)本地线程化,从而做到多线程状况下的安全。在一次请求响应的处理线程中, 该线程贯通展示、服务、数据持久化三层,通过ThreadLocal使得所有关联的对象引用到的都是同一个变量。 
    参考下面 代码,这个是《Spring3.x企业应用开发实战中的例子》,本文后面也会多次用到该书中例子(有修改)。
public class SqlConnection {
    //①使用ThreadLocal保存Connection变量
    privatestatic ThreadLocal <Connection>connThreadLocal = newThreadLocal<Connection>();
    publicstatic Connection getConnection() {
       // ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection,
       // 并将其保存到线程本地变量中。
       if (connThreadLocal.get() == null) {
           Connection conn = getConnection();
           connThreadLocal.set(conn);
           return conn;
       } else {
           return connThreadLocal.get();
           // ③直接返回线程本地变量
       }
    }
    public voidaddTopic() {
       // ④从ThreadLocal中获取线程对应的Connection
       try {
           Statement stat = getConnection().createStatement();
       } catch (SQLException e) {
           e.printStackTrace();
       }
    }
}
    这个是例子展示了不同线程使用TopicDao时如何使得每个线程都获得不同的Connection实例副本,同时保持TopicDao本身是单实例。

事务管理器:

    事务管理器用于管理各个事务方法,它产生一个事务管理上下文。下文以SpringJDBC的事务管理器DataSourceTransactionManager类为例子。
    我们知道数据库连接Connection在不同线程中是不能共享的,事务管理器为不同的事务线程利用ThreadLocal类提供独立的Connection副本。事实上,它将Service和Dao中所有线程不安全的变量都提取出来单独放在一个地方,并用ThreadLocal替换。而多线程可以共享的部分则以单实例方式存在。

事务传播行为:

    当我们调用Service的某个事务方法时,如果该方法内部又调用其它Service的事务方法,则会出现事务的嵌套。Spring定义了一套事务传播行为,请参考。这里我们假定都用的REQUIRED这个类型:如果当前没有事务,就新建一个事务,如果已经存在一个事务,则加入到的当前事务。参考下面例子(代码不完整):
@Service( "userService")
public class UserService extends BaseService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private ScoreService scoreService;
   
    public void logon(String userName) {
        updateLastLogonTime(userName);       
        scoreService.addScore(userName, 20);
    }

    public void updateLastLogonTime(String userName) {
        String sql = "UPDATE t_user u SET u.last_logon_time = ? WHERE user_name =?";
        jdbcTemplate.update(sql, System. currentTimeMillis(), userName);
    }

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/nestcall/applicatonContext.xml" );
        UserService service = (UserService) ctx.getBean("userService" );
        service.logon( "tom");

    }
}

@Service( "scoreUserService" )
public class ScoreService extends BaseService{
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void addScore(String userName, int toAdd) {
        String sql = "UPDATE t_user u SET u.score = u.score + ? WHERE user_name =?";
        jdbcTemplate.update(sql, toAdd, userName);
    }
}
    同时,在配置文件中指定UserService、ScoreService中的所有方法都开启事务。
    上述例子中UserService.logon()执行开始时Spring创建一个新事务,UserService.updateLastLogonTime()和ScoreService.addScore()会加入这个事务中,好像所有的代码都“直接合并”了!

多线程中事务传播的困惑:

    还是上面那个例子,加入现在我在UserService.logon()方法中手动新开一个线程,然后在新开的线程中执行ScoreService.add()方法,此时事务传播行为会怎么样?飞线程安全的变量,比如Connection会怎样?改动之后的UserService 代码大体是:
@Service( "userService")
public class UserService extends BaseService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private ScoreService scoreService;

    public void logon(String userName) {
        updateLastLogonTime(userName);
        Thread myThread = new MyThread(this.scoreService , userName, 20);//使用一个新线程运行
        myThread .start();
    }

    public void updateLastLogonTime(String userName) {
        String sql = "UPDATE t_user u SET u.last_logon_time = ? WHERE user_name =?";
        jdbcTemplate.update(sql, System. currentTimeMillis(), userName);
    }

    private class MyThread extends Thread {
        private ScoreService scoreService;
        private String userName;
        private int toAdd;
        private MyThread(ScoreService scoreService, String userName, int toAdd) {
            this. scoreService = scoreService;
            this. userName = userName;
            this. toAdd = toAdd;
        }

        public void run() {
            scoreService.addScore( userName, toAdd);
        }
    }

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/multithread/applicatonContext.xml" );
        UserService service = (UserService) ctx.getBean("userService" );
        service.logon( "tom");
       }
}
    这个例子中,MyThread会新开一个事务,于是UserService.logon()和UserService.updateLastLogonTime()会在一个事务中,而ScoreService.addScore()在另一个事务中,需要注意的是这两个事务都被事务管理器放在事务上下文中。
    结论是:在事务属性为REQUIRED时,在相同线程中进行相互嵌套调用的事务方法工作于相同的事务中。如果互相嵌套调用的事务方法工作在不同线程中,则不同线程下的事务方法工作在独立的事务中。
 

底层数据库连接Connection访问问题

     程序只要使用SpringDAO模板,例如JdbcTemplate进行数据访问,一定没有数据库连接泄露问题!如果程序中显式的获取了数据连接Connection,则需要手工关闭它,否则就会泄露!
    当Spring事务方法运行时,事务会放在事务上下文中,这个事务上下文在本事务执行线程中对同一个数据源绑定了唯一一个数据连接,所有被该事务的上下文传播的放发都共享这个数据连接。这一切都在Spring控制下,不会产生泄露。Spring提供了数据资源获取工具类DataSourceUtils来获取这个数据连接.
@Service( "jdbcUserService" )
public class JdbcUserService {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Transactional
    public void logon(String userName) {
        try {
            Connection conn = jdbcTemplate.getDataSource().getConnection();           
            String sql = "UPDATE t_user SET last_logon_time=? WHERE user_name =?";
            jdbcTemplate.update(sql, System. currentTimeMillis(), userName);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void asynchrLogon(JdbcUserService userService, String userName) {
        UserServiceRunner runner = new UserServiceRunner(userService, userName);
        runner.start();
    }

    public static void reportConn(BasicDataSource basicDataSource) {
        System. out.println( "连接数[active:idle]-[" +
                       basicDataSource.getNumActive()+":" +basicDataSource.getNumIdle()+ "]");
    }

    private static class UserServiceRunner extends Thread {
        private JdbcUserService userService;
        private String userName;

        public UserServiceRunner(JdbcUserService userService, String userName) {
            this. userService = userService;
            this. userName = userName;
        }

        public void run() {
            userService.logon( userName);
        }
    }

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/connleak/applicatonContext.xml" );
        JdbcUserService userService = (JdbcUserService) ctx.getBean("jdbcUserService" );
        JdbcUserService. asynchrLogon(userService, "tom");
    }
}
    在这个例子中,main线程拿到一个UserService实例,获取一个Connection的副本,它会被Spring管理,不会泄露。UserServiceRunner 线程手动从数据源拿了一个Connection但没有关闭因此会泄露。
    如果希望使UserServiceRunner能拿到UserService中那个Connection们就要使用DataSourceUtils类,DataSourceUtils.getConnection()方法会首先查看当前是否存在事务管理上下文,如果存在就尝试从事务管理上下文拿连接,如果获取失败,直接从数据源中拿。在获取连接后,如果存在事务管理上下文则把连接绑定上去。
    实际上,上面的代码只用改动一行,把login()方法中获取连接那行改成就可以做到:
Connection conn = DataSourceUtils. getConnection( jdbcTemplate .getDataSource());    
   需要注意的是:如果DataSourceUtils在没有事务上下文的方法中使用getConnection()获取连接,依然要手动管理这个连接!
    此外,开启了事务的方法要在整个事务方法结束后才释放事务上下文绑定的Connection连接,而没有开启事务的方法在调用完Spring的Dao模板方法后立刻释放。

多线程一定要与事务挂钩么?

    不是!即便没有开启事务,利用ThreadLocal机制也能保证线程安全,Dao照样可以操作数据。但是事务和多线程确实纠缠不清,上文已经分析了在多线程下事务传播行为、事务对Connection获取的影响。

结论:

  • Spring中DAO和Service都是以单实例的bean形式存在,Spring通过ThreadLocal类将有状态的变量(例如数据库连接Connection)本地线程化,从而做到多线程状况下的安全。在一次请求响应的处理线程中, 该线程贯通展示、服务、数据持久化三层,通过ThreadLocal使得所有关联的对象引用到的都是同一个变量。 
  • 在事务属性为REQUIRED时,在相同线程中进行相互嵌套调用的事务方法工作于相同的事务中。如果互相嵌套调用的事务方法工作在不同线程中,则不同线程下的事务方法工作在独立的事务中。
  • 程序只要使用SpringDAO模板,例如JdbcTemplate进行数据访问,一定没有数据库连接泄露问题!如果程序中显式的获取了数据连接Connection,则需要手工关闭它,否则就会泄露!
  • 当Spring事务方法运行时,就产生一个事务上下文,它在本事务执行线程中对同一个数据源绑定了一个唯一的数据连接,所有被该事务上下文传播的方法都共享这个连接。要获取这个连接,如要使用Spirng的资源获取工具类DataSourceUtils。
  • 事务管理上下文就好比一个盒子,所有的事务都放在里面。如果在某个事务方法中开启一个新线程,新线程中执行另一个事务方法,则由上面第二条可知这两个方法运行于两个独立的事务中,但是:如果使用DataSourcesUtils,则新线程中的方法可以从事务上下文中获取原线程中的数据连接!

http://www.xuebuyuan.com/1771946.html

http://www.oschina.net/question/87799_11230



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Viewing all 11804 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>