注册
环信即时通讯云

环信即时通讯云

单聊、群聊、聊天室...
环信开发文档

环信开发文档

Demo体验

Demo体验

场景Demo,开箱即用
RTE开发者社区

RTE开发者社区

汇聚音视频领域技术干货,分享行业资讯
技术讨论区

技术讨论区

技术交流、答疑
资源下载

资源下载

收集了海量宝藏开发资源
iOS Library

iOS Library

不需要辛辛苦苦的去找轮子, 这里都有
Android Library

Android Library

不需要辛辛苦苦的去找轮子, 这里都有

个推TechDay-基于容器的微服务架构实践

报名地址:活动报名

QQ图片20170815164443.jpg



30442782453566008.jpeg




30802784413319012.jpeg



报名地址:活动报名

基于办公的 IM 的基础设计

   现在的 IM 在设计上是基于会话的,多个人可以组成一个会话,相当于一个聊天室,当一个人加入到一个会话后,就可以看到从加入开始之后这个聊天室里所有参与人的发言。有的 IM 会把两人对话也抽象成同一个东西,也可能出于优化的考虑把双人对话特殊处理。 所以,这...
继续阅读 »
   现在的 IM 在设计上是基于会话的,多个人可以组成一个会话,相当于一个聊天室,当一个人加入到一个会话后,就可以看到从加入开始之后这个聊天室里所有参与人的发言。有的 IM 会把两人对话也抽象成同一个东西,也可能出于优化的考虑把双人对话特殊处理。

所以,这些 IM 在操作界面上会有一个会话列表:表现出来会是联系人名单、聊天群列表等等。选中会话列表中的项目,进入会话查看聊天记录、发言,就是这类 IM 的使用逻辑。

我认为,这种对即时通讯的抽象方式,其实是不适合办公环境的。和日常个人社交环境不同,办公群体其实是一个相对关系密切的团体,我们通常不会拉黑一个同事不让他给你发消息,也不会拒收公司发的通告,也不会因为一个同事平常不和你打交道就拒绝建立联系。项目组里的讨论,也未见得是多么保密的事情,需要防止隔壁组的同事旁听。你也很少会在办公 IM 上和妹子私聊谈人生理想。

我们这几年使用腾讯的 RTX 作为公司办公使用,我就感受到了太多这类设计缺陷。比如,有同事找我有事,我忽略了他的私聊信息;找人一般在对方活跃的项目群组里吼;程序群沦为了日常扯淡的位置,常常同时讨论着不同的问题,线索及其混乱。“群”这个设计,我在很多年前就思考过 ,我一直觉得需要在根本上换个角度看待社交聊天的需求。

我现在的想法是这样的:

作为办公 IM ,我们不应该基于固定会话(群)来设计,而应该是“通知”和“话题”。

所谓通知,就是有人发起了一条消息,他需要把这条消息传达给某些对象,对象可以是人,也可以是某个组织:比如程序、游戏项目组、等等。

组织并非是群那样的聊天室,而仅仅是一个标签,由人来关注标签,而不是去组织这个聊天室里有多少听众。

而话题,则是由消息或旧话题衍生而来。任何通知消息、话题内部消息,都可以变成一个新话题。话题也可以包含在一则消息里转发给某个对象。

用户的客户端应该把所有的通知按时间线排列在一起,呈现在同一个地方。也就是说,无论是谁给我发消息(默认就是通知)都应该投递在一起,而不是像现在 RTX 那样只是在系统托盘里闪烁提醒、也不是微信 qq 那样,联系人名单上多出一个小红点。

而一旦我回复一个通知消息,其实就把这则通知转化成了一个话题,在时间线上,话题内的消息是归属在一起的。同一时刻,无论你的思维切换多么快,其实在短时间内你只能聚焦在一个话题上,所以客户端界面是很容易表达的,把当前话题展开在主界面(通知的时间线)即可,切换话题后自然可以折叠起来。

话题并不是聊天室、它更像是论坛的帖子。一个话题可以有很多人参与(至少发言一次),更应该支持更多的人浏览。我们不应该按聊天室的思路:用户只有在加入聊天室的那一刻开始,才能收到后续的消息,而应该像论坛那样,他只是打开了这个话题帖,可以随时聊天过去到现在发生的事情。话题内的任何一个消息,都可以由用户展开为新话题,老话题对新话题只是一个引用链接而已,并不需要有层级关系,我们也可以把任意一个话题或尚未转化为话题的消息转发出去,如果有人对他评论,就生成了新话题。

话题是一个有时效性的东西,对于办公来说,如果一个话题超过 8 小时没有新的消息,就可以认为这个话题已经结束了。但是事后我们依然可以对老话题浏览,或是继续讨论,而继续讨论就是生成的一个新话题了。

只要生成话题足够方便,每个用户的主时间线上就只会有不多的通知消息,信息传达更为有效。而管理每天的消息、检索旧消息也有很强的时间线。不像现有的 IM 群聊天,每天的聊天内容会被自然的组织成话题,这些话题上标识了参与人数、归属的组织的 tag 、继承于哪个父话题或通知、经历的时间段、衍生出哪些后续话题,等等。

即使是两个人之间的对话,也同样应该是话题的形式,而不应该把消息直接组织成一长串的聊天历史。话题未必有明确的主题,只是一种更自然的信息聚合形式而已。

对于办公场合来说,有意个最重要的优势:用户群有足够的自律。基于这种自律,我认为上面的思路若实现出来很容易推广使用。

在自律之外,或许还需要一些权限管理。这些权限管理应该是相对松散简单的,主要是限制用户订阅特定组织的 tag (比如一般员工不能订阅管理层的 tag ),限制围观特定话题(比如两人之间的私聊话题默认就是不对第三人开放权限的),话题可以锁定不准转发。权限设置的细节还需要进一步推敲。
 
本文转自云风的BLOG,原文地址http://blog.codingnow.com/ 收起阅读 »

【移动战略说 · 第一期】智能硬件产品开发从0到1

   据GSMA预期,到2020年,全球互联设备将突破270亿,移动互联设备有望达到105亿,新的市场机遇将进一步增多。自动上报家中燃气数据、远程开关气阀、精准透明计费、自动调节远程定时控制路灯等,基于新一代物联网的新型智慧产品正在走入我们的生产生活。 ...
继续阅读 »
   据GSMA预期,到2020年,全球互联设备将突破270亿,移动互联设备有望达到105亿,新的市场机遇将进一步增多。自动上报家中燃气数据、远程开关气阀、精准透明计费、自动调节远程定时控制路灯等,基于新一代物联网的新型智慧产品正在走入我们的生产生活。

   开发一款智能硬件产品涉及的环节很多。本次活动,APICloud联合华强聚丰和智石科技,从样品生产、App开发和近场通讯技术在智能硬件中的应用跟大家分享智能硬件产品如何快速从0到1!
 
活动概况
【活动时间】2017年8月19日(周六),13:30-16:30
【面向人群】制造业企业、智能硬件管理层、产品负责人、技术负责人,其他相关从业者
【活动咨询/合作】请加微信:appdev1,备注819
活动议程
【13:30-14:00】签到
【14:00-14:40】如何快速完成样品生产
内容概要:产品硬件开发者希望快速拿到样品,进行方案验证和调试,发现设计问题,快速进行方案修正,以便进入下一开发环节,完成开发工作。怎样解决这些困难?怎样才能让生产环节快速顺利完成样品生产?
【14:40-15:20】自主研发or外包?智能硬件App开发指南
内容概要:现在市场上智能硬件往往需要一款App配合,无论是控制设备还是查看数据。企业不但需要考虑成本,还要兼顾产品体验。本环节APICloud将会为大家介绍App开发技术如何选型;自己招团队与找外包的对比;以及项目准备、开发、测试、上线各个阶段可能遇到的问题和注意事项。
【15:20-16:00】室内精准位置物联网络搭建
【16:00-】幸运抽奖&自由交流
分享嘉宾


30972779689807524.jpeg




30242778644313753.jpg




30852779689957552.jpeg



报名地址活动报名 收起阅读 »

【环信征文】程序员为灾区祈福,我听说过的语言差不多都有了

8月8日21时19分在四川阿坝九寨沟县发生7.0级地震,地震发生后社会各界纷纷为灾区祈福。使用各种语言的程序员也不甘示弱吗,争先恐后地用自己的语言为灾区祈福。我听说过的语言差不多都有了。 ~trace("ActionScript程序员为灾区祈福!&...
继续阅读 »
8月8日21时19分在四川阿坝九寨沟县发生7.0级地震,地震发生后社会各界纷纷为灾区祈福。使用各种语言的程序员也不甘示弱吗,争先恐后地用自己的语言为灾区祈福。我听说过的语言差不多都有了。

~trace("ActionScript程序员为灾区祈福!");
~TEXT_IO.PUT_LINE ("Ada程序员为灾区祈福!");
~<% Response.Write("ASP程序员为灾区祈福!") %>
~MsgBox(1,'','AutoIt程序员为灾区祈福!')
~BEGIN { print "AWK程序员为灾区祈福!" }
~echo 'Bash程序员为灾区祈福!'
~? "BASIC程序员为灾区祈福!"
~WRITES ("BCPL程序员为灾区祈福")
~Print "BlitzBasic程序员为灾区祈福!"
~print "BOO程序员为灾区祈福!"
~printf("C程序员为灾区祈福!");
~cout << "C++程序员为灾区祈福!"<<endl;
~System.Console.WriteLine("C#程序员为灾区祈福");
~PROCEDURE DIVISION.DISPLAY "COBOL程序员为灾区祈福!".STOP RUN.
~echo Linux Shell程序员为灾区祈福!
~io.put_string("Eiffel程序员为灾区祈福!")
~hello_world() -> io:fwrite("Erlang程序员为灾区祈福!").
~." Forth程序员为灾区祈福!" CR
~WRITE(*,*) 'Fortran程序员为灾区祈福!'
~HTML程序员为灾区祈福!
~System.out.println("Java程序员为灾区祈福!");
~<%=("JSP程序员为灾区祈福!")%>
~(format t "Lisp程序员为灾区祈福!")
~print "Lua程序员为灾区祈福!"
~Print["Mathematica程序员为灾区祈福!"]
~Nuva程序员为灾区祈福!
~NSLog(@"Objective-C程序员为灾区祈福!");
~print_endline "OCaml程序员为灾区祈福!";
~writeln('Pascal程序员为灾区祈福!');
~say "Perl程序员为灾区祈福!";
~<?= "PHP程序员为灾区祈福!"?>~
~write("Pike程序员为灾区祈福!");
~write("Prolog程序员为灾区祈福!").
~#!/usr/bin/env pythonprint("Python程序员为灾区祈福!")
~say "REXX程序员为灾区祈福!"
~#!/usr/bin/rubyputs "Ruby程序员为灾区祈福!"
~Om:"Sbyke Laborana程序员为灾区祈福!"
~(display "Scheme程序员为灾区祈福!")
~sed -ne '1s/.*/sed程序员为灾区祈福/p'
~writeln("Seed7程序员为灾区祈福!");
~Transcript show: 'Smalltalk程序员为灾区祈福!'
~TextWindow.WriteLine("Small Basic程序员为灾区祈福!")
~OUTPUT = "SNOBOL程序员为灾区祈福!"
~print 'SQL程序员为灾区祈福!'
~println("Swift程序员为灾区祈福!")
~#!/usr/local/bin/tclputs "Tcl程序员为灾区祈福!"
~? "TScript程序员为灾区祈福!"
~put "Turing程序员为灾区祈福!"
~<includeonly>UNIX-style shell程序员为灾区祈福!</includeonly>
~ShowMessage('Delphi程序员为灾区祈福!');
~Print "Visual Basic程序员为灾区祈福!"
~? "Visual FoxPro程序员为灾区祈福!"
~QLabel label("X11程序员为灾区祈福!");
~alert("JavaScript程序员为灾区祈福!");
~(PostScript程序员为灾区祈福!) show
~println("Scala程序员为灾区祈福!")
~println("Kotlin程序员为灾区祈福!");
~调试输出(“易语言程序员为灾区祈福!”) 收起阅读 »

【环信征文】请不要说自己是Android程序员

经常在网上看到各种标题为“Android程序员”、“Java程序员”、“PHP程序员”、“C/C++程序员”的招聘帖子,但这种招聘方式,很难找到好的人才。语言只是一种工具,对一个聪明的程序员来说,用没用过什么工具主要是由他原来的工作需要决定,并不能代表他全部的...
继续阅读 »
经常在网上看到各种标题为“Android程序员”、“Java程序员”、“PHP程序员”、“C/C++程序员”的招聘帖子,但这种招聘方式,很难找到好的人才。语言只是一种工具,对一个聪明的程序员来说,用没用过什么工具主要是由他原来的工作需要决定,并不能代表他全部的技能。

软件行业是一个非常强调人的价值的行业,价值就体现在有效的推动产品前进,而语言只是实现这个价值的工具。

(W[}_`X~BVTQM{3A`@HN4JU.png



一个软件产品往往涉及很多方面的知识,比如网络、数据库、Cache、编译环境工具等。如果这些必要基础知识不足,很难很好的独立完成一个产品的某个部分。

另一方面,一个人的聪明程度、对新知识的好奇心、自我驱动意识、为问题找到最佳解决方案的决心,才是他能不能成为一个好程序员的关键。举个例子,我的一位在某米当cto学长的告诉我,有位同事本来是服务器端以C#语言为主做开发的,完全没有过android开发经验,但他表现出对移动开发很有兴趣,并且在做服务器端开发时,表现出良好的学习能力,后来我把他调到Android组,负责android SDK和APNs相关的工作,结果只花了几个星期,Android SDK的稳定性大幅提升,解决了多个致命问题。

不要仅仅把自己定位为某种语言的程序员,说自己是Java程序员,C#程序员,Python程序员等等。一方面会限制自己的发展,一方面对团队整体的能力提升也不利。几乎所有的语言都有它自己的适用场景,在合适的地方用合适的语言,才能极大的提升生产效率。
正确的做法是,首先要有良好的基础知识,深刻的掌握2~3门语言,然后适用于不同场景的语言要了解概念。基础知识包括各种计算机原理、数据方面的知识,在学校没认真学的,现在有时间也要补充。语言方面比如掌握了C/Java,那C++/Python/Bash/Javascript/CSS等都可以了解下概念,至少要理解在一个完整的产品链里,它们分别适用于哪个环节。

标题用“请不要说自己是Android程序员”没有贬低Android程序员的意思,Java是目前被采用得最多的语言,主要用Java的程序员里,也是有大量牛人。另外,同样的,也不要说自己是C程序员、Python程序员。

 古语说的好,“书中自有黄金屋”。这句话告诉我们书籍是学习知识的第一大根本方向。在与Java相关的专业书籍中,相继记述着关于这门课程的基础知识及进阶内容,先易后难、步步深入,非常适合初学者去学习。
  虚心求教不可少。
往往很多高深莫测,经验丰富,功力深厚的人都埋藏在自己的身边,不容自己去察觉。所以如果大家想要从事Java行业,不妨请假身边从事过该行业的朋友,求学不在高低贵贱之分,只要碰到不懂的地方,就去虚心求教,世界这么大,而且这门知识又是如此让人追捧,比自己懂的人岂止千百?从这些人身上自己一定能够受益匪浅。

现在以Java语言为主的工作非常之多,另外在学校里就以学习Java为主的人也越来越多。但是,从学校就以学习Java这种高级语言为主的人,很多基础知识比较薄弱。高级语言掩盖了太多细节,提高了生产力,但在学习阶段,却不利于基础知识累积。

MSBFLGP1I{8KVLTCJ9)Q46.png


“Nicholas C. Zakas是全世界最著名的JavaScript程序员之一,之前是在雅虎将近工作5年。三年前,他写了一篇长文,回顾自己的职业生涯,提到七个对他来说最重要的建议,希望对大家的职业生涯有帮助:

1、 不要别人点什么,就做什么

我的第一份工作,只干了8个月,那家公司就倒闭了。我问经理,接下来我该怎么办,他说:"小伙子,千万不要当一个被人点菜的厨师,别人点什么,你就烧什么。不要接受那样一份工作,别人下命令你该干什么,以及怎么干。你要去一个地方,那里的人肯定你对产品的想法,相信你的能力,放手让你去做。"

我从此明白,单单实现一个产品是不够的,你还必须参与决定怎么实现。好的工程师并不仅仅服从命令,而且还给出反馈,帮助产品的拥有者改进它。

2、 推销自己




我进入雅虎公司以后,经理有一天跟我谈话,他觉得我还做得不够。

"你工作得很好,代码看上去不错,很少出Bug。但是,问题是别人都没看到这一点。为了让其他人相信你,你必须首先让别人知道你做了什么。你需要推销自己,引起别人的注意。"

我这才意识到,即使做出了很好的工作,别人都不知道,也没用。做一个角落里静静编码的工程师,并不可取。你的主管会支持你,但是他没法替你宣传。公司的其他人需要明白你的价值,最好的办法就是告诉别人你做了什么。一封简单的Email:"嗨,我完成了XXX,欢迎将你的想法告诉我",就很管用。

3、 学会带领团队
工作几年后,已经没人怀疑我的技术能力了,大家知道我能写出高质量的可靠代码。有一次,我问主管,怎么才能得到提升,他说:"当你的技术能力过关以后,就要考验你与他人相处的能力了。"
于是,我看到了,自己缺乏的是领导能力,如何带领一个团队,有效地与其他人协同工作,取到更大的成果。

4、 生活才是最重要的
有一段时间,我在雅虎公司很有挫折感,对公司的一些做法不认同,经常会对别人发火。我问一个同事,他怎么能对这种事情保持平静,他回答:"你要想通,这一切并不重要。有人提交了烂代码,网站下线了,又怎么样?工作并不是你的整个生活。它们不是真正的问题,只是工作上的问题。真正重要的事情都发生在工作以外。我回到家,家里人正在等我,这才重要啊。"
从此,我就把工作和生活分开了,只把它当作"工作问题"看待。这样一来,我对工作就总能心平气和,与人交流也更顺利了。
5、 自己找到道路
我被提升为主管以后,不知道该怎么做。我请教了上级,他回答:"以前都是我们告诉你做什么,从现在开始,你必须自己回答这个问题了,我期待你来告诉我,什么事情需要做。"
很多工程师都没有完成这个转变,如果能够做到,可能就说明你成熟了,学会了取舍。你不可能把时间花在所有事情上面,必须找到一个重点。
6、 把自己当成主人

我每天要开很多会,有些会议我根本无话可说。我对一个朋友说,我不知道自己为什么要参加这个会,也没有什么可以贡献,他说:"不要再去开这样的会了。你参加一个会,那是因为你参与了某件事。如果不确定自己为什么要在场,就停下来问。如果这件事不需要你,就离开。不要从头到尾都静静地参加一个会,要把自己当成负责人,大家会相信你的。"
从那时起,我从没有一声不发地参加会议。我确保只参加那些需要我参加的会议。
7、 找到水平更高的人
最后,让我从自己的经历出发,给我的学员一个建议。
"找到那些比你水平更高、更聪明的人,尽量和他们在一起,吃饭或者喝咖啡,向他们讨教,了解他们拥有的知识。你的职业,甚至你的生活,都会因此变得更好。"
 我的感受是IT行业是当今社会的热门行业,说它热门是因为它的发展潜力是无穷的,所以我们能进入到这个行业是一种幸运。在此,我特别感谢上家公司带我教我前辈们和师傅,在学习期间给了我莫大的帮助,在我遇到困难时,给我很大的鼓励和帮助,让我更加有信心坚持下来,找到工作。最后送大家一句话:相信自己没有选错行业,相信自己有立足的能力,为自己制定明确的目标,然后努力地去学习、体会、感悟、进步!
  收起阅读 »

如何阅读计算机科学类的书

   作为一个研发工程师,无论你是否喜爱阅读,相信你都一定读过不少关于计算机技术的书籍。这其中不乏《21天学会JAVA》这样的语言入门书籍,也有《算法导论》这样的专题书籍,也有《人月神话》这样关于软件管理学的实用性的书籍。也许你已经读过他们中的大...
继续阅读 »
 

QQ图片20170810185201.png


 作为一个研发工程师,无论你是否喜爱阅读,相信你都一定读过不少关于计算机技术的书籍。这其中不乏《21天学会JAVA》这样的语言入门书籍,也有《算法导论》这样的专题书籍,也有《人月神话》这样关于软件管理学的实用性的书籍。也许你已经读过他们中的大部分,也许你现在还在不断地购入新的书籍来补充你的知识库。但请稍等一下,你是否思考过这样的问题,面对大量的计算机科学书籍,你是否都真正读懂了它们呢?有多少本书,当你将他放在书架上之后,就再也没有重新打开过?有多少知识是真正被存储在你的大脑中,并随时可以提供调用?拿到一本书后,高效阅读的正确姿势的什么?如果你有以上的疑惑,那么接下来,我们将一起探讨一个问题,如何阅读一本计算机科学类书籍。

阅读的四种层次

   首先,我们先要学会如何阅读。你可能会觉得不可思议,我已经接受过高等教育,怎么可能还不会阅读。然而可悲的是,现代教育体系中,恰恰忽略了对阅读能力的训练。我们在初中之后,阅读水平就几乎没有机会再得到提升。总体来说,阅读分为四种层次,分别是:

  • 基础阅读

  • 检视阅读

  • 分析阅读

  • 主题阅读


 
   这其中的概念来源于莫提默·J·艾德勒和查尔斯·范多伦的著作《如何阅读一本书(How To Read A Book)》,这里我必须对其中的概念做简单的总结,以便在后续的篇幅中,我们能统一对阅读名词的理解。

基础阅读
   当我们完成中学学业后,我们中的绝大部分人,都已经掌握了基础阅读的能力。在这个层次中,我们关心的是,书里的每句话是什么意思。这是一个最基础的层次。
检视阅读
   检视阅读,我们也可以称之为快速阅读。快速浏览全书,了解书的主题,架构全书,提出核心问题。这并不是很新鲜的概念,但很多人可能并没有思考过,为什么要做检视阅读。检视阅读作用是为了帮助我们筛选这本书是否值得阅读,同时为接下来的分析阅读打下基础。在这个层次中,我们关心的是,这本书在讲什么。
 
分析阅读
   分析阅读是一个更为高级的阅读层次,目标让我们能充分理解本书,与作者对话。其中包含了多个阶段,这里不再详述,有兴趣的同学可以研读原著。
 
主题阅读
   当我们跨越过分析阅读后,这本书已经被我们掌握。此时,我们会就相同的主题,阅读不同的书籍,找出其中关联与矛盾,倾听不同的作者的不同声音,从而对某个主题产生更加深刻的认识。这个阶段,我们关注的不再是某一本书,而是一个具体的问题。
 
计算机科学书籍的特征
   原著中针对不同类型的书籍,给予了不同的阅读建议。但由于所著时间很早,就计算机科学类图书的阅读建议,在书中并没有专门设计章节阐述。根据我的阅读经历,深感计算机科学类书籍,较其他类型图书有着其独特性:

单本书籍的信息量大
   相较其他学科,绝大多数计算机科学类书籍并不是以得出结论并且论证结论为核心,而偏重于阐述方法和解释原理。有很多计算机书籍旨在剖析某个系统。这里的系统不仅仅指代诸如操作系统这样的实体系统,还包括一门语言或者一套管理方法论这样的理论系统。而系统通常是由多个部分组成的综合体,这其中势必包含不同组成部分的不同细节,信息量之大可见一斑。
 
注重实践
   计算机科学是一门实用性的学科。这里的实用性可以理解为,计算机科学诞生的目的就是为了解决实际问题。因此,几乎所有的计算机科学书籍,都是以指导实践为目标而作。
 
更新速度快
   计算机科学的更迭速度可以准确地被描述为日新月异。有些技术很快地火爆起来,又很快地消亡,所以有些书也就跟着很快地淹没在时代的进程中。
 
分类细致但同质度高
   计算机科学对自己有着过分清晰的划分,不同的技术之间往往边界清晰。我们很少见操作系统和数据库系统在同一本书中论述,也不常见集不同语言之成的大作。由于领域划分细致,相同领域的书籍,多数时候往往论述的是同样的主题。
 
阅读计算机科学书籍的误区
   绝大多数读者的错误意识在于把所有的书籍都认为是层层推进的论述过程。这样的阅读经验一旦沿用在计算机科学类书籍中,就会感觉举步维艰。前文说过,大多数的计算机书籍都是在剖析系统,一个系统又是由许多相互关联的部分组成。解读这类书籍,如同拆解一个机械,我们在拆解的过程,常常会犯下这些错误。

通读全书
   在你的头脑中没有对全书的结构有整体了解的情况下,从头至尾通读全书,意味着试图从细节窥视一个系统的全貌。这是一种低效的读书方式。当读到中落时,你会因为没有全局概念,而迷失在各种细节中,以至于完全失去了阅读的方向和目标。
 
跳过序言
   序言往往是很多人忽略的内容,似乎序言只是重复了正文的内容。而正因为如此,序言以简短精炼的语言,为你分解了整本书的架构,帮助你把握系统的整体。这项工作本来应该是读者在阅读全书之前的必备工作,绝大多数的作者都已经帮你完成了,而你需要做的仅仅是认真的阅读它。
 
脱离实践
   前文说过,计算机科学类书籍重视实践,脱离了实践,往往就不能完全理解书中所述的理论和方法,过目就忘,纸上谈兵。
 
忽视基础
   封装在计算机的世界中是一个非常重要的概念。计算机的发展史,总的来说就是一部封装史:将底层不断包装,提供简单的调用方式,由此不断的扩展计算机的边界和能力。新的技术层出不穷,而他们的很多所依赖的环境和系统,从设计之初就没有发生过质的变化。
有时,在追逐新的技术之前,深入了解他们所在的系统;在学习新的算法之前,掌握好其基础的数学原理。只有牢固的基础才能支撑足够结实的上层建筑。
 
阅读计算机科学书籍的建议
   当了解阅读误区后,你们是不是已经发现阅读这类书籍的核心原理呢?那就是将整本书当做一个系统,从整体到局部,层层递进,逐步剖析。根据这个核心原理,我总结了一些好的实践方式。
 
检视阅读
   当你拿到一本计算机科学书籍,第一步就应该快速浏览序言和目录,然后用检视阅读的方式整理出整本书的大纲。这样,你对这本书是介绍理论还是关注实践,所属什么分类,哪些问题是本书将会讨论,而哪些问题是不被详细讨论的,这些信息你都会有整体上的认知。这时,你就可以很轻松地判断,这本书值不值的阅读,哪些内容是你已经熟知的,哪些内容是你关注的重点,这样做阅读的效率将会大大的提高。
   如果从来没有使用过这种阅读方式,开始实践时,会受到一定的心理上的阻力。可能你对某个专有名词完全没有概念,以至于整章的内容都模棱两可。这时,你应该坚持继续阅读,对不甚理解的内容,先记住有这样的概念。绝大多数的时候,经过检视阅读后,过程中的问题都会有所释怀,剩下依然没有明白的内容,视其重要性,再决定是否对其进行分析阅读。
 
提取问题
   当你了解了整本书的全貌,一般而言,你会发现,有些章节你已经熟悉,有些章节你全然不知。这时就要对这些章节进行分析阅读。分析阅读的很多步骤和方法在《如何阅读一本书(How To Read A Book)》有详细的介绍,这里不展开细说。但有时,你在阅读的过程中,会发现阅读的兴趣在下降。信息量愈大,阅读的动力愈弱,最后你就迷失在信息的汪洋之中。
我们应该如何避免这样的信息疲劳呢?答案就是去掉冗余的干扰信息。在上一个建议中,我们强调了检视阅读的重要性。那检视阅读的成果是什么呢?那就是你对每个部分(不一定是书中给你划分的章节)所提出的问题,也可以称之为阅读目标。而你要做的就是,找到这些问题的答案,完成自己的阅读目标。
   这样做过滤了很多作者认为重要,其实和你关心的主旨没有联系的信息,减少了信息疲劳。同时,不同部分之间有关联的问题,可以帮助你更好的串联全书阐述的核心概念,把握整本书的主要脉络。
例如,我在阅读《深入理解计算机系统》的异常控制流时,就提出这样的问题:进程是如何管理内存?而部分的答案,在下一个章节虚拟内存中。当我解答这个问题时,我就会将这两个分离的章节的内容,通过一个问题联系在一起,加深了自己的理解。
 
持续重读
   一本经典优秀的计算机科学书籍,值得你反复的阅读。不要觉得整本书我已经完全理解,就再也不需要重新回顾阅读了。因为此类书籍存在大量信息,而这些信息并没有必要占据我们大脑有限的记忆存储空间。我们要做的就是认真做好第一条建议,当我们需要使用这些书籍解决问题的时候,能第一时间在其中找到我们需要的信息。毫不夸张的说,计算机科学类的书籍生来就是供人反复翻阅的。
 
鉴别烂书
   作为阅读爱好者,谁能说自己没读过几本烂书呢。在计算机科学这个类别中,烂书的比例一点也不比其他学科低。信息重复(抄袭),结构混乱,论证不清晰(作者对某个技术一知半解)等等,都是烂书的特征。关于烂书,我们要做的就是第一时间将其鉴别出来,然后放到自己的黑名单中。具体如何鉴别烂书,由于本篇幅太长,我可能会新开一篇文章单独讨论。
 
结语
   以上就是我对于如何阅读计算机科学类书籍的理解。本来想缩短些篇幅,但最后还是决定保留那些我觉得应该详细论述的部分。毕竟这篇文章的初心并非是厕所读物,而是一个阅读爱好者认真地与读者探讨一个严肃的话题。如果可以,我希望在通过我不断地探索,阅读能力的持续提升,我还能在此宝地继续这个话题,完善我的理论。
我在下面列出我认为经典优秀的计算机科学书籍,也欢迎大家补充,排名不分先后。 收起阅读 »

【环信征文】没有几样强迫症,不配自称程序员

程序员是一类特殊的群体,因为与电脑交流多于与人交流,所以他们成为了强迫症的高发群体。我国的程序员人数已经达到了 500 万人,比世界上一半的国家人口都多。任何小问题乘以 500 万都是很惊人的,程序员的强迫症成了不可忽视的社会现象。我将程序员高发的强迫症分为十...
继续阅读 »
程序员是一类特殊的群体,因为与电脑交流多于与人交流,所以他们成为了强迫症的高发群体。我国的程序员人数已经达到了 500 万人,比世界上一半的国家人口都多。任何小问题乘以 500 万都是很惊人的,程序员的强迫症成了不可忽视的社会现象。我将程序员高发的强迫症分为十大类。

0 数字强迫症

数字强迫症的症状是数数从 0 开始,这是中了大多数编程语言的毒导致的。

数字强迫症的另一种症状就是对二进制有执念,很多程序员员都认为世界上有 10 种人:一种懂二进制,另一种不懂。

数字强迫症的晚期症状是认为 256 和 1024 等 2 的 n 次方很完美,常常有 1kg == 1024g 或者 1L = 1024mL 的错觉。

1 格式强迫症

格式强迫症的症状是对代码的缩进要求极其严格,代码务必美观。即使遇到缩进不能再整齐的代码,如果有的缩进是 1 个Tab而有的缩进是 4 个Space都会浑身难受。

当代的IDE做到了Enter换行自动缩进和Ctrl + Alt + L整理格式,大大减少了格式强迫症的发病率,格式强迫症也顺理成章发生了变异。格式强迫症最常见的变异就是从只追求左边的对齐变成了也追求右边的对齐,患者会把IDE的字体都换为等宽字体。

2 命名强迫症

命名强迫症的症状是对类、接口、变量、常量、方法、枚举等的命名既追求简短,又追求直白,希望能一目了然——但一般来说简短和直白就如同物美和价廉一样不可兼得。当命名强迫症作为输入强迫症的并发症出现时,经常会因为一列对象的命名字数不一致而有砸电脑的冲动。

中国的程序员有种特殊的命名强迫症,就是不喜欢拼音命名,看见前任遗留代码中的拼音命名就会火冒三丈。

命名强迫症的另一种症状是不喜欢看到笼统的命名,例如data_1、msg_2、view_3甚至干脆就是i、j、k(方法内部循环除外);更不喜欢看到有误导的命名,比如突然发现这么一句注释:“//以下所有left代表右,所有right代表左”。

命名强迫症的晚期症状就是对驼峰命名法有莫名其妙的痴迷,就连新注册网站的用户名都要严格遵循驼峰命名法。

3 保存强迫症

在Eclipse + NetBean的时代,IDE没有自动保存功能,很多程序员养成了随时Ctrl+S的习惯。而当代IDE基本上都有自动保存的功能,他们的习惯,这就是保存强迫症。

前端程序员上网的时候会不断Ctrl+S。如果网页有文本编辑器,在Ctrl+S的时候会弹出对话框:“文字已成功保存于某年月日”,然后会莫名紧张:“怎么又弹窗了?”好久才反应过来自己在上网。

保存强迫症并非一无是处,患者玩单机游戏会自带“随时使用S/L大法”技能,会大大避免前功尽弃的可能。

4 维修强迫症

维修强迫症的症状是在U盘或者移动硬盘里保存各类杀毒软件、木马库、系统镜像、越狱工具、Android root工具以便随时维修电脑和手机。病因是被七大姑八大姨“你不是程序员吗怎么连电脑/手机都不会修?”逼的。

维修强迫症没有晚期症状,三舅妈的大姑姐找程序员帮她修智能洗衣机等loT设备或者四叔的小舅子找程序员把科学计算器刷成Android系统时就把程序员直接逼死了。

5 硬件强迫症

硬件强迫症的症状是程序员对自己工作有关的硬件要求极高。以下常见的致病硬件的逼格和获得的成本递增:

移动硬盘:移动硬盘是线下的Git,保存无数代码、文档以及秘钥。在“考研资料/政治/马克思主义哲学/第十八章/课程H”下面也隐藏着不为人知的东西。

机械键盘:噼里啪啦的手感和不菲的身价,HHKB是每个程序员的信仰,买不起HHKB的程序员会用国产的机械键盘凑合着用。

iMac或者Macbook Pro:苹果的电脑性能都非常好,编译程序速度非常快。更重要的一点:OS X系统不能玩LOL,避免了浪费写代码的时间。

双显示器:对于前端程序员来说,双显示器不仅是装逼用的,一台竖屏显示器显示WebStorm,而另一台横屏显示器显示Chrome对编程很有帮助的。显示器的价格并不昂贵,昂贵的是能呈 120 度角摆两台显示器的桌子下面的地皮在北上广深杭写字楼里的租金。

人体工程学座椅:五花八门的不正常办公家具包括人体工程学座椅和支持站立编程的桌子等,美其名曰保护程序员的颈椎、腰、屁股和前列腺,受到程序员喜爱的真实原因你懂的。

程序员鼓励师:大多数程序员渴望但不曾拥有过的硬件是只属于自己的程序员鼓励师,换句话说就是在你写代码时红袖添香的女朋友。

6 白盒强迫症

白盒强迫症的常见症状是看见代码就想优化一下。说程序员只怕“error”不怕“warning”是非常错误的,很多程序员见不得黄字和中划线,也见不得蓝色的“// TODO”。

白盒强迫症很多时候都是有益的,可以让代码变得整洁,隐藏的漏洞也会减少。

白盒强迫症的晚期患者每次打开一个网页都要右键查看源代码,已经无法正常上网。

7 黑盒强迫症

黑盒强迫症的常见症状是每次看见闭源的软件都想研究一下里面的原理,再想想自己能不能做得更好。比如用支付宝扫码支付的时候想的是识别二维码、通信加密、支付安全等原理;或者乘坐电梯时看着电梯的按钮面板(现实世界的UI)会开始思考电梯的调度算法,比如多个实例之间状态可以互相影响,还有一些优先级、加速度、预判方面的东西。

黑盒强迫症的晚期症状是看见现实世界中办事的流程都想用算法知识优化一下,常见的是想着如何优化公司报销和升职的审批流程;再举个反面例子,看《人民的名义》或《官场现形记》时都想着怎么优化贪官和奸商的“办事”流程。

8 收藏强迫症

收藏强迫症的症状是在GitHub上看见好源码必star,技术博客上看到好文章必然收藏,没有收藏功能的个人站也要加入收藏夹。收藏虽多,但不会再看。明知如此,还感觉不收藏就会吃亏。

9 身份强迫症

身份强迫症的早期症状就是头脑中“程序员 == 我自己”的概念根深蒂固,看到和程序员有关的话题都要打开看一下,尽管大多数程序员不会因为应勤是程序员就看《欢乐颂2》,但你打开本文一定是因为本文标题有“程序员”。读完本文的患者还会把自己和同事们作为一个数组,本文中 10 种强迫症作为另一个数组,然后在自己的大脑里做一个递归,查查自己和同事们分别中了几枪。

身份强迫症的晚期症状是把现实世界中见到的一切理解为IT知识,忘记了自己在职场外怎么做一个正常人:走火入魔的患者偶然有一天没有在家写代码,出门看见太阳想到的是“单例模式”,看见双胞胎想到的是“拷贝”,看到摩天轮想到的“循环”,看到排队想到的是“队列”。

身份强迫症进入日薄西山阶段的症状是患者已经无法用人类的语言进行交流了,QQ聊天时每句话的最后都要家一个“;”,没错,是半角的分号;更有甚者还会把脏话用“/*”和“*/”框起来,以为对方就看不见了;看见卖西瓜就只买一个包子的程序员听说学姐留学归来,会四门语言的第一反应是问她那四门语言是Java、PHP、Python和JavaScript还是C、C++、C#和Objective-C。

身份强迫症进入回光返照阶段的情况是试图把别的语言、工具、领域的程序员改造成自己同行的程序员,曾高呼“PHP是最好的语言”的程序员在移动互联网时代改行Android后会纠结怎么把iMac或者Macbook Pro屏幕背面的Apple形状的灯改成Android形状的。

如果你读到最后,不但一枪没中,也没把自己身边的朋友和同事套在这十大强迫症上做个递归,那么你一定不是一个程序员。 收起阅读 »

战狼3剧透!!!

       冷锋回到中国后尽管已经恢复了军职,还受到了人民的爱戴,冷锋拥有了以前不可能拥有的荣耀,但是他忘不了的还是龙小云,几年后,他费劲千辛万苦终于得到了龙小云的消息,大家都以为龙小云在几年前被反政府武装的雇佣兵杀死了,令人庆幸的是龙小云...
继续阅读 »
   

16783307241313752924.jpg



   冷锋回到中国后尽管已经恢复了军职,还受到了人民的爱戴,冷锋拥有了以前不可能拥有的荣耀,但是他忘不了的还是龙小云,几年后,他费劲千辛万苦终于得到了龙小云的消息,大家都以为龙小云在几年前被反政府武装的雇佣兵杀死了,令人庆幸的是龙小云被南非的救援中心救了下来。

   冷锋的到消息后立马跑去南非找龙小云,可是在欧洲臭名远扬的雇佣兵也知道了这个消息,原来老爹的幕后大咖就是他的父亲飞鱼,飞鱼为了给儿子报仇雪恨竟也来带走龙小云,还出动了大批的先进专备,于是又一轮的世纪大战又开始了。

   冷锋在期间困难重重但他还是咬牙坚持下去了,后来冷锋救回龙小云后,他们决定回到北京生活,不久后他们在北京开了互联网公司,还亲自找环信学习即时通讯的集成,生意做得风生水起!从此,过上了幸福的生活!!![鼓掌][鼓掌][鼓掌]冷锋为了感谢环信,还将那个子弹头送给了环信!你也想他一样嘛!?赶紧报名参加环信的Alpha计划培训吧。

   环信Alpha计划北京场报名已满,参加的小伙伴请选择上海和深圳场,报名地址环信Alpha计划报名 收起阅读 »

看看30万程序员怎么评论:在网吧写代码是怎样一种体验?

今天要给大家分享一个有趣的话题,在网吧写代码是怎样的体验,你想想,你吃着泡面唱着歌,突然电脑就死机了!哈哈,这是一种悲哀 ,我自己没有在网吧写过代码,但是看了论坛上的小伙伴们说的这些趣事,还是挺有意思的: ...
继续阅读 »
今天要给大家分享一个有趣的话题,在网吧写代码是怎样的体验,你想想,你吃着泡面唱着歌,突然电脑就死机了!哈哈,这是一种悲哀 ,我自己没有在网吧写过代码,但是看了论坛上的小伙伴们说的这些趣事,还是挺有意思的:

TIM截图20170810110817.png




TIM截图20170810110919.png




TIM截图20170810110954.png




TIM截图20170810111108.png



TIM截图20170810111131.png



TIM截图20170810111158.png



TIM截图20170810111300.png



116c7861bf9f02ba648912446deae8b0_b.jpg


最后再来给程序员提几点建议:

1.写代码好像没试过,不过那个时候做个人网站,家里没有网,写好代码winzip打包,拷软盘里。找网吧前台小妹放软盘(那个网吧只有前台的电脑有软驱)。共享,在我的机器上拷出来,ftp上传到免费空间。周围和我同龄的孩子们基本都是qq 红警 星际之类的。我一直因为不会打游戏也不会去聊天室和妹纸聊天没法和他们融在一起。在所有人的鄙视甚至类似于今天的类似“装逼”等词汇的鄙视中,完成工作。唯一欣慰的是有几个女生看到我的网站会投来些许崇拜的目光(也仅仅是些许)。

2.程序员工作空闲之余也就是逛逛论坛,上上网,聊聊天。下班时间宅在家里,打打游戏,写写代码,写写博客,很少锻炼身体,以至于某天的头条就有可能是某某公司大老猝死了,所以大伙们懂的。 收起阅读 »

2017年的八大顶级开源项目

摘要:本文介绍了在开源界比较有名的八个项目。如果你对其中的某个项目不了解的话,赶快来学习一下吧。以下是译文。原文:Top Open Source Projects In 2017 作者:William Belk  翻译:雁惊寒 今天,让我们一起来...
继续阅读 »
摘要:本文介绍了在开源界比较有名的八个项目。如果你对其中的某个项目不了解的话,赶快来学习一下吧。以下是译文。
原文:Top Open Source Projects In 2017
作者:William Belk 
翻译:雁惊寒


2397007-9583dc6fe2d5d8f2.png


今天,让我们一起来看一下2017年开源界的八个顶级玩家。下面列出的几个开源项目反映了开源社区在过去几年来发展的成熟度。这里列出的所有项目(Lab41除外)都是在2014年及以后发布的,每个项目都在各自的社区里发挥着重要的作用。
 
TensorFlow

Google的TensorFlow发布于2015年,它是一个可扩展的基于神经元的机器学习库。我们可以使用TensorFlow构造流水线来对图像和文本这类东西进行分类,甚至还可以构造出更复杂的问题场景,例如“X类型的用户会买Y吗?”。

许多行业目前对于机器学习的研究或应用还只是流于表面。尽管在我们的意识中一直认为自己可以用AI来实现任何目的,但机器学习还是会受到计算资源和数据训练的限制。在未来的几年里,数据的训练可能依然是大家忽略的问题,许多人低估了能够解决复杂问题所需的可靠训练数据的数量。也就是说,机器学习是为真实场景服务的,并且会很快出现在我们每天使用的很多应用程序之中,隐匿于应用程序的底层。我们还将看到许多有趣的项目和展望,这些来源于机器学习的东西说明了目前还存在着太多的公开数据可供使用。

如果你想了解更多有关TensorFlow的内容,请查阅这篇来自于Google的博文

Hyperledger

Hyperledger发布于2015年,由Linux基金会赞助,旨在推动区块链技术在未来商业的应用。 Hyperledger开发了模块化的工具,可以作为分布式区块链基础来解决各种商业问题,包括合同安全、匿名账户和身份管理,以及基于社区的历史交易记录。

Hyperledger已经使得IBM、思科、红帽、VMWare,摩根大通、富国银行、埃森哲等公司对其产生了巨大的兴趣。

Node.js / React Native

我们得承认 Node.js 社区的胜利,它现在无处不在。Node.js使得新一代程序员在服务器端编码方面摆脱了束缚。我们在谈论React Native的时候,不能不承认Node.js将继续在软件工程领域保持强劲的势头,特别是对于消费者和移动应用。

React Native于2015年推出,并且许下了一个美好的愿望:只使用一个代码库就能将应用程序部署到多个平台上。例如,使用单个代码库来为苹果iOS、Android和Web编译应用程序。

这为什么是一个诱人的想法呢?对于消费者网站而言,我们可以使用最常用的语言:javascript。我们无需把团队根据不同语言的特点拆分开来,例如javascript、ruby/python/php、java、Objective C。我们可以快速地进行构建。我们可以利用本地设备组件来解决像图像处理这样的“硬骨头”。我们可以只维护单个应用程序,然后将其核心应用分发到每一个需要的平台上。

React Native还有哪些酷炫的地方呢? 应用广泛,就像Facebook、特斯拉、Airbnb、Instagram、腾讯、彭博和Uber一样。

Dolores
 
Dolores是一套“可定制”、“可私有化部署”的OA办公系统,一套完整的企业通信解决方案,一个完整的企业沟通工具(以下简称企业IM),支持以下几个功能:IM消息服务、组织架构管理、工作流集成。

   公司想自己开发一套IM系统应该从哪里开始呢? 企业通讯录怎么保持同步呢? 企业通讯录的权限管理应该怎么做?
   三个关于OA办公系统的究极问题,从开源的OA办公项目-Dolores(朵拉)诞生迎刃而解了。Dolores项目遵循Apache Licence 2.0 开源协议,可以直接拿来用,也可以修改代码来满足需要并作为开源或商业产品发布/销售。

Kubernetes

当Google在2014年发布Kubernetes的时候,这个项目的前途看起来很光明。该项目的目标非常远大,试图解决在多个层次、组和角色之间对分布式服务器容器协调的问题。例如,一家公司可能在四个城市的三个环境层(开发、预备、生产)上运行了200多个容器,这管理起来非常头疼。

我们必须要承认,在过去的几年里,虚拟服务器协作在大型企业的复杂部署中占有举足轻重的地位。这是Amazon Web Services目前如此成功的其中一个原因。即使像Docker这种虚拟化的容器部署逐渐兴起,但问题依然存在。公司必须依靠脆弱的开源项目、昂贵的专有平台或者依靠广泛的内部工具来管理虚拟集群和容器。

在大规模的容器协作方面,Kubernetes似乎明显处于领先地位,并与纽约时报、高盛、SoundCloud、Box、Comcast 和 易趣 等用户建立了合作关系。

Lab41
Lab41是一个“挑战实验室”,在那里美国情报界与他们在学术界工业界中的同行一起处理大数据。


虽然Lab41本身并不是一个开源项目,但它提出了一些有趣的问题,进而引出了一些开源代码,并对开源社区做出了一定的贡献。它展示了开源原则、风险投资和政府优先事项的交叉点,这是一个非常独特的东西。

Vault
Vault可以保护、存储和严格控制对现代计算中的令牌、密码、证书、API密钥和其他机密内容的访问。


如果你看看下面这张有关全球数据泄露的交互信息图的话,就能马上理解为什么Vault如此重要了。

2397007-76533d0347436258.png



凡信
凡信是一个开源的高仿微信项目,截止目前已经更新了3个大版本,从基础的好友聊天做起,到朋友圈、红包功能等功能愈发完善,直播、阅后即焚等新功能层出不穷,整个项目完全免费,Android/ios/服务端所有代码全部开源。

 由于凡信的1.0和2.0都是基于环信SDK 2.x系列开发,而当前环信官方力推的是3.x的系列SDK,在此背景下,作者决定将凡信迁移至3.x的demo上。迁移的同时,对存储机制和网络接口做了一定的优化。与此同时,针对时下火热的直播APP,结合环信的聊天室功能和ucloud,做了两个模块-观看直播和进行直播;针对IM场景中常见的发红包/抢红包,集成了由环信提供的红包SDK,对于想做红包以及账户管理的开发者,是一种非常值得推荐的解决方案,一是开发者不用头疼于安全问题,以及开发中逻辑不严谨导致的资金转移丢包的问题。 收起阅读 »

春华秋实,环信Android/ios V3.3.4SDK发布,同一账号可在电脑手机间互传消息与文件

春华秋实,听说秋天APP和环信更配!环信发布了V3.3.4版本SDK ,同一账号可在电脑手机间互传消息与文件,并增加消息撤回接口和回调,同时Android端更新了新版环信推送(HMS)。 Android V3.3.4 2017-08-04新功能 ...
继续阅读 »
春华秋实,听说秋天APP和环信更配!环信发布了V3.3.4版本SDK ,同一账号可在电脑手机间互传消息与文件,并增加消息撤回接口和回调,同时Android端更新了新版环信推送(HMS)。



微信图片_20170807161714.jpg



Android V3.3.4 2017-08-04新功能
  • 新增加API请查看链接3.3.4api修改
  • 增加接口支持获取历史消息(消息漫游);
  • 新增PC与移动端互发消息和文件的功能;
  • 增加消息撤回的接口和回调;
  • 支持华为新版推送功能(HMS);
ios V3.3.4 2017-08-04新功能:
  • 新增:PC端和手机端登录同一个账号,两个设备之间互发消息;
  • 新增:消息漫游,从服务器分页获取历史消息;
  • 新增:消息撤回。
功能修复及优化:
  • 优化删除一组会话时,回调只返回一次;
  • iOS SDK不再支持i386;
  • 修复录制音频文件时,音频权限判断。

 版本历史:Android SDK更新日志  ios SDK更新日志
下载地址:SDK下载
收起阅读 »

月薪五千和五万销售的区别:一只丑桔引发的大单子(环信真实案例改编)

​​   这是一个初冬的早晨。王向东迈着轻快的步伐,走进了“黄桃园”集团大楼,直奔物业管理公司CEO陶福成办公室。与陶总交换名片后,陶总看着名片,抬头说:“你就是那个什么环信公司的销售经理?你在电话上说有一笔大生意要谈?简单说说吧,我只有十分钟时...
继续阅读 »
​​ 

timg.jpg


 这是一个初冬的早晨。王向东迈着轻快的步伐,走进了“黄桃园”集团大楼,直奔物业管理公司CEO陶福成办公室。与陶总交换名片后,陶总看着名片,抬头说:“你就是那个什么环信公司的销售经理?你在电话上说有一笔大生意要谈?简单说说吧,我只有十分钟时间。”陶总抬手看了眼手表。

王向东从包里拿出一只丑桔,放到大班台上,说:“这是丑桔,想必陶总吃过。”陶总微微点了下头。“我要和陶总谈的生意与丑桔有关。”陶总好奇地问:“我一个物业公司,怎么会和丑桔生意有关呢?”

“我先问陶总一个经营上的问题。现在由于人工费用上涨很快,物业公司从业主收来的物业费却多年没有做相应的调整,物业公司的利润逐年下滑,甚至出现亏损,不知是不是属实?”陶总点了下头,心里却想你个毛头小子还和我说盈亏,真不知天高地厚。

“所以物业公司不得不想别的办法,拓展收入来源来弥补物业费的亏空。”陶总一笑:“所以你想推荐丑桔生意?”王向东指着台上的丑桔说:“是的!咱们算笔账。陶总物业公司管理着三个高档小区,一共有3万2千住户。”陶总眼睛从半眯状到睁大状。“丑桔是新开发的一个水果品种,口味独特,很受欢迎,超市里卖到24块每公斤。如果能以18块每公斤卖给您的住户,想必一定卖的很好。如果直接和原产地进货,进货价格是10块每公斤,这样的话毛利是8块每公斤。假设有1万5千住户每户购买一箱20公斤,总共30万公斤,毛利240万。”陶总深深点了下头:“240万不少,但对于我这样的物业公司来说,还真不是什么了不起的收入。”

“如果我说丑桔贡献240万,精品东北大米贡献300万,陕西红富士苹果贡献300万。。。。。。这些收入合起来贡献2000万毛利,够不够大?”“够大!但是我要把这个生意做成,需要店面,仓库,运输,配送,押款。。。。。。费用支出多大,你知道吗?”

“知道。但如果我有办法把这些费用降到零呢?”陶总瞪大了眼睛:“什么办法?”“就是利用移动互联技术,构建客服平台,起到一石三鸟作用。”“哪三鸟?”“一是解决咱们物业管理老本行与住户的交流和住户服务请求和相应;二是形成电子商务平台,网上推广产品;三是网上缴费,既交物业费,又是电子商务资金流通道。”

陶总站起来,拉住王向东的手:“快说说,你能帮我建设这个什么客服平台吗?”“可以,环信就是这方面的专家。”

陶总快步走到门口,对秘书说:“马上通知总裁办主任,客服部主管,IT部主管,财务部主管到我这里开会!”

几分钟后,主管们到齐。陶总说:“来,跟大家介绍一下这位小兄弟,王向东,他可是给我们带来了好东西,先听听他的介绍。”王向东站起来谦逊地个跟每个主管打了招呼,才坐下简要地介绍了刚才跟陶总交流的内容。陶总站起来说:“王兄弟带来的方案,揭开了困扰我们好长时间的难题,有了这个客服平台,可以大幅度提高我们的物业服务质量,同时开辟了扩大收入的渠道,是个非常有价值的建议。我要求你们和小王兄弟一起尽快拿出方案,做出预算,在2个月内上线!”

所有主管都响亮地答应下来,同时心里在猜测这位“小王兄弟”后台有多硬,是陶总的什么关系?

没过几天,方案出来了,预算也出来了。一期先建设即时通讯软件平台和客户交互平台,建设费用320万;二期建设智能客服机器人系统,建设费用180万;采用vpc形式,每年支付环信托管费用50万;环信提供战略和业务咨询,每年咨询费40万。

一个由丑桔引起的“大单子”就这么发生了!(由环信真实销售案例改编,文中均为化名) 收起阅读 »

环信移动客服v5.23已发布,支持添加多个不同功能网页插件

摘要:环信移动客服v5.23版本更新,发布了新版网页插件,支持在客服工作台创建多个网页插件,分别设置每个网页插件的功能,并对网页聊天窗口的实际效果进行预览。新版网页插件集成更便捷,只需在页添加一行代码,并支持随时预览网页插件的实际效果。客服模式 客服同事...
继续阅读 »
摘要:环信移动客服v5.23版本更新,发布了新版网页插件,支持在客服工作台创建多个网页插件,分别设置每个网页插件的功能,并对网页聊天窗口的实际效果进行预览。新版网页插件集成更便捷,只需在页添加一行代码,并支持随时预览网页插件的实际效果。
客服模式

客服同事消息提醒


当收到客服同事的消息时,会话页面“客服同事”页签名称旁显示红点,提醒客服有未读消息。 

001.png


支持在工单页面新建工单

当客户在线咨询的问题需要后续跟进处理而会话已结束时,客服可以在工单页面为客户创建工单,由工单系统的专家继续为客户解答问题。

进入工单页面,点击右上角“新建工单”按钮,填写工单相关信息,并保存。

注:工单为增值服务,需要管理员进入“管理员模式 > 工单 > 申请工单”页面,申请开通工单功能。 

002.png


管理员模式

新版网页插件


网页插件配置方式升级。支持在客服工作台创建多个网页插件,分别设置每个网页插件的功能,并对网页聊天窗口的实际效果进行预览。

新版网页插件有如下特点:

  • 多个网页插件:支持添加多个网页插件,并设置不同的功能,用于不同的网页。

  • 极简集成:支持在客服工作台设置网页插件的UI、功能,只需在您的网页添加一行代码即可。

  • 效果预览:支持随时预览网页插件的实际效果。

  • 兼容性:兼容旧版网页插件的代码集成方式,升级新版后,不影响已有的网页聊天窗口功能。



升级新版网页插件

1. 进入“管理员模式 > 渠道管理 > 网页”,点击右上角“升级新版网页插件”按钮。 

003.png

2. 了解新版网页插件功能,确认升级至新版网页插件。点击“马上升级”按钮。 

004.png

注意:升级至新版网页插件后,无法退回至旧版网页插件页面,但原有的配置方式依然生效。

新版网页插件依然支持桌面聊天窗口和H5网页两种方式:

桌面聊天窗口

在“管理员模式 > 渠道管理 > 网页”页面,将网页插件的代码复制并粘贴到您的网站的</body>标签之前,保存并发布。

H5网页

在浏览器地址栏输入以下地址,并将{configId}替换为您的网页插件页面显示的configId的值。 
http://kefu.easemob.com/webim/im.html?configId={configId}
关于新版网页插件更详细的使用说明,请查看网页渠道集成(新版)

技能组成员管理优化

技能组页面改版,支持根据客服昵称搜索技能组成员,根据客服在线状态筛选技能组成员,以及批量更新技能组成员。

  • 搜索:在搜索框中,输入客服昵称或登录邮箱,系统自动显示搜索到的技能组成员;

  • 筛选:在成员列表右上方,勾选客服的在线状态(默认全部勾选),系统自动显示处于该状态的技能组成员。




005.png


  • 批量更新:点击“成员管理”,并点击右上角“代码模式”,进入代码模式。在该页面添加或删除客服的登录邮箱地址(用换行隔开),用于批量更新技能组成员。




006.png

欢迎语菜单指定技能组

新增欢迎语菜单指定技能组功能。可以设置欢迎语菜单,并将菜单项与技能组绑定。当客户点击菜单项时,将会话分配给对应技能组。

设置方式:进入“管理员模式 > 设置 > 系统开关”页面,打开“欢迎语菜单指定技能组”开关,添加菜单项,并将菜单项与技能组绑定。

注:暂时仅网页访客端支持显示欢迎语菜单。欢迎语菜单指定技能组功能为入口指定的一种,需要在“设置 > 会话分配规则 > 路由规则”页面,将“入口指定”设置为优先。 

007.png

网页访客端示例: 

008.png

通过关键字匹配提醒客服

设置正则表达式用于匹配客户消息中的关键字,当匹配到关键字时,在会话窗口显示预设的消息提醒客服。该功能可用于固定回复的提示、敏感信息的提醒,等等。

设置方式:进入“管理员模式 > 设置 > 关键字匹配”页面,点击“添加关键字匹配规则”,填写规则名称、设置规则条件(正则表达式)和执行动作(在坐席端提示消息,或,在坐席和访客端提示消息),并保存。

  • 在坐席端提示消息:在会话窗口显示预设的消息提醒客服,消息仅对客服可见。

  • 在坐席端和访客端提示消息:以调度员身份将设定的消息发送给客户,消息对客户和客服可见。



注:关键字匹配功能为增值服务,如需开通,请提供租户ID并联系环信商务经理。 

009.png


在坐席端提示消息示例: 

010.png


PC客服工作台

当前版本:V2.1.2017.07030

支持记录历史登录数据

PC客服工作台支持记录历史登录数据。设置保存登录数据后,可以使用历史登录数据快速登录客服系统。

网页插件

当前版本:V47.14.1

支持显示企业欢迎语菜单

网页访客端支持显示企业欢迎语菜单。

管理员在“管理员模式 > 设置 > 系统开关”页面设置“欢迎语菜单指定技能组”功能后,当客户点击欢迎语的菜单项时,会话自动分配给对应技能组。

支持显示满意度评分标签

网页访客端支持显示满意度评分提示和标签。

管理员在“管理员模式 > 设置 > 满意度评价邀请设置”页面设置满意度评分选项后,网页访客端收到的满意度评价邀请显示对应的满意度评分提示和标签。客户选择满意度星级后,需要再次选择标签,才能完成满意度评价。 

011.png


环信移动客服更新日志http://docs.easemob.com/cs/releasenote/5.23

环信移动客服登陆地址http://kefu.easemob.com/  
收起阅读 »

环信公开课15期回放|人脸特效:AI+深度学习实现视频聊天美颜技术

7月27号,环信举办了第15期环信公开课,环信人脸特效产品创意师林珊珊做了主题为《人脸特效:AI+深度学习实现视频聊天美颜技术》的分享,讲述了人脸特效的发展历史及应用平台,并现场进行了美颜、滤镜、贴纸、换脸、扣背景等环信人脸特效演示。 环信公开课...
继续阅读 »
7月27号,环信举办了第15期环信公开课,环信人脸特效产品创意师林珊珊做了主题为《人脸特效:AI+深度学习实现视频聊天美颜技术》的分享,讲述了人脸特效的发展历史及应用平台,并现场进行了美颜、滤镜、贴纸、换脸、扣背景等环信人脸特效演示。




微信图片_20170802151120.jpg


环信公开课15期直播现场


以下是林珊珊分享PPT

001.jpg




002.jpg




003.jpg




004.jpg




005.jpg




006.jpg




007.jpg




008.jpg


环信公开课15期视频回放地址https://v.qq.com/x/page/g0532nad8xj.html
恭喜本期幸运观众俊鹏同学获得环信定制版瑞士军团双肩背包。


第十15期公开课3_10.jpg


 
环信人脸特效体验请联系环信小助手,微信huanxin-hh

扫码.gif

收起阅读 »

【环信征文】|两处小改动,解决环信V3.0官方版本关于转发的bug

    (本人github:https://github.com/BHAreslee)(若转载,请告知本人并附上原文链接,谢谢)          最近接手了一个集成即时通讯功能的项目,用的是环信的SDK。用环信的接口可以快速实现即时通讯的很多功能。并且对官方...
继续阅读 »
    (本人github:https://github.com/BHAreslee)(若转载,请告知本人并附上原文链接,谢谢)
    
    最近接手了一个集成即时通讯功能的项目,用的是环信的SDK。用环信的接口可以快速实现即时通讯的很多功能。并且对官方demo稍加改动基本能够满足项目需求。真机测试时,发现图片的转发,每次都是转发失败。我开始以为是我集成时有疏漏,逐行检查代码。发现并不是我的问题。从app store下载的官方demo同样是转发失败!!坑我啊!!原因是ContactListSelectViewController这个控制器里无法正确获取到想转发的图片的缓存地址。
修改如下图:


2893691-7bfd41d8c42b5f3d.png


ContactListSelectViewController.m
代码拷走直接用
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
didLongPressRowAtIndexPath:(NSIndexPath *)indexPath
{
id object = [self.dataArray objectAtIndex:indexPath.row];
if (![object isKindOfClass:[NSString class]]) {
EaseMessageCell *cell = (EaseMessageCell *)[self.tableView cellForRowAtIndexPath:indexPath];
//////////////////////////解决转发问题的代码///////////////////////////////
EMImageMessageBody *imageBody = (EMImageMessageBody*)[cell.model.message body];
EMMessageBodyType ty = cell.model.bodyType;
if (ty == EMMessageBodyTypeImage) {
NSString *str = cell.model.message == nil ? cell.model.thumbnailFileURLPath : [imageBody localPath];
[[NSUserDefaults standardUserDefaults] setValue:str forKey:@"imgTosand"];
}
/////////////////////////解决转发问题的代码////////////////////////
[cell becomeFirstResponder];
self.menuIndexPath = indexPath;
[self showMenuViewController:cell.bubbleView andIndexPath:indexPath messageType:cell.model.bodyType];
}
return YES;
}
ContactListSelectViewController是取数据,那么存数据要在ChatViewController控制器做存数据的操作。消息类型写死为EMChatTypeChat,是因为,不论是从单聊界面转发,还是从群聊界面转发,都只能转发给个人,所以这里写死,目前没有问题。
如下图:


2893691-7beb949a62e8035f.png


ChatViewController.m
代码拷走直接用
#pragma mark - EMUserListViewControllerDelegate
- (void)userListViewController:(EaseUsersListViewController *)userListViewController
didSelectUserModel:(id<IUserModel>)userModel
{
if (!self.messageModel) {
return;
}
if (self.messageModel.bodyType == EMMessageBodyTypeText) {
EMMessage *message = [EaseSDKHelper sendTextMessage:self.messageModel.text to:userModel.buddy messageType:EMChatTypeChat messageExt:self.messageModel.message.ext];
__weak typeof(self) weakself = self;
[[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
if (!aError) {
// NSMutableArray *array = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
UIViewController *chatController = nil;
#ifdef REDPACKET_AVALABLE
chatController = [[RedPacketChatViewController alloc] initWithConversationChatter:userModel.buddy conversationType:EMConversationTypeChat];
#else
chatController = [[ChatViewController alloc]
initWithConversationChatter:userModel.buddy conversationType:EMConversationTypeChat];
#endif
chatController.title = userModel.nickname.length != 0 ? [userModel.nickname copy] : [userModel.buddy copy];
// if ([array count] >= 3) {
// [array removeLastObject];
// [array removeLastObject];
// }
// [array addObject:chatController];
// [weakself.navigationController setViewControllers:array animated:YES];
[weakself.navigationController popViewControllerAnimated:YES];
} else {
[self showHudInView:self.view hint:Localized(@"transpondFail")];
}
}];
} else if (self.messageModel.bodyType == EMMessageBodyTypeImage) {
[self showHudInView:self.view hint:Localized(@"transponding")];
__weak typeof(self) weakSelf = self;
NSString *localPath = [(EMImageMessageBody *)self.messageModel.message.body thumbnailLocalPath];
//////////////////////////解决转发问题的代码////////////////////////////
localPath = [[NSUserDefaults standardUserDefaults] valueForKey:@"imgTosand"];
//////////////////////////解决转发问题的代码//////////////////////////
UIImage *image = [UIImage imageWithContentsOfFile:localPath];
void (^block)() = ^(EMMessage *message){
EMImageMessageBody *imgBody = (EMImageMessageBody *)message.body;
NSString *from = [[EMClient sharedClient] currentUsername];
EMImageMessageBody *newBody = [[EMImageMessageBody alloc] initWithData:nil thumbnailData:[NSData dataWithContentsOfFile:imgBody.thumbnailLocalPath]];
newBody.thumbnailLocalPath = imgBody.thumbnailLocalPath;
newBody.thumbnailRemotePath = imgBody.thumbnailRemotePath;
newBody.remotePath = imgBody.remotePath;
EMMessage *newMsg = [[EMMessage alloc] initWithConversationID:userModel.buddy from:from to:userModel.buddy body:newBody ext:message.ext];
// newMsg.chatType = message.chatType;//此为环信代码
newMsg.chatType = EMChatTypeChat;//这里是我加的
[[EMClient sharedClient].chatManager sendMessage:newMsg progress:nil completion:^(EMMessage *message, EMError *error) {
if (error) {
[weakSelf showHudInView:self.view hint:Localized(@"transpondFail")];
[weakSelf performSelector:@selector(backAction) withObject:nil afterDelay:1];
return ;
}
[(EMImageMessageBody *)message.body setLocalPath:imgBody.localPath];
[[EMClient sharedClient].chatManager updateMessage:message completion:nil];

// NSMutableArray *array = [NSMutableArray arrayWithArray:[weakSelf.navigationController viewControllers]];

#ifdef REDPACKET_AVALABLE
RedPacketChatViewController *chatController = [[RedPacketChatViewController alloc] initWithConversationChatter:userModel.buddy conversationType:EMConversationTypeChat];
#else
ChatViewController *chatController = [[ChatViewController alloc] initWithConversationChatter:userModel.buddy conversationType:EMConversationTypeChat];
#endif
chatController.title = userModel.nickname.length != 0 ? userModel.nickname : userModel.buddy;
// if ([array count] >= 3) {
// [array removeLastObject];
// [array removeLastObject];
// }
// [array addObject:chatController];
// [weakSelf.navigationController setViewControllers:array animated:YES];
[weakSelf.navigationController popViewControllerAnimated:YES];//转发完跳回去
}];
};

if (!image) {
[[EMClient sharedClient].chatManager downloadMessageThumbnail:self.messageModel.message progress:nil completion:^(EMMessage *message, EMError *error) {
if (error) {
[weakSelf showHudInView:self.view hint:Localized(@"transpondFail")];
[weakSelf performSelector:@selector(backAction) withObject:nil afterDelay:1];
return ;
}

block(message);
}];
} else {
block(self.messageModel.message);
}
}
}
上面一定要判断一下消息体类型,只有消息体为图片类型(EMMessageBodyTypeImage)才需要保存图片本地。如果不做判断的话,点击气泡马上崩掉。
个人感觉虽然能解决图片转发的问题,但并不是最好的解决办法,虽然对环信demo的代码改动最少。有更好的办法,欢迎在评论区交流。
(本人github:https://github.com/BHAreslee)(若转载,请告知本人并附上原文链接,谢谢) 收起阅读 »

从不加班的大数据创业公司招聘一个写代码的

招聘!招聘! 随着移动互联网寒冬越来越冷,靠App的情怀已经骗不来融资了,作为互联网连续创业者的本人决定中止全部App开发,战略方向调整为大数据的研究。本人新开办了一家大数据创业公司,我有一个能超越阿里腾讯的创意(不需要市场调查、原型设计、推广方案),就差个...
继续阅读 »
招聘!招聘!
随着移动互联网寒冬越来越冷,靠App的情怀已经骗不来融资了,作为互联网连续创业者的本人决定中止全部App开发,战略方向调整为大数据的研究。本人新开办了一家大数据创业公司,我有一个能超越阿里腾讯的创意(不需要市场调查、原型设计、推广方案),就差个写代码的了,要求和待遇如下:
1.转正月薪¥1000W,试用期月薪¥0,试用期视能力而定,从100年到千秋万代不等
2.每周上班8天,每天工作25小时,从不加班,每周少上一天班扣三天工资
3.每个工位配备反人体工学老虎凳
4.辣椒水无限畅饮
5.来自日本的程序员鼓励师穿着制服陪伴工作












20160408132932130.jpg



只不过手里拿着皮鞭和刺刀 收起阅读 »

环信Web IM v1.4.12已发布,支持离线状态发送消息并自动重连

Web IM v1.4.12 2017-07-17新功能: [sdk] 修改delivery ack和read ack的格式 [sdk] 用户在离线状态下发送消息,会自动重连并将未成功发送的消息发送出去 [sdk] WEBIM支持多设备,添加加入聊天室事件...
继续阅读 »


TIM图片20170728180129.png


Web IM v1.4.12 2017-07-17新功能:

  • [sdk] 修改delivery ack和read ack的格式

  • [sdk] 用户在离线状态下发送消息,会自动重连并将未成功发送的消息发送出去

  • [sdk] WEBIM支持多设备,添加加入聊天室事件

  • [sdk] 给delivered和ack加上from字段

  • [demo] 添加Rest Interface的 Test case

  • [demo] sdk/demo上传功能兼容ie8



Bug修复:

  • [sdk] 提升ie8的兼容性

  • [sdk] 自己发送的消息的已读ack,不再发送给自己

  • [demo] 新建需要审批的公有群,加入必须有审批流程

  • [demo] 鼠标悬浮在群禁言图标上出现提示信息“禁言”

  • [demo] demo.html中从cdn引入sdk

  • [demo] 修复无法准确统计离线消息数的bug

  • [demo] window.history.pushState在windows的chrome上有兼容性问题,统一改成window.location.href

  • [demo] window.location.href = xxxx,如果修改的是href.search参数(?a=x&b=y)时候, 如果遇到file方式打开本地index.html会直接跳转页面,造成登录一直不成功,改成修改 href.hash 参数(#a=x&b=y)

  • [demo] 将群管理员可操作的项目展示给管理员


 
webim在线体验:https://webim.easemob.com 

版本历史:更新日志
 
SDK下载:下载地址 收起阅读 »

环信Android/ios V3.3.3 SDK 已发布,支持多设备消息漫游及管理

Android​版本 V3.3.3 2017-07-21   新功能 新增加API请查看链接3.3.3api修改支持在多个设备登录同一个账号,多个设备间可以同步消息,好友及群组的操作(多设备登录属于增值服务,需要联系商务开通);添加群共享文件的大小属性;增加获...
继续阅读 »

TIM图片20170725145101.png


Android​版本 V3.3.3 2017-07-21
 
新功能
  • 新增加API请查看链接3.3.3api修改
  • 支持在多个设备登录同一个账号,多个设备间可以同步消息,好友及群组的操作(多设备登录属于增值服务,需要联系商务开通);
  • 添加群共享文件的大小属性;
  • 增加获取同一账号登录的设备列表的接口,并可以选择踢掉某个设备上的登录;
问题修复
  • 修复分页获取聊天室成员接口无法传入cursor的问题;
  • 修复邀请群成员时没有附带信息的bug;
  • 修复群组操作时必须获取所有已加入群组的问题;
  • 修复附件消息在web IM中右键另存时不能正确显示名字的问题;
  • 修复android 共享文件名为中文时显示乱码的问题;
  • 修复下载附件路径不存在或者打开错误时仍然下载成功的bug;
  • 修复切换账号时某些场景下崩溃的bug;
  • 修复获取群成员时最后一页cursor未更新的问题;
 ios版本 V3.3.3 2017-07-21新功能:
  • 新增:支持在多个设备登录同一个账号,多个设备间可以同步消息,好友及群组的操作(多设备登录属于增值服务,需要联系商务开通);
  • 新增:群共享文件的大小属性;
  • 新增:获取同一账号登录的设备列表的接口,并可以选择踢掉某个设备上的登录;
问题修复:
  • 修复邀请群成员时没有附带信息的bug;
  • 修复群组操作时必须获取所有已加入群组的问题;
  • 修复下载附件路径不存在或者打开错误时仍然下载成功的bug;
  • 修复切换账号时某些场景下崩溃的bug;
  • 修复获取群成员时最后一页cursor未更新的问题;
  • 修复调用异步删除好友接口,参数传“YES”不能删除会话。

 
 
版本历史Android SDK更新日志  ios SDK更新日志
下载地址SDK下载 收起阅读 »

Freshdesk母公司收购Joe Hukum进军聊天机器人市场

译者按:相对于国外智能聊天机器人市场的方兴未艾,国内智能聊天机器人的落地势头更是一浪高过一浪,以环信为首的智能客服厂商提供的服务包括单轮会话、多轮会话以及人工协作已经广泛应用于包括保险、教育、金融、电商等行业,借助于AI技术在包括主动营销方面也有了更深入的探索...
继续阅读 »
译者按:相对于国外智能聊天机器人市场的方兴未艾,国内智能聊天机器人的落地势头更是一浪高过一浪,以环信为首的智能客服厂商提供的服务包括单轮会话、多轮会话以及人工协作已经广泛应用于包括保险、教育、金融、电商等行业,借助于AI技术在包括主动营销方面也有了更深入的探索。


微信图片_20170725114409.jpg


   Freshworks(Freshdesk母公司)去年筹集5500万美元,用以建立超越现有帮助台服务。今天,Freshworks通过收购Joe Hukum来实现这一战略。Joe Hukum是一家印度创业公司,负责为企业提供建立自己的聊天机器人平台。

   虽有问询,但这些公司并没有透露任何交易条款。Joe Hukum, 之前为Speedy,最初侧重建立自己的个人助理或管理程序,帮助人们订购商品和服务,现转向为其他企业构建机器人服务平台。“Joe Hukum”是一种印地语的音译,意思是“按照你的意愿”。

   这是Freshworks在两年内的第八次收购,且在人工智能领域进行了一系列的收购,特别是“神经语言程序设计”(简称为“NLP”,注意不能与自然语言处理相混淆):另外两个收购是Chatimity和Frilp。Freshworks表示将利用三家创业公司的技术和人才,推出基于聊天机器人的解决方案。

   具体而言,Joe Hukum已经建立了知识树编码用以自动化销售、服务和支持工作流程。所以由联合创始人Arihant Jain,Ajeet Kushwaha和Rahul Agarwal领导的创业团队将在现有的Freshworks产品之上构建机器人产品。

   这笔交易强调了客户服务行业对聊天机器人的持续兴趣:公司正在寻找更有效率和更便宜的方式来提供基本信息和帮助客户。许多人认为聊天机器人是可行的解决方案,尽管目前正在建设的很多东西仍处于早期阶段。

   Freshworks创始人兼CEO Girish Mathrubootham在一份声明中说:“我们看到我们的客户对如何使用聊天机器人抱有浓厚兴趣,因为他们正在寻找与客户在网络和移动渠道上进行互动的新途径。随着客户偏好从传统的基于呼叫中心的电话树转移,聊天机器人提供了新的支持体验,同时也根本解决了对客户查询和途径进行分类的老式挑战,将其转为恰当的支持代理。这些仍属于聊天机器人的初期阶段,但Joe Hukum的创新团队和技术将帮助企业客户更好地吸引和支持其顾客。

   Freshworks引用了Gartner的研究,预测到2019年,40%的企业将使用自然语言聊天机器人来进行业务中(思考Slack风格的机器人)和对外的通信。

   这也正是Freshworks觉得它有潜力的地方。目前该公司为大约10万家公司提供Freshdesk,并在这一群体中开始销售这些机器人新服务。

   Joe Hukum的Jain在一份声明中表示:“作为Freshworks的一部分,对我们所有人来说都是激动人心的,因为它为我们提供了一个平台,为我们扩大了规模和覆盖面,并影响了成千上万的客户。

   相对于国外智能聊天机器人市场的方兴未艾,国内智能聊天机器人的落地势头更是一浪高过一浪,以环信为首的智能客服厂商提供的服务包括单轮会话、多轮会话以及人工协作已经广泛应用于包括保险、教育、金融、电商等行业,借助于AI技术在包括主动营销方面也有了更深入的探索。近期环信联合Gartner发布的业界首个智能客服机器人实践报告《Best Practice of Customer Service Bot In Customer Service Industry》更是给呼叫中心向在线客服转型的业客户注入了一剂强心针,客户们有充足的理由相信借助于智能聊天机器人的帮助可以利用有限的客服资源来应对移动互联时代海量客户咨询的暴涨。
 Gartner报告点击查看 收起阅读 »

环信荣膺“2017未来独角兽企业”,做商业的连接器

 独角兽企业往往聚集了行业里大多的资源,随着技术、人才、资金的积累,其在行业里的地位与机会将逐步放大,前进愈发顺利,发展迎风而起。近日,由中国科学院《互联网周刊》杂志评选的“2017未来独角兽企业TOP150”榜单正式揭晓,有着国际领先的企业级软件服务提供商愿...
继续阅读 »
 独角兽企业往往聚集了行业里大多的资源,随着技术、人才、资金的积累,其在行业里的地位与机会将逐步放大,前进愈发顺利,发展迎风而起。近日,由中国科学院《互联网周刊》杂志评选的“2017未来独角兽企业TOP150”榜单正式揭晓,有着国际领先的企业级软件服务提供商愿景的环信凭借在即时通讯云和SaaS客服领域的行业深耕和迅猛发展,以全国榜单第130名位居垂直行业第一。

ea790d9dly1fhv495ni8gj211j0pyn6b.jpg


“连接人与人”,“连接人与商业”的愿景支撑垂直行业第一

   企业服务市场是一块大蛋糕,练就的是技术内功,靠的是对市场趋势的准确把握,环信以用户需求为出发点近期推出客户互动云(CEC),环信CEC基于全球领先的即时通讯云技术,通过人工智能和大数据赋能,依托多渠道接入管理、精准用户画像、智能客服机器人、客户之声、智能质检、视频客服等SaaS客服体系为包括保险、证券、金融、教育、电商等行业提供了从客户互动渠道、到客户服务、再到精准营销的全流程客户互动解决方案。

   环信的起家产品“即时通讯云”,承担环信“连接人与人”的商业愿景,为开发者提供基于移动互联网的即时通讯能力,作为全球最大的即时通讯云厂商已经广泛应用服务13万余APP客户,环信全面支持Android、iOS、Web等多种平台,在流量、电量、长连接、语音、位置、安全等能力做了极致的优化,让移动开发者摆脱繁重的移动IM通讯底层开发,极大限度地缩短产品开发周期,二十四时间内即可让App拥有移动IM能力。目前环信即时通讯云已经拓展推出了包括直播、社交大数据、红包、鉴黄、视频人脸特效、短信验证码等增值服务。

   而“环信移动客服”是即时通讯云“连接人与人”场景的一个延伸到“连接人与商业”,包括网页在线客服、社交媒体客服(微博、微信)、APP内置客服、工单和呼叫中心等多种渠道均可一键接入。基于环信业界领先的IM长连接技术保证消息必达,并通过智能客服机器人技术降低人工客服工作量。同时,基于人工智能和大数据挖掘的客户旅程透析产品”环信客户声音”能够帮助企业优化运营,提高跨渠道客服体验。

   2016年,基于开发即时通讯云和移动客服的基础上,环信对已有产品进行了再次的研发和升级,针对已有在包括电商、保险、证券、金融、教育等优势行业的积累基础上,着手开发人工智能 —— “环信智能客服机器人”。他们希望在不降低用户体验的情况下,尽可能地解决商家日益增长的客服成本和海量客服请求之间的天然矛盾。

   比如,我们在移动端通过国美在线下单后,产品遇到的任何问题,通过IM窗口和客服咨询,这个沟通通道就是环信即时通讯云在提供底层通信服务。环信移动客服依托智能客服机器人很大程度上为企业节约了人力成本,众多保险公司已经通过部署环信智能客服机器人来提高客服效率。环信客户声音提高了跨渠道的客户服务体验,帮助企业优化运营,实现了客户中心完成从成本中心向价值中心的转化,国内某标杆教育机构已经在部署完环信客服声音以后尝到了客户转化率、客单价双升的甜头。

   与此同时,环信还一直利用自己的大数据平台产品给客户提供增值服务,让客户通过即时通讯云和移动客服等产品的后台数据,分析得出自己产品的适用人群、产品体验和活跃度等。让客户能更好地改善自己的产品,更好地服务消费者。

   环信的所有更新、改变与尝试,都是在围绕着一个行业,或者说是一个目标在努力。走上行业的顶峰之后,面临坦途时就会懈怠很多,但他们似乎仍然没有放弃向更高峰的攀登。

   2016年环信作为国内唯一的SaaS厂商荣膺Gartner 2016 Cool Vendor,2017年3月环信刚获得由经纬中国领投、银泰嘉禾跟投的1.03亿元C轮融资,显示出包括国际顶级研究机构和资本市场对于环信商业模式和发展前景的认可。正是得益于包括红杉资本、经纬中国、SIG和银泰嘉禾的鼎力支持,保障了环信持续巨额的研发投入,形成了公司业务发展的正向循环。

志存高远方能有所大成

   独角兽企业往往聚集了行业里大多的资源,随着技术、人才、资金的积累,其在行业里的地位与机会将逐步放大,前进愈发顺利,发展迎风而起。优势会被放大,引领、变革行业发展的责任则愈发凸显。换句话说,独角兽企业不仅仅是行业的佼佼者,更重要的,它是行业的领跑者、推动者。

   身为未来独角兽企业,要以行业推动者自居,以创新破迷局,以诚信守正心,以担当为己任。只有致力于市场需求的满足,行业发展瓶颈的突破,才会在纷乱的市场竞争中把握准方向,守得住初心,冲出迷雾,把握未来。

独角兽是一种荣耀的名片,更意味着一种担当与责任。 收起阅读 »

北京大半个SaaS圈都来了|SaaS厂商的社群销售方案和云服务销售社群私享会

 哇!社群销售沙龙倒计时7天,SaaS品牌热情响应。已确认参会品牌商:致远、麦达、 销售易、纷享销客、六度人和、高速波、云代账、有序云、Ping++......   更有客户和合作资源对接:畅捷通、环信、金融魔方3大资深SaaS品牌商,中国软件网海量渠道...
继续阅读 »
 哇!社群销售沙龙倒计时7天,SaaS品牌热情响应。已确认参会品牌商:致远、麦达、 销售易、纷享销客、六度人和、高速波、云代账、有序云、Ping++......

  更有客户和合作资源对接:畅捷通、环信、金融魔方3大资深SaaS品牌商,中国软件网海量渠道资源。届时将共同围绕“企业销售资源是否决定SaaS产品销售成败”话题激烈碰撞!


微信图片_20170720111910.jpg


没有销售员、销售员能力不足,如何做销售?


渠道招商乏力,伙伴能力不足,如何做销售?

社群销售:连接拥有专业知识、行业经验、社交关系等群体,用新规则整合社群生态体系,通过在线订购、直播订购、销售坐席促进转化。

私享会●北京站:邀请SaaS品牌商,拆解社群销售方案及运营模式,分享拥有30000个推客的云服务销售社群,帮助SaaS厂商实现销售增长。
 
私享会 活动看点  
大咖观点:增加销售员&干掉销售员 
出席嘉宾:用友助理总裁、金融魔方副总裁、CSaaS总裁
碰撞话题:企业销售资源是否决定SaaS产品销售成败
 
社群销售:让销售组织无边界 
推客发展:没有合伙人就没推客,合伙人为社群源动力
协同销售:厂商、渠道商、推客协同完成营销、销售
 
资源对接:3万推客资源状况及共享方案
推客构成:客户连接点,软件渠道商销售/服务工程师
推客能力:承接活动邀请、软件注册、产品销售等任务
品牌入驻:通过任务广场发任务,共享3万推客资源
 
案例分解:用友好会计社群&中驰车福车客社群1好会计社群概述
畅捷通出品好会计在线财务软件,招募100个合伙人,分别连接100名会计推客,形成万人销售社群,每月百套购买。2中驰车客社群概述
中驰车福为汽车后市场供应链服务商,采用B2b+B2r双模式,旨在全国招商9000汽配零售商,通过600个合伙人,分配连接50家汽配商,快速形成3万推客的销售社群。私享会 参会须知  
  
社群销售私享会 适合谁?
①软件/SaaS/在线教育等行业
②寻找企业增长新途径的企业管理者:如CEO、联合创始人、分管营销的VP、市场总监、运营总监、销售总监、渠道总监等
社群销售私享会 如何参加?
①时间:2017.7.27 14:30-17:00
②地址:北京●中关村软件园
③报名:点击下方进行报名

 点击此处立即报名 

 私享会 嘉宾团   于光辉 码客CEO

001.jpg



20余年营销服务一线经验,国内第一批CRM实践和传播者,码客社群销售方案及平台总设计师。曾任用友软件副总经理、MyCRM董事、红杉树高级副总裁、用友营销云事业部总经理。国家经贸委、中国电信/号百股份高级营销顾问、张艺谋《鸟巢图兰朵》在线营销总顾问。

程旭文 环信VP

微信图片_20170720153956.jpg




二十年企业服务老司机,重点关注即时通讯云/SaaS客服/协同OA等领域。

创建开源力量IT在线教育平台。在此之前曾就职于IONA Technologies、Progress Software、上海浩方等公司, 历任软件工程师、售前技术顾问 、销售经理、中国区销售总监等职位。
王学钧 用友集团助理总裁

002.jpg



用友畅捷通云业务总经理 投资总监,企业信息化资深专家,具有丰富的企业服务领域营销、 渠道、产品经验;畅捷通渠道支持体系创立人,曾实现用友集团千万级业务年增长5倍业绩。

杜永旺 金融魔方副总裁

TIM图片20170720112420.png


13年企业服务市场从业经验,曾任职TQ、中企动力、ZOHO中国企业应用软件、信息化服务公司,对SaaS产品和客户服务有较强方案设计能力和销售规划管理能力。

许卫国  中国软件网副总裁 合伙人

003.jpg



先后与近1000家软件企业交流,总结出中国企业级软件市场的销售模式和方法。武汉电视台《一飞冲天》导师。《大数据时代的移动营销》讲师;《传统软件企业转型》讲师;《云服务降维销售》讲师。

                 合作伙伴  
本期沙龙特别鸣谢以下合作伙伴鼎力支持!



TIM图片20170720112501.png




TIM图片20170720112530.png




TIM图片20170720112523.png




TIM图片20170720112542.png




主办方简介  

微信图片_20170720112126.jpg

收起阅读 »

在线教育+直播,千亿市场的新入口

百度报告显示,互联网教育市场在2016年的增长率位居全行业第三,预计2017年的市场规模将突破2800亿元。AI、VR、AR等新技术的日趋成熟也给产品创新带来了新的可能。在激烈的竞争中,如何提高开发效率,快速将产品推向市场;如何借助前沿技术,给用户带来创新的体...
继续阅读 »
百度报告显示,互联网教育市场在2016年的增长率位居全行业第三,预计2017年的市场规模将突破2800亿元。AI、VR、AR等新技术的日趋成熟也给产品创新带来了新的可能。在激烈的竞争中,如何提高开发效率,快速将产品推向市场;如何借助前沿技术,给用户带来创新的体验,赢得市场成为企业关注的重点。
本次活动,APICloud将联合合作伙伴从在线教育类App的开发及创新技术应用等方向,跟大家聊聊直播给在线教育带来的新机会。

30102748471066586.png



【活动时间】2017年7月29日(周六),13:30-16:30

【活动地点】创业邦Demo Space(北京市海淀区中关村创业大街11号海置创投大厦7层)

【面向人群】在线教育企业管理层、产品负责人、技术负责人,其他在线教育从业者

【活动咨询/合作】请加微信:appdev1,备注729




01.png



【13:30-14:00】签到

【14:00-14:40】在线教育App开发面临的挑战

内容概要:如何冲破在线教育的技术壁垒;在线教育业务落地平台选型对比;在线教育类App实例分析

【14:40-15:20】视频内容版权保护技术在在线教育中的应用

内容概要:视频盗版的发现、防范及证据保存,以及如何保护视频内容的版权

【15:20-16:00】直播和在线教育结合的实践经验

内容概要:直播和在线教育相结合的特点与好处;直播与线下培训、图文、音频分享的区别与特点;线上直播分享的运营和推广经验;IT 在线教育的未来发展趋势

【16:00-】幸运抽奖&自由交流




02.png



03.jpg




04.png




05.jpeg




06.jpeg


活动报名:报名地址 收起阅读 »

web IM的实现过程

web IM 聊天功能已实现,能够完成文本、emoji、图片、文件的收发。下面就以已完成的demo为中心,来说一下具体的实现方法。该demo已封装,能快速集成到项目中去。 1、demo展示: chat 目录下有两个子文件,chat_hx、chat_hx2,两...
继续阅读 »
web IM 聊天功能已实现,能够完成文本、emoji、图片、文件的收发。下面就以已完成的demo为中心,来说一下具体的实现方法。该demo已封装,能快速集成到项目中去。

1、demo展示:
chat 目录下有两个子文件,chat_hx、chat_hx2,两个文件代表俩个不同的用户,除im.js中用户配置不同其他代码均相同,可分别点击chat_hx、chat_hx2下的index.html运行该demo,会出现两个聊天界面,在此可以感受一下聊天功能。
 
2、demo目录结构:
chat_hx和chat_hx2下有 sdk、static、webrtc、im.js、index.html、main.html、pcChat.html。

sdk:目录下为环信官方提供的聊天聊天接口,strophe-1.2.8.min.js、webim.config.js、websdk-1.4.11.js;三个文件在index.html中均需要引入,webim.config.js文件中则需要我们配置应用的AppKey,是该应用的唯一标识;
static:有css、img、js 提供聊天界面的样式,图片、emoji表情库、jQuery库、underscore库;
webrtc:官方提供的的rtc聊天库,集成即时视频功能需要引用的文件;
index.html:手机web聊天界面入口,聊天窗口标签及相应的聊天模板;
pcChat.html:pc聊天界面,聊天窗口标签及相应的聊天模板;
main.html:pc聊天界面入口,通过iframe引入pcChat.html;
im.js:该文件中处理了所有聊天逻辑,提供用户登录接口,消息收发接口,采用localStorage来做消息的本地缓存,在html文件中只需要调用具体方法即可完成聊天功能。一下为具体的调用方法:
//初始化进去界面掉用该方法
getHxUser(login_account,send_to);
//发送图片调用方法 onClick("sendPrivateImg()")
sendPrivateImg();
//发送文件调用方法 onClick("sendPrivateFile()")
sendPrivateFile();
//发起视频聊天调用方法 onClick("videoCall()")
videoCall();
//发送文本消息调用方法 onClick("videoCall()")
sendPrivateText();

3、缓存逻辑:
缓存采用了没有时间限制的数据存储 localStorage 存储方式,以键值对的形式来存储一个聊天组。
(1)展示聊天信息:
key:"user1:user2" 以当前用户名和聊天对象的用户名作为key;
value:具体的聊天信息记录以数组形式存在。
每次登录后通过key来获取缓存中的聊天记录数组:
var group = "user1:user2";
var localContent = JSON.parse(localStorage[group]);
//遍历聊天数组
$(localContent).each(function(key , obj){
var domstring = showBox(obj);//获取对应的聊天模板
$(".chat-container").append($(domstring));//展示聊天信息
text2bottom();//聊天记录滚动至底部展示最新的聊天信息
});

(2)接收信息的缓存处理:
接收消息将消息同样以键值对(登录用户名:接收者用户名)的的形式存储接收到的消息,存储前处理存储内容:
var group = "user1:user2";
var localContent = new Array();
if (localStorage[group]) {
localContent = JSON.parse(localStorage[group]);
}
localContent[localContent.length] = {
'time':crtTimeFtt(),//时间
'data':data,//文本、emoji(符号)、图片(url)、文件(url)数据
'from':from,//谁发的
'type':type,//文本类型 text,emoji,file,picture
'id':id//消息id
};
localStorage[group] = JSON.stringify(localContent);//存储本地;

(3)发送消息的缓存处理:
发送的消息同样以键值对的形式进行存储,同(2),图片文件,则是通过官方提供的方法当发送成功后会有对应的URL返回,即将URL作为数据存入data字段即可。

4、模板:
为控制方便模板写了六套,及左右聊天展示个三套 分别为文本、图片、文件。
 
 

00F7D790-2475-434B-9AEC-B86384B827C7.png




7AC59638-1719-4B4E-9015-461A25D5B039.png




CC744F4E-B6D4-4B4D-9ED9-31BA00AA651B.png


  收起阅读 »

android 集成环信 之后apk安装不了,打不开,打开之后就闪退的问题

之前做项目集成的是 环信的sdk ,环信的sdk 确实很好,客服 也很给力。但是在集成的过程中发现,apk 在手机上发布不了,要么就是,安装了 打不开,打开就闪退:问题有一下两方面 1.之前做过一个环信的即时通讯,集成好环信的sdk之后在4.x的手机上就打开...
继续阅读 »
之前做项目集成的是 环信的sdk ,环信的sdk 确实很好,客服 也很给力。但是在集成的过程中发现,apk 在手机上发布不了,要么就是,安装了 打不开,打开就闪退:问题有一下两方面

1.之前做过一个环信的即时通讯,集成好环信的sdk之后在4.x的手机上就打开就闪退,,只能在5.x和6.x手机上打开app

2.最近又碰到了同样的问题不过这次和上次不一样,这次是因为我的 as升级到了 2.3 之后出现的这个问题..所以经过了两次遇到这个问题今天决定记录一下.


这个问题的处理方法分三部:

1.把Android studio的 instant run给关掉,setting ----- 搜索instant run 如图:


20170330103930974.png



2.然后把as的所有缓存给清楚掉方法:删除build这两个文件


20170330104151895.png



3.clear project 清理一下项目 



20170330104254039.png



然后重新运行项目 :链接http://blog.csdn.net/wangrain1/article/details/68483976
  收起阅读 »

基于波特—劳勒综合激励模型对员工激励的几点思考

     员工作为企业的重要主体,其工作状态决定了他的工作绩效,员工的工作绩效则决定了企业的产出和绩效,因此员工管理也就成为企业管理者最为关注的问题之一。如何管理好员工并满足其需求、如何有效地激励员工提升其满意度、如何通过激励让员工产出最大化进而提升组织绩效,...
继续阅读 »
 
   员工作为企业的重要主体,其工作状态决定了他的工作绩效,员工的工作绩效则决定了企业的产出和绩效,因此员工管理也就成为企业管理者最为关注的问题之一。如何管理好员工并满足其需求、如何有效地激励员工提升其满意度、如何通过激励让员工产出最大化进而提升组织绩效,一直是企业管理者不断探索、力求攻克的难题。

   为此,各大企业都积极推出各种激励手段,包括工资奖金、各种评优评先等员工关怀激励措施,目的是让员工始终保持高效能的工作状态。有些措施取得了很好的成效,有的也会遇到一些瓶颈,比如激励资源虽然投放出去但出现激励措施失衡、激励效果未达到预期等问题,究其原因,可能是缺乏一些系统的激励理论思想的指导所致,以至于在激励的时候出现方法不对或是激励对象不对等情况。激励看似是一种非常有效的手段,但并不是可以泛用或滥用,如何通过激励手段让与员工达到更好的工作绩效,笔者通过对基于波特—劳勒综合激励模型中的一些理论的分享,浅谈个人的一些思考和见解。

一、波特—劳勒综合激励模型的理论指导模式

   波特—劳勒综合激励模型是管理学和组织行为学研究的重要内容之一, 在二十世纪六七十年代,劳勒—波特激励模式的提出确实产生了非常大的影响,直至今天仍有相当的现实意义。它是对激励过程的一个比较恰当的描述,让我们清楚地认识到,激励并不是一个简单的因果关系,不要以为设置了激励目标就一定能获得组织所需要的行动和努力,通过奖励,员工就一定会得到满意,激励是一个复杂的受外界许多因素干扰的循环过程(如图1)。

TIM图片20170714111207.png


   波特和劳勒将得到的奖励分为外在奖励和内在奖励。外在奖励指的是工资、提升、地位、安全感等, 按照马斯洛的需求层次论,它主要是满足一些低层次的需要。内在奖励是指一个人由于工作成绩良好而自己给予的报酬和奖励,如感到完成了一件有意义的工作,对社会做出了贡献等。它对应的是一些高层次需要的满足,与工作成绩直接相关。在本文中,笔者重点分享关于内在奖励的一些思考和建议。

二、基于波特—劳勒综合激励理论的四象限“按需激励”模型

   根据波特—劳勒综合激励模型所描述的内在奖励,跟物质没有直接关系,而更多地是和员工对工作价值和自我认知价值关系紧密,跟工作绩效密切相关,可以说员工对内在奖励越满足,他的内在工作动力就更足,工作绩效就会越好,对公司的贡献就更大。基于这个出发点,在保证员工外在激励的前提下,管理者加大对员工的内在激励,就能更好地激发员工积极性,增强其对工作的价值满足感,进而提升满意度达到个人产出最大化。而每个员工在组织中的工作状态是不一致的,有些员工能力强,但工作意愿稍显不足,有些员工能力不足,但工作意愿很强,有些员工能力强,工作意愿也非常足,而也有员工能力不足,工作意愿也不强……管理者如何做到对不同的员工进行个性化的有效的激励?对此,笔者提出了一个四象限“按需激励”模型(如图2)。

TIM图片20170714111307.png


   根据四象限“按需激励”模型可以看到,该模型强调的是“按需”激励,即根据不同工作状态的员工的激励需求,管理者给予不同的工作激励模式,一方面帮助员工能力成长,更重要的一方面是激发员工的工作价值感,提升工作绩效。

1、推销式激励。这是针对“双低”即低意愿低能力员工的一种激励模式,很多企业内部都不乏这类员工,尤其一些出现职业倦怠、能力一般的老员工,他们需要一种新的能量注入,提升意愿和能力,针对这部分员工管理者可以导入推销式激励,在能力上给予员工工作指导,在工作意愿上给予精神支持,这要求管理者前期对员工倾注更多的精力,包括工作方法上的指导,跟进员工的改善情况,同时对于员工取得的进步及时给予表扬等精神激励。对于“双低”员工,常见的观点是直接放弃,而从对员工负责的角度来讲,管理者还是要先尝试给予员工辅导和提升的机会,通过大量的努力无法让员工提升胜任岗位能力要求,再考虑是否放弃。

2、教练式激励。这是针对高意愿低能力员工的一种激励方式。这部分员工的特征为稳定性好、工作积极、忠诚度高,但工作能力较弱,这部分员工最需要的就是给予方法指导,针对这部分员工管理可以导入教练式激励,采用引导或教练的方式充分激发员工的潜能和能力,帮助员工树立工作目标,密切监督并评估其工作绩效的提升。

3、授权式激励。这是针对“双高”即高意愿高能力员工的一种激励方式。这部分员工通常在企业中是非常受欢迎的员工,表现积极、自律,自我要求高、非常优秀,对企业贡献较大,针对这部分员工,管理者可以采用授权式激励,充分对其进行授权,鼓励他超越自己,并培养为后备管理人才。

4、参与式激励。这是针对低意愿高能力员工的一种激励方式。这部分员工工作能力强,但是意愿不太高,他们对自己工作能力自信,同时希望得到更多的尊重和认同,针对这部分员工,管理可以导入参与式激励,和员工建立充分的信任关系,多给予支持和鼓励,让员工参与一些决策等,激发员工的工作意愿。

   以上是针对四象限“按需激励”模型的具体应用建议,期望通过针对不同员工的激励需求提供相应的激励方式,提升员工的工作价值感,最终通过提升员工满意度来推动组织绩效的提升。从波特—劳勒综合激励模型我们还可以看到,除了外在激励和内在激励是影响员工满意度的因素之外,还有一个调节因素就是“公平感”,即一个人要把自己所得到的报酬与自己认为应该得到的报酬相比较,如果他认为相符,他就会感到满足,并得于激励,以后会更加努力。反之,如果他认为不相符,即使事实上他得到的报酬并不少,但还是会感到不满,甚至沮丧,从而影响他以后的努力。所以企业还要加强对员工感知的关注,营造制度的合理性,双管齐下,员工激励不仅仅是一门科学,更是一门艺术,只有综合运用,多管齐下,才能取得最有效果。

本文刊载于《客户世界》2017年4月刊;本文作者黄清华,作者单位为广东太阳神健康产业有限公司客户联络中心。 收起阅读 »

12张图看懂Gartner《智能客服机器人行业最佳实践》报告

   引言:2016,开启了人工智能(AI)元年,在世界范围内掀起了一轮新的技术和应用革命。由于云计算、大数据、机器学习、深度学习等技术的不断发展进步,伴随着人工红利消失、消费升级、个性化用户体验的刚性需求催化了各种AI应用的快速落地,包括无人驾驶、计算机视觉...
继续阅读 »
   引言:2016,开启了人工智能(AI)元年,在世界范围内掀起了一轮新的技术和应用革命。由于云计算、大数据、机器学习、深度学习等技术的不断发展进步,伴随着人工红利消失、消费升级、个性化用户体验的刚性需求催化了各种AI应用的快速落地,包括无人驾驶、计算机视觉、智能聊天机器人等人工智能技术慢慢从实验室走进了我们的日常生活。随着2016年Alpha GO打败李世石震惊了世界,人工智能也迎来了一波投资热潮。2016年前三季度全球人工智能行业融资额36.84亿美元,融资交易高达457次。据统计,2015年全球AI市场规模约为484亿元人民币,到2020年,全球AI市场将达到1190亿元人民币规模。

   有科学家大胆预测,在未来几十年人类将创造出具有灵长类动物智能的人工智能系统。但现阶段AI发挥最大生产力更可能是在垂直行业,如无人驾驶、安防、医疗、工业机器人、企业服务等。以企业级服务为例,人工智能已经被企业级软件服务行业视为顶层设计和终极竞争层面,特别是在客户服务行业,智能客服聊天机器人已经展示给世人强大的生产力。

   作为人工智能应用方面的企业级服务先行者,环信CEO刘俊彦认为:“在中国目前的环境,锦上添花的AI功能叫好不叫座,客户缺乏付费意愿。AI只有做到真正替代人工或者完全自动化一个企业的流程,甚至创造出一个全新的更具效率的业务流程,才会有客户大规模买单。”而在客户服务行业,当用户请求接入后,先由智能客服机器人解答80%的常见问题,剩下20%复杂问题再由真人专家客服来回答解决。智能客服机器人创造的整套流程已经完全改变了整个客服行业的劳动力结构和工作方式,正如自动驾驶未来终将彻底改变整个交通出行和汽车制造行业。

   科技和创新进入拐点式爆发,从“互联网+”到后移动互联网时代,再到人工智能的浪潮席卷全球,人工智能与各行业的紧密结合将催生出更多、更大、更接地气的应用场景。互联网作为一个连接器,实现了人与人,人与信息的普世连接,而环信也将借助环信智能客服机器人在新的人工智能时代实现对“人与商业”的重构和深度连接。

智能客服机器人的自我修养【环信版】V1.2---副本---副本_01_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_02_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_03_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_04_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_05_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_06_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_07_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_08_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_09_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_10_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_11_.png




智能客服机器人的自我修养【环信版】V1.2---副本---副本_12_.png


进入Gartner官网阅读中文版全文 收起阅读 »

环信移动客服v5.22已发布,自动消息功能助力客户营销

客服如何从成本中心变为营销中心和盈利中心?环信CEC(客户互动云)要把精准营销融入云客服。环信“自动消息”功能通过创建线上的自动消息,可以向APP、网页渠道的目标客户主动推送产品和活动消息,帮助您更好地对您的客户进行营销,将他们留住使用您的产品或服务。 客服模...
继续阅读 »
客服如何从成本中心变为营销中心和盈利中心?环信CEC(客户互动云)要把精准营销融入云客服。环信“自动消息”功能通过创建线上的自动消息,可以向APP、网页渠道的目标客户主动推送产品和活动消息,帮助您更好地对您的客户进行营销,将他们留住使用您的产品或服务。

客服模式

支持打印消息记录


支持打印历史会话的消息记录。可将任意一条会话的消息记录打印为PDF或使用打印机打印,消息记录以对话方式呈现,格式清晰,便于文件传递。

在历史会话页面,点击会话进入会话详情页,点击右上方的打印按钮,打印该会话的当前消息记录。如需打印所有消息记录,需要点击“更多历史消息”,将历史消息加载出来后打印。

该功能在客服模式和管理员模式都支持。

支持查看质检评分

支持查看质检员对会话的服务质量给出的质检评分。

在历史会话页面,点击会话进入会话详情页,点击“质检”tab,可以查看质检员对该会话的质检评分。

管理员模式

自动消息

环信移动客服系统推出“自动消息”功能。通过创建线上的自动消息,可以向APP、网页渠道的目标客户主动推送产品和活动消息,帮助您更好地对您的客户进行营销,将他们留住使用您的产品或服务。

“自动消息”有以下特点:
  • 精准筛选目标客户:根据客户的创建时间、标签、客户名称等客户属性进行精准筛选。
  • 预制发送内容和接待者:在设置自动消息时,提前设定好消息内容,并指定接待客户的坐席或技能组。
  • 计划定时发送:支持设置自动消息的持续周期和触发时间点,如中午12:00或凌晨2:00。
  • 发送效果审视:发送后可以随时查看消息发送情况,包括消息发送量、到达终端量、客户打开的数量、客户回复的数量等。
“自动消息”功能为增值服务,如需开通,请提供租户ID并联系环信商务经理。

001.png

“自动消息”使用介绍:1. 创建自动消息。进入“管理员模式 > 自动消息”页面,点击“新建自动消息”按钮,设置自动消息名称、目标客户、消息内容、作用时间,点击“发布按钮”,设置发布时间并发布。
  • 自动消息名称:设置自动消息的名称。
  • 目标客户:根据客户属性筛选自动消息的目标客户。
  • 消息内容:设置自动消息的营销号、接待者、消息内容。营销号将展示在app、网页访客端。
  • 作用时间:设置自动消息的触发时间点。系统在设置的作用时间将自动消息发送给目标客户。
  • 发布时间:设置自定消息的持续周期,系统在该时间范围内按照作用时间将自动消息发送给目标客户。

002.png

2. app、网页访客端展示。自动消息送达访客端后,将展示在聊天窗口中。若客户正在使用网页聊天窗口,会收到如下提醒。  

003.png

注:使用旧版移动客服android/iOS SDK可以收到消息,但统计不到自动消息的打开数、回复数,建议集成最新版移动客服android/iOS SDK。 3. 自动消息的发送效果。在自动消息页面,可以查看自动消息的发送效果。
  • 发送数:已发送给客户的自动消息的数量。
  • 到达数:抵达客户使用的访客端的自动消息的数量。
  • 到达率:已到达的自动消息的数量占比。
  • 打开:客户打开的自动消息的数量。
  • 打开率:已打开的自动消息的数量占比。
  • 回复人数:回复自动消息的客户的数量。
  • 回复率:客户回复的自动消息的数量相对于客户打开的自动消息的数量的占比。

    004.png

  •  
 满意度评价邀请设置新增满意度评价邀请设置页面。原系统开关页面的“会话结束自动发送满意度评价邀请”开关转移至该页面,新增“满意度评价菜单项序号显示为倒序”开关和“评分选项设置”。满意度评价菜单项序号显示为倒序在微信、微博等渠道,满意度评价内容是数字型菜单,序号顺序默认为正序。打开开关时,菜单的序号顺序为倒序。评分选项设置满意度评分选项,允许自定义星级对应的文字提示,支持为星级添加标签。

005.png

访客端:若设置评分选项的文字提示和标签,访客端收到评价邀请后,选择满意度评分,需要再次选择标签。注:微信、微博端支持显示设置的文字提示和标签;app、网页访客端暂时不支持。客服可以手动发起会话邀请开关优化“客服主动发起会话”功能。新增“网页端访客访问页面时,客服可以手动发送会话邀请”开关,并支持设置默认消息内容。“客服主动发起会话”功能为增值服务。开通该增值服务,并打开此开关后,客服可以在“待接入”页面的“正在访问”页签主动向网页渠道的访客发送邀请。邀请送达后,网页端弹窗提醒访客。

006.png

访客端示例:

007.png

支持设置工单帮助主题、优先级、事件推送支持自定义工单帮助主题、工单优先级,配置工单事件推送。
  • 帮助主题为工单的类别。进入“管理员模式 > 工单 > 工单帮助主题自定义”页面,可以自定义帮助主题选项。
  • 优先级用于标记工单的紧急或重要程度。进入“管理员模式 > 工单 > 工单优先级自定义”页面,可以自定义优先级选项。
  • 事件推送用于将工单相关的数据推送至第三方服务器。进入“管理员模式 > 工单 > 工单事件推送配置”页面,填写第三方服务器的URL地址和token,并启用工单事件推送功能。
注:工单功能为增值服务。使用前,请先在“管理员模式 > 工单 > 申请工单”页面申请开通该功能。【优化】历史会话页面记录会话过程历史会话的详情页记录会话过程,包括会话接起、会话转接、会话结束的操作人和发生时间。这些信息显示在“记录”tab页签。【优化】质量检查的筛选项支持多选质量检查页面的筛选项(渠道、关联、参与客服)支持多选,方便质检员从不同纬度筛选需要进行质检的会话。【优化】工作量、工作质量导出报表包含客服账号工作量、工作质量页面的导出报表增加客服账号,客服账号为客服的登录邮箱地址。多租户管理后台多租户管理后台增加以下新功能、优化。管理员的权限多租户管理员权限分为普通管理员和超级管理员。
  • 普通管理员:可以查看管理员、租户、统计、设置等页面的相关信息,并导出历史会话、统计数据。仅能够对租户进行管理,包括添加、删除租户等。
  • 超级管理员:拥有普通管理员的所有权限,并且可以创建、删除其他管理员,设置多租户的基本信息、坐席分配、租户模版、单点登录等。
租户成员信息租户详情页新增成员信息,显示该租户的所有管理员、坐席,以及账号名称、创建时间、在线状态、在线时长等。坐席分配新增坐席分配功能,允许超级管理员根据各个租户的实际坐席数,对租户的最大坐席数进行重新分配,优化资源配置。进入“设置 > 基本信息”页面,点击“坐席分配”按钮,可以重新分配租户的最大坐席数。单点登录新增单点登录功能,允许为多租户管理平台的租户设置指向第三方系统的登录URL,坐席使用该第三方系统的账号登录后,可以直接进入客服系统。移动客服Android SDK当前版本:V1.0.8新功能:
  • 支持自动消息的统计上报
  • 支持Google GCM推送
  • 支持显示待接入正在排队人数(增值服务)
  • 支持显示客服的输入状态(增值服务)
移动客服iOS SDK当前版本:V1.1.2新功能:
  • 支持自动消息的统计上报
网页插件当前版本:V47.13.1新功能:
  • 支持自动消息的统计上报
改进:
  • 客服头像显示在聊天窗口左侧
  • 线上标准版本全面支持移动端

 
环信移动客服更新日志http://docs.easemob.com/cs/releasenote/5.22

环信移动客服登陆地址http://kefu.easemob.com/   收起阅读 »

TIOBE 7月编程语言排行榜:Go语言飙升至前十 Java暴跌

来源丨TIOBE   翻译丨苗稳      从前几月的排行榜来看,Go语言在今年一路飙升,终于在这个月进入前十名。此外,新兴语言Kotlin、Elixir和Hack在本月并没有太大的进步,Kotlin和Elixir同时下跌了5名,Hack下跌了6名,Elixi...
继续阅读 »


微信图片_20170712153712.jpg


来源丨TIOBE
 
翻译丨苗稳
 
   从前几月的排行榜来看,Go语言在今年一路飙升,终于在这个月进入前十名。此外,新兴语言Kotlin、Elixir和Hack在本月并没有太大的进步,Kotlin和Elixir同时下跌了5名,Hack下跌了6名,Elixir再次失去进入50名的机会。

   之前,七牛云许式伟曾说过Go语言会取代Java,从目前来看,Go语言正在朝这一目标迈进,那么它是否会一直保持上升势头,紧跟在JavaScript和Python等明星语言之后吗?让我们拭目以待。

TOP 20编程语言排行榜


微信图片_20170712153754.jpg


TOP 10编程语言指数走势

微信图片_20170712153813.jpg


21-50名编程语言排名

微信图片_20170712153829.jpg


第51到100名编程语言排行如下,由于它们之间的数值差异较小,不做先后排名:


 (Visual) FoxPro, ABC, ActionScript, APL, AutoLISP, bc, Bourne shell, C shell, CFML, CL (OS/400), Clipper, Clojure, Common Lisp, Crystal, Elixir, Elm, Emacs Lisp, Factor, Forth, Icon, IDL, Inform, Io, J, Korn shell, Magic, Maple, ML, MUMPS, NATURAL, NXT-G, OpenCL, OpenEdge ABL, Oz, PL/I, PowerShell, Q, REXX, Ring, S, Smalltalk, SPARK, SPSS, Standard ML, Stata, Tcl, VBScript, Verilog, VHDL, Wolfram


历史排名(1987-2017)

以下排名取自于12个月的平均值。

微信图片_20170712153900.jpg


年度编程语言

年度编程语言是授予一年中评分最高的编程语言:

微信图片_20170712153916.jpg


【说明】TIOBE 编程语言社区排行榜是编程语言流行趋势的一个指标,每月更新,这份排行榜排名基于互联网上有经验的程序员、课程和第三方厂商的数量。排名使用著名的搜索引擎(诸如 Google、MSN、Yahoo!、Wikipedia、YouTube 以及 Baidu 等)进行计算。




请注意这个排行榜只是反映某个编程语言的热门程度,并不能说明一门编程语言好不好,或者一门语言所编写的代码数量多少。

这个排行榜可以用来考查你的编程技能是否与时俱进,也可以在开发新系统时作为一个语言选择依据。

排行榜的详细定义可以参考这里:https://www.tiobe.com/tiobe-index/
  收起阅读 »

七大有效的编程习惯助你成为更好的程序员

作者 | Bartlomiej Karalus 翻译 | 雨言 编程能力和水平固然重要,但如果具备良好的编程习惯,往往也能帮助你事半功倍。本文作者通过切身经验,分享了七个有效的编程习惯,希望对大家有所帮助。     最近在读一些不错的关于习惯养成的书籍,...
继续阅读 »


TIM图片20170712152139.png


作者 | Bartlomiej Karalus

翻译 | 雨言


编程能力和水平固然重要,但如果具备良好的编程习惯,往往也能帮助你事半功倍。本文作者通过切身经验,分享了七个有效的编程习惯,希望对大家有所帮助。


    最近在读一些不错的关于习惯养成的书籍,读完之后,备受启迪,于是,我开始反省自己目前的各种习惯,其中有一些就是平时日常生活中的习惯,也有一些仅仅与工作有关,说到工作,就不得不说一下编程习惯了,我很乐意与大家分享我的编程习惯。

随时随地“Ctrl+S”

   这是我多年来一直坚持的一个习惯,尽管现在很多新的IDE甚至不需要手动保存,可以自动保存,但我还是会在代码结束的最后一行不由自主地按下组合键“Ctrl+S”,如果我没记错的话,每次只要我敲键盘一停下来我就会“Ctrl+S”,但奇怪的是,这个“Ctrl+S”实际上比我同事脸上的笑容更能节省我一天的时间。

定期释放大脑内存

   有的程序猿说长时间敲代码让他们感觉像是到了天堂一样飘飘欲仙,感觉棒极了,这在我看来是一种“狂暴模式”,短期内可能确实让人感觉良好,但随后你将需要花费大量的时间进行自我修复。所以说,短时间内的头脑风暴是可以的,但是要适时地停下来歇会儿,头脑风暴太久实际上会让你思维迟钝,容易钻死胡同。

确保排除一切干扰

   当我专注于一件非常重要的事情时,我会把手机关机,避免社交媒体或任何不必要的媒体的干扰,当然,听点音乐还是可以的。不过话又说回来,还是需要采用健康一点的方式。如果你有小孩,你又需要非常专注于工作,为了不被打扰,把他们关在地下室听起来好像还不错,但是从长远来看,这并不是一个好的解决办法。

以终为始

   有人说,可视化的力量无与伦比,它可以帮助我们确定今天的目标,最后在一天结束时减少或消除沮丧和失望等负面情绪。所以,不论什么时候,一定要清楚自己到底想要做什么。这听起来似乎很显而易见,也很容易做到,但实际操作过程中,这个步骤往往经常被忽略。

定期培训

   我有一个很好的习惯就是定期培训,当然去健身房也是一个好习惯,这种情况下,我更关心的是一个人的实际编程能力。我热衷于通过即兴编程训练来让我的思维保持敏锐,这样的训练也许在短期内不会有什么显著的成效,但总有一天会厚积薄发。

从写测试用例开始

   近期最常用的一种模式就是不管写什么代码都先从写测试用例开始,这来源于我早期的一个观点,它帮助我在开始之前就看到了目的地,显然,这让最终呈现出来的结果更加安全可靠,同时还能够设计和记录代码,我意外的是竟然很少有程序猿认同这一观点。
 
切忌“前程规划”

   另一个是我新养成的习惯――避免“前程规划”。以前我也不懂这个道理,总是想一步到位,想一开始就把方方面面都考虑周全,想要覆盖到一切可能的边界的测试用例,甚至想要把我的后代使用时有可能出现的情况也考虑进去。渐渐地,我意识到这样会导致代码基过于复杂,并且耗费大量时间,最常见的结果就是,我的代码完美无瑕同时也一无是处。

   最后,如果你觉得我说的这些有符合你口味的就试试呗!这些对我编程来说确实非常有帮助,但是罗马也不是一天建成的,养成一个习惯最好的办法就是去使用,总有一天你会突然发现,习惯不知不觉已经养成。哈,如果你有一些好的习惯也记得和我分享哦! 
 
本文转自CSDN公众号 收起阅读 »

超越Twitter,老哥,稳!环信助力新浪微博深度连接“人与商业”

(本文共1766个字,不信你数一数,阅读完需三分钟,不信你试试)      微信渐老,微博逢春。就在大家认为微博没落的时候,新浪微博用月活用户数、收入、股票暴涨,一波“还有这种操作”的方式引领进入社交媒体下半场。据公开数据显示,截至3月31日,微博月活跃用户达...
继续阅读 »
(本文共1766个字,不信你数一数,阅读完需三分钟,不信你试试)
 
   微信渐老,微博逢春。就在大家认为微博没落的时候,新浪微博用月活用户数、收入、股票暴涨,一波“还有这种操作”的方式引领进入社交媒体下半场。据公开数据显示,截至3月31日,微博月活跃用户达3.4亿(其中91%为移动端用户),已超过Twitter成为全球用户规模最大的独立社交媒体公司。得益于用户规模的持续扩大和内容生态的不断完善,微博的商业化继续保持快速增长。财报显示,一季度微博总营收达到13.7亿元,同比增长76%,其中广告营收达到11.7亿元,同比增长80%。
 
 与此相关,微博商业化开放2年多来,为企业带来了品牌曝光、变现转化等机会,然而随着大量咨询需求的涌入,客户沟通成本同时不断变高。如何帮助微博平台用户与粉丝/客户更好地沟通,做更好的商业连接,成为了微博亟需解决的问题,也成为了环信与新浪微博合作的契机。

TIM图片20170712111933.png


    无论对于企业蓝V用户还是个人橙V用户来说,当运营到增长或成熟阶段并且粉丝消息量达到一定规模后,普遍会出现以下这些问题:

   1,消息量增长蹭蹭的,客服小助手忙不过来。很多时候这事儿不是增加几个客服小妹就能解决的,哪怕是一个账号的大量消息,就算多人伺候解决了一部分接待数量问题,但没有好的分配机制,也有可能出现回复互相撞车的情况。

   2,手上有多个账号要管理,来回切换效率低下。尤其对于微博平台的企业用户来说,很可能一家企业会运营多个微博蓝V账号,但回复私信、评论、@时需要来回换账号,甚是麻烦,更不用提可能还需要维护微博以外的其他渠道如微信、官网的互动。

   3,撩了半天好不容易有意向转化成交,跟进却不及时流失了。不少企业运营微博是有转化商机的目的,通过微博沟通后,客服小妹发现潜在商机线索时,需要销售同事进一步跟进沟通,但转接消息不方便,只能要么一个人都负起责任服务同时引导购买,要么得共用账号你聊完毕我来聊;

   针对这些问题,为了帮助微博用户更好地做连接做服务,新浪微博采用了更高级的粉服开发者模式,但需要企业自身具备较高的开发能力,很多企业尤其是中小企业无法HOLD住这种方式,当新浪微博寻找更便捷优质的解决方案时,环信基于在全媒体智能云客服领域的积累和沉淀恰好满足了这样的需求,双方一拍即合拉开了深度合作的序幕。

   环信为新浪推出的多客服系统在微博平台正式上线以来,截止2017年2月,已经有2200家企业注册试用多客服系统,开通坐席累积4000+,共关联938个微博账号,平均一周的会话量达26000条、独立访客数达20000+,帮助注册用户接待历史会话35W条,接待27.2W访客。第一期使用效果较好的企业分布在电商、3C数码、快递、婚纱摄影等行业。

   微博与环信联合推出这套多客服系统,是为了更好地连接人与商业,帮助基于微博的用户更快地成长和成功,为企业和微博大V节能增效附加了更强的客户服务沟通能力:

   1、 降低开发门槛,无缝接入大量信息。开通账号即用,信息进入多客服系统后可以实现智能分配,通过路由设置的熟客优先、空闲率等原则,分配给最合适的客服接待。同时可以根据问题类型、咨询兴趣、商机程度的不同直接对应不同的技能组直接服务,避免等待和流失。


TIM图片20170712112117.png


   2、 统一平台管理账号矩阵。涉及到一家企业或一个运营方需要维护多个账号的情况,可以统一绑定到一套系统中,免去来回切换之苦,统一管理所有消息。

   3、 多渠道接入,不止于微博。对于微博客服渠道,除了天然能获取到的评论、私信、@等消息,更将消息范围扩展到订阅评论、评论中@等。除了微博渠道,企业的其他客服入口如微信、官网、H5等消息也可以一并接入环信多客服系统。

1.png


 4、支持用户画像,帮你更了解TA。不仅能够帮助你获取到非粉丝用户信息及基于昵称的用户UID,还可以结合用户轨迹、行为、互动记录等手动打标签,丰富用户画像,应用到自身业务场景中,更有针对性地记录客户偏好并与客户进行沟通。

2.png



3.png


 多客服系统入口:管理中心—粉丝服务—多客服系统
 
   新浪微博首席执行官王高飞表示:“微博专注于提供中国最好的社交媒体服务,促成了微博强劲的第一季度业绩。展望未来,我们预计将继续保持强劲增长势头,将和合作伙伴进一步优化微博分享、发现和消费信息的竞争力,特别是在移动、社交和视频的场景中。”

   融入了环信移动智能多客服能力的新浪微博平台,秉承的是更加开放、更加精细的商业平台生态构建原则,不仅仅是对商业成功的追求,更是希望致力于提升用户体验,以客户为先,帮助客户成功。
 
点击查看微博多客服系统攻略
  收起阅读 »

【环信征文】Android 开发之应届狗从掉洞到填坑之路

在开发了几个项目之后我决定写篇文章分享一下一路走来的经验教训。 一、在开发中的话慢慢你会理解(如果觉得专业知识警示不想看可看本人写的二部分一点感悟,颇为精彩!希望给予你收获,嘿嘿!) 1.好代码像好的段子,不需要多余的解释。如果你的代码是不解自明的,那么大多数...
继续阅读 »
在开发了几个项目之后我决定写篇文章分享一下一路走来的经验教训。
一、在开发中的话慢慢你会理解(如果觉得专业知识警示不想看可看本人写的二部分一点感悟,颇为精彩!希望给予你收获,嘿嘿!)
1.好代码像好的段子,不需要多余的解释。如果你的代码是不解自明的,那么大多数情况下,它并不需要注释和文档。
在使用任何第三方库之前都要三思,这件事非常严肃,别人不维护了怎么办,突然改别的需求了又咋办,自己没进步不知道原理咋办,是不是觉得自己要亲力亲为呢,如果学习了别人的原理去使用,对自己是一大突破,那天自己也能封装个呢,嘿嘿。

212e000206a62a09af6b.jpg



2.除非必须,不要使用数据库。2017再多不过发生的几大事情中,很多都是从删除到跑路,当让前提要自己跑的安全。脱得干净,会丢锅。但是你可以尝试使用realm(第三方数据库),这个真的不错。项目很快就会达到65k方法,真的很快,此时可以求助Multidex。


E84ACF8A154B2E51DE9543662FF3F608.gif



3.RxJava是AsyncTask的最佳替代,而且它远不止于此,此前一个月一直在学习,用上了保证你爱不释手,嘿嘿!
Retrofit是最好用的网络库,不要自己写Http客户端,可以用Volley或OkHttp。
附上一个我喜欢的链接,讲的还是比较透彻的:http://blog.chengdazhi.com/index.php/140 
4.使用RetroLambda缩减代码,我能想到人生最cool的事,就是把RxJava、Retrofit和RetroLambda绑在一起。


2016-12-05-cc4709b76a6aa9763528ada82f7406c2.gif



5.EventBus挺好用,但我不会用太多,因为代码会变得很纠结,不过难者不会,难免有大佬喜欢用。

6.通过功能分包,而不是通过层。这样子功能模块会越发的清晰,但是如果有习惯,那请自便。

7.不要在UI线程中执行逻辑代码,不然可能会ANR。作为新手的我遇到过几次,但是后来我学会注意了,希望后人谨慎!

8.使用Lint检查Layout层级可以帮你发现没用的View,兴许可以去掉。

9.使用Gradle以及默认项目结构。

10.把密码与敏感数据放在gradle.properties里。(译者注:或许更好的方式是把这些数据放在local.properties里,然后把这个文件加进.gitignore)

11.使用styles来避免在Layout文件中写重复代码。

12.不要让ViewGroup层级太多。(会过度绘制)

13.监控电量,充电时可以进行更多的数据更新,低电量时停止数据的自动更新。
14.当系统缺少内存(而不是应用缺少内存)时,系统会调用onLowMemory()方法,所以OOM原则上无法避免。这个嘛我遇到的少,但是还是要记住。
15.使用Account Manager来提示登录所需的信息(用户名、邮箱、密码等)。
16.给方法一个明确的命名,要能顾名思义,作为一名新入门选手这个真的很重要,搞不好就不记得这个代码是不是自己写的了,哈哈!

2016-05-21-37ed343e41a53af66bb76242c66d8b5a.jpg



17.启动界面是应用带给用户的第一体验,如果不需要启动界面,那不要无故添加。要不然后果可想而知(有的启动界面太炫酷,导致用户进不去的真是在我身边发生过)。


2016-05-21-3301241d475b43d63fda2b2fb4c29c02.jpg



18.保持colors.xml文件短而简单,只写基本颜色就行。;保持dimens.xml文件简单,之定义基本常量。

19.当要时常修改一个字符串时,使用StringBuffer或StringBuilder(后者不保证线程安全)。

20.为了避免内存泄露,不要在AsyncCallBack中保留View引用!不要让静态对象持有View引用!

21.最好不要在集合框架中存储View,但你也可以使用WeakHashMap。

22.FlatBuffers是一个高效的跨平台的序列化类库,建议使用,尽管本人没用,但是觉得很好用,学习了一点。

23.Serializable实现起来很方便,但性能是真的差。

在开发过程的注意先说这么多,希望对大家有所帮助。希望给你带来一丝丝感悟,嘿嘿!

二.生活,关于一个应届狗,对实习半年的总结

 转眼间大学生活走到了尽头。人们需要仪式感,所以无论情不情愿,总要和过去的自己诀别一番。尽管你我都知道,毕业后不会是一个更新的自己,只会是一个更老的自己。


2016-01-31-6309d659d99d4f5049577f322e4c8907.gif


只是当你在午夜检点行藏,追忆过去日夜里,回想年初制定的那些计划,有太多的事情值得仔细思量。
csdn是一个让人着迷的地方,人们用各式各样的方式展示他们的博学、美丽和健康(无意给csdn打广告)。环信论坛也是一个讲道理的地方,在这里一切都可以找到方法和经验。所以你看到这里程序员谈笑风生年入百万,健身狂六块腹肌也只一般,营销有秘籍,美容有秘方,屌丝逆袭太简单。好像美腿美颜都不是天生,世上无难事,只要肯登攀。


2016-05-21-3301241d475b43d63fda2b2fb4c29c02.jpg


 
这一切都让人产生错觉。于是我们立下许多flag,仿佛自己也能跟他们一样。
你说自己要瘦成一道闪电,要从130减到120。你办了健身卡,加入夜跑团,心心念念就是自己的计步排行。你每天拍一张照片想见证一个奇迹的诞生。有没有瘦有没有瘦,你特意等了两周才站上体重秤,上面写着61kg。哗,你的三观就此崩塌。你不到一个月就坚持不下去了。该吃吃该喝喝,人生贵在适意过,微胖一点又如何?半年后你忽然想起健身卡上还有几千块钱,心想别浪费了,然后发现健身房烟消云散老板已不知去向,原来的门脸换了主人。老板娘一脸粉饼一脸热情,帅哥美容吗,办个卡吧?
你说未来是互联网的天下,要转行当程序员,上追马化腾下追温赵轮。你买了算法导论和21天精通C++,从谭浩强看到 Bjarne Stroustrup。一入编程深似海,你终于在第20天的时候撑不住了。在此期间你的学习目标从C++、java换成了python,在下载盗版Visual Studio的时候中毒丢失了所有的种子。你备受打击,原来教程里都是骗人的。你打开一个新世界说了句“hello world”,世界回了一句“get out SB”。你灰溜溜地卸载VS,重新装上了最爱用的360软件管家。


2016-05-21-dd4b54f2eb4cc08b5782ec5d02c939c6.jpg




你说要恶补英语提升职场价值,李阳疯后舍你其谁。你下载了沪江英语和哈利波特原版小说,每天在有道上秀出自己羞涩的发音,得到85分的评分。你在地铁上枕头上马桶上背单词。你追随奶爸的脚步刷着书单,最后变成了奶带逛。终于你的哈利波特永远停在了第一章,词汇永远在5000打转,听力就像罗永浩说的听了3000张英文唱片除了fuck什么也没听到。你搞不定任何一个多音节单词的pronunciation,只有第一页的abandon没齿难忘。


17_-_1.webp_.jpg



有人曾经说为什么地铁上都是学英语的而不是其他,因为学英语是失败了也不心疼的。我们已习惯一次次的跳票和失败,有些事你我早已心知肚明。我们都是平凡人,在牛人出没的地方有了自己也优秀的错觉。如果一个人是因为看了环信博客上的知识、经验和见解才开始计划,那么十有八九是坚持不下去的。坚持是种稀缺品。我们能坚持的常常只有平庸。那些能够成功的人,往往早就养成了成功的习惯,不会等到知乎和环信论坛的出现。

哈哈,是了。 这不是生活的真谛,却是一个残酷的真相。我们都是平凡人,平凡到一年的生活真的可以用一句话来总结。因为除了年龄,一切都没有改变。

于是平庸的日子一年一年。我们总会在年初的时候立很多的flag,又在年末的时候亲手拔掉,开始一个新的轮回。

然而,这平凡的一年中有多少刻骨铭心的快乐、痛苦、感动和辛酸,只有我们自己知道。人的命运又怎么能跑过历史的进程,除了他又有谁能永恒?也许我们最终也会甘于平凡,但至少我们努力过挣扎过振奋过。哪怕它唯一的意义只是在夜深人静的时候,被自己感动得热泪盈眶。


2016-11-12-3b4a954ea34d51b3110268ef1cb8a745.gif



一首旧作,聊寄衷肠。

白马秋风塞上,杏花春雨江南。九十还续旧因缘,世事浮云过眼。
理想绝逼是病,节操果断换钱。不当大V好多年,听取呵呵一片。
 
 
  收起阅读 »

环信CEC给保险行业提供全流程客户互动解决方案

       2017年7月6-7日以“保险科技,创新保险生态”为主题的中国保险IT应用高峰论坛在北京召开。环信CEC(Customer Engagement Cloud)——全媒体智能客户交互云,基于全球领先的即时通讯云技术,通过人工智能和大数据赋能,在保...
继续阅读 »
   
   2017年7月6-7日以“保险科技,创新保险生态”为主题的中国保险IT应用高峰论坛在北京召开。环信CEC(Customer Engagement Cloud)——全媒体智能客户交互云,基于全球领先的即时通讯云技术,通过人工智能和大数据赋能,在保险行业积累了大量关于移动化承保保全、视频客服车损定险、机器人自助理赔、精准用户画像主动营销等落地经验,提供了从客户互动渠道、到客户服务、再到精准营销的全流程客户互动解决方案,典型用户包括中信证券、泰康在线、中意人寿等。截止2016年底,环信CEC共服务了58541家企业客户,现已覆盖包括保险、证券、银行、电商、教育、O2O等领域的众多标杆企业。

ea790d9dly1fha0pwdxwkj20zk0qomzy.jpg




ea790d9dly1fha0n74k4tj21kw1h7k0a.jpg




ea790d9dly1fha0muqy60j20zg1bqqa2.jpg


  收起阅读 »

简商沙龙:B2B电商如何玩转在线供应链金融

    B2B电商“春光乍现”,引入金融服务已有基本共识,且条件初步成熟。在线金融的增值服务对平台盈利及生态构建至关重要。 但,尚需解决以下两个问题: 1、B2B电商需要具备哪些能力才能更好地对接在线供应链金融服务? 2、适合B2B电商的在线供应链金融服...
继续阅读 »
    B2B电商“春光乍现”,引入金融服务已有基本共识,且条件初步成熟。在线金融的增值服务对平台盈利及生态构建至关重要。

但,尚需解决以下两个问题:

1、B2B电商需要具备哪些能力才能更好地对接在线供应链金融服务?

2、适合B2B电商的在线供应链金融服务应该具有哪些特点和能力?


B2B电商如何玩转在线供应链金融?

本期简商沙龙特地请来前IBM高管、现任国付宝CTO邓明和B2B电商资深从业者、对产业互联网及B2B电商有独到见解的现任1号签联合创始人胥明为您解读,机会难得,仅限30人,快来报名吧! 

微信640x360.jpg


嘉宾介绍



胥明.png


1号签 联合创始人 胥明


胥明,业内资深的产业互联网观察者,对互联网商业模式和B2B垂直电商具有近20年的研究和实践经验,B2B 1.0时代就曾经主持研发过数个大型B2B交易平台,对B2B有独到见解,现任第三方电子签约平台——1号签的联合创始人。



邓明.png


国付宝 CTO 邓明


IT老兵。1999年入职IBM,在GBS部门供职15年。先后涉足电商、银行、电信、石油石化等多个行业。现任国付宝CTO。
活动概况
受众:
B2B电商创始人、联合创始人、VP及高管
B2B垂直媒体负责人、记者、编辑

规模:30人(审核制,凭名片入场,谢绝空降)

价格:80元/位
注:分享到朋友圈后,截图给主办方可免费参与

活动流程:
13:30-14:00 签到+茶歇
14:00-15:00 主题演讲:《彻底的全线上交易闭环,重构B2B未来》
15:00-16:00 主题演讲:《B2B电商的在线供应链金融》
16:00-17:00 互动交流

时间:
2017年7月12日(周三)13:30 - 17:00

地点:
北京泰智会创业空间(丹棱街一号互联网金融中心一层103):地铁10号线海淀黄庄站A2口出,步行5min即到


路线图.PNG


主办方简介
1号签
1号签是国内领先的第三方电子签约平台,可实现合同文件在线签署,以拥有专利技术的线上签约取代现行签约方式,在金融、旅游、B2B、互联网、教育、房地产、物流、人资等行业及政府机构广泛应用,同时提供举证与司法鉴定等法律服务。




国付宝
国付宝信息科技有限公司是由商务部中国国际电子商务中心发起,与海航集团联手组建的,精心打造国有背景独立第三方支付平台。依托国有背景、先进支付技术推出“国付宝”系列电子支付产品,于2011.12.22日正式获得中国人民银行颁发的互联网支付和移动支付业务许可证。经过多年发展,现已成长为具有互联网支付、移动支付、基金支付、跨境支付、和预付卡支付业务的综合金融支付服务平台。
场地简介
泰智会
泰智会是总部设立在北京海淀区的全国创新载体运营商和科技服务商,通过服务企业、产业组织和产业园区,满足企业发展规模提升中的融资、产业落地等各类需求,给产业园区注入生命力,形成完整的产业生态系统,是创新的“产业”孵化体系。泰智会正在北京、深圳、上海、成都、西安、武汉等8个城市和美国纽约落地建设。


微信图片_20170706144123.jpg




场地内部路线.jpg


组织机构​

logo汇总图.jpg


 
PS:活动咨询及市场合作请联系王女士,13501399269(电话及微信)wanghan@enjoysign.com
活动报名:点击报名 收起阅读 »

从传统客服到电商客服管理,需要过几道坎?

    不可否认,电话客服已慢慢没落。究其原因有很多,但主要是成本过高,加上新生代的沟通方式发生了很大的变化。    逢电商的蓬勃发展,促使在线客服大行其道。传统客服的机会越来越少,新兴行业的发展却越来越迅猛。于是,很多人尝试从传统行业跳到电商行业。 ...
继续阅读 »
    不可否认,电话客服已慢慢没落。究其原因有很多,但主要是成本过高,加上新生代的沟通方式发生了很大的变化。

   逢电商的蓬勃发展,促使在线客服大行其道。传统客服的机会越来越少,新兴行业的发展却越来越迅猛。于是,很多人尝试从传统行业跳到电商行业。

   问题来了,一直从事传统电话客服管理的人,有没可能容易华丽丽转身到电商客服管理?要做怎样的积累?
 
从我经验看,从传统客服转变为电商客服管理,还是比较容易的。只要在传统客服管理体系中增加三个知识点,就能顺利转变为电商客服管理了。这三个知识点是:
 

  • ☑入门级电商指标。

  • ☑人货场理论

  • ☑电商客服管理


 
先定义本文的2个概念:
 
[list=1]
  • ☊ 传统客服:指通过电话接入提供服务。

  • ✎ 电商客服:指通过在线接入提供服务,这里特指天猫,京东、独立商城的实物商品零售客服。


  • 一、入门级电商指标

       这不是本文重点,所以我只概述性描述,起到抛砖引玉的作用。sorry,这里并不会告诉你电商是什么,是怎样发展的诸如此类的知识点。在我看来,把电商的各个指标搞深搞透了,就算是入门了。我只列举,详细大家可度娘。 

    • 流量指标:PV、UV、跳失率、平均停留时长、平均访问深度。

    • 商品指标:售罄率、动销率

    • 客户指标:销售额、客单价、件单价、客件数、动销率。

    • 库存指标:库存天数、库存周转率、售罄率。

    • 物流指标:订单满足率、订单响应时长、平均送货时间。

    • 退货指标:金额退货率、数量退货率、订单退货率。

    • 会员指标:会员留存率、会员复购率、会员回购率。


     
    二、人货场分析

    电商的本质是零售。所以很多零售理念可以用来分析电商行业。其中人货场思维模式最为普遍。

    这个也不是本文重点,借用@黄成明《数据化管理》一书中的思维导图进行说明:

    微信图片_20170705114344.jpg

    三、电商客服管理

    电商的在线客服与传统电话客服相比,差异不大,管理方式甚至是一样的。主要有以下四方面的区别:

    岗位设置不一致

    传统客服简单的组织架构分现场管理、培训管路、质量管理。我在《3招搞定自建客服中心》一文有提,这里不再重复。电商客服也是一样,区别主要在于电商客服的售后岗位和评价岗位。以下举一个电商组织架构的栗子:

    微信图片_20170705114459.jpg

    在线指标不一致

       几乎全部电商都是在线客服或者混合型。显而易见,由于在线客服是文字聊天,所以与传统语音客服在指标监控上会有不一致,以下列举在线客服特有的重点指标:
     
    销售数据
     

    • call in转化率=询问客户数/总IP。

    • 询单转化率=经询问后成交的客户/询问的客户数。

    • 静默转化率=未经询问直接拍下付款的客户/总IP。

    • 全店转化率=所有成交客户/总IP。



    效率指标
     

    • 最大同时接待数:在所选时间内,客服同时接待的最大值。(同时接待的定义:一个客服在某一时刻前后两分钟内有聊天的客户数。

    • 回复率=回复过的客户总人次/总接待人次。

    • 慢响应人数:同一聊天中,超过3次,每次回复间隔超过120秒的人数。可自定义次数与间隔时间。

    • 长接待人数:一般定义为超过20分钟才回复相应的客户数。可自定义时间。



    人工智能应用更为广泛

    目前客服行业的人工智能,主要是回复一些通用程度较高的问题,这只是一些日常的简单问题,用人力回答会耗费太多资源,用人工智能系统去回答的话,只需要告诉对方简单的流程步骤即可。具体如下:
     

    • 24小时客服在线,全天候相应客户咨询与需求。

    • 建立客服机器人的知识库,用深度学习方式自动回复重复问题。

    • 接入人工时机器人给予部分回复建议,加快反馈速度。



    当然,有部分厂商产品可以做到智能监控、智能质检等,但未十分成熟。

    客户信息“大”数据化

    电商客服,客户在店铺中的所有行为都被记录在案并能进行查询。这与传统电话客服系统只简单记录客户通话记录与客户订单信息有很大差别。

    客户信息的“大”数据化,最大的一个应用是:用户画像。简单点讲,就是给客户贴标签。具体现在不展开了,用户画像可以从以下几个方面收集信息:基本属性、购买能力、行为特征、心理特征、兴趣爱好等。

    传统客服与电商客服,在本质上是一致的。所以,想要从传统转变为电商客服,需要花的时间不会很长。

    本文作者:陈秋良

    本文首发公众号:陈秋良 收起阅读 »

    经纬熊飞:企业服务行业如何先赢而后战

           企业服务并非科技新兴领域,早在上世纪70年代,美国已出现SAP、微软、Oracle这样的ToB公司,成长为巨头。在国内,由于经济快速增长及人力成本低廉,一直以来,企业服务市场属于少为人知的领域。2012年起,国内GDP增速放缓,人力...
    继续阅读 »
       

    201707039141499064337064.jpg


       企业服务并非科技新兴领域,早在上世纪70年代,美国已出现SAP、微软、Oracle这样的ToB公司,成长为巨头。在国内,由于经济快速增长及人力成本低廉,一直以来,企业服务市场属于少为人知的领域。2012年起,国内GDP增速放缓,人力成本增长问题凸显,同时2013年棱镜门事件后,国内加大去IOE力度,也为企业级服务创业提供了较好的发展土壤。

       经纬创投是最早布局企业服务领域的机构。从2012年开始,经过5 年的探索与沉淀,目前在经纬系布局的近50家企业服务创业项目中,有北森、销售易、七牛、永洪BI、OneAPM、环信、GrowingIO、亿方云、上上签、佳格数据、盖雅工场、Pingcap等已初露锋芒。

       今天的文章来自我们与经纬董事总经理熊飞的一次交流,希望对你有所启发。以下,Enjoy:“企业服务项目到底怎么投?两个核心关键点。

    Q:在我看来,做VC有个能力:当有经验积累后,挑项目的时候,是能够预判出项目发展路径的。但问题在于,当一个项目到了一定的标准,投与不投,是多维度进行判断的。比如Saas,中国Saas目前看来还比较难做,如果满足了基本条件KPI达标,那么超越KPI的标准是什么?在此之上经纬看重什么?

    熊飞:第一点,是个大市场。比如CRM,再比如人力资源,也有很多细分项目,比如做核心人力、做招聘,但肯定不只是做一个报表工具。企业服务公司所处的市场足够大,这是核心。企业服务本身是让企业为该职能相关痛点去付费。而销售、HR、客服、财务等职能,是企业最核心职能,痛点的商业价值最大。所以大市场的基础,是该产品关注的是企业核心职能,以及解决的是核心职能中的核心痛点。

    第二点,要考虑这个项目是不是处在浪尖位置。我们经常说投浪尖。三五年前投Saas,那个时候对于早期项目来说是一个浪尖。过去一两年投infrastructure(IT底层架构),也是个浪尖,比如说marketing automation(营销自动化)、iot等等。所以如果你现在做客服Saas创业就不是浪尖了,因为已有环信这些头部项目。浪尖的优势在于你是最早做的,所有资源都给你。

    总结一下:它应该是这个领域最早的探路者,且速度一直高速增长。如果市场够大,并处于浪尖的位置,是先人半步与先人一步的机会,这个我们是非常看重的。“企业服务,产品技术导向的创始人更有优势。

    Q:在这两点满足的前提下,关于团队层面,有什么体会?你们看重创始人的哪些特质?

    熊飞:我觉得没有完美决策,我们常说VC是一个判断+运气的连续体,但投ToB靠判断会更多一些。做的每一个判断都希望结果是大概率事件,但所谓大概率也只能证明这个项目七八成应该投,但没有百分之百。

    我个人倾向产品技术导向的创始人。在我看来,投产品技术导向的团队没什么下行风险,但上行收益巨大;因为产品技术好,最差情况就是没销售,但优势在于产品壁垒高,一旦市场找到感觉,找到销售合伙人,业务可能就会以5 倍、10倍增速发展。但纯销售导向创始人,早期业务起来比较快,但如果竞争对手是产品技术导向,对手一旦找到市场感觉和销售合伙人,下行风险就很大。

    宏观来看,企业服务公司产品技术的护城河宽不宽,有没有留下足够多的安全边际,是我们很关注的点。这也是经纬系企业服务公司,为什么普遍发展很扎实、高速健康增长的原因。我们在投的时候,是希望跟产品技术导向、着重于打磨自己产品的创始人去沟通。

    Q:说到产品和技术,其实相对难判断,ToC可能是看KPI;ToB的话,特别是一些早期公司除了看创始人过去的背景,怎么去判断呢?

    熊飞:我觉得有几点,第一,做reference track,团队的能力,是可以通过reference相当程度判断。

    第二,团队投每个领域都会投入很多的时间,要了解趋势,知道有哪些领先的公司。形成初步投资假设。再去和公司聊发展、聊产品,就能够比较快的判断出这个团队的视野、产品意识。

    第三,就是一些标杆客户的反馈,这个是实打实的。做到这三点就很快能做出不赖的判断。“先赢而后战。

    Q:经纬五年前就开始布局ToB,坚持到现在。在我看来,五年前的时候应该非常寂寞。直到2015年大家才普遍觉得 ToB是风口,这期间你是怎么去判断的?

    熊飞:投ToB其实投的创始人的特质,往往都是比较踏实、稳重、重逻辑、重积累,团队专注某一个方向;ToC则不然,可能需要创始人是愿意快速变化的人——这两类人是完全不一样的。

    另外,我个人觉得在中国投ToB的长期回报会比美国投ToB好很多。原因在于:

    在美国,因为Salesforce、Workday等已有领先者产品的市场占有度很高,导致创业公司长不动、长不大,很多都是10亿美金、12亿美金被并购。在中国,ToB领域竞争并不激烈,因为没有产品供给,很多公司创业两年,就可以做中国500强的生意,这在美国不可想象。所以从长期来看,国内 ToB创业公司的天花板显著的高。

    另外,从运营效率来看国内Saas创业公司也有不小优势。美国很多Saas公司大概做到1 个亿美金收入还在不停亏损,还要不停地往前赶,很难实现现金流打平。但在国内,至少我们投的很多Saas公司做到亿元人民币量级的时候,或者之后一年,就有机会做到单月盈亏平衡。

    最后,从经纬角度来说,最核心是投产品高壁垒和护城河足够宽的项目,比如像HR领域的北森现在发展很好,五年后还会发展很好、再比如销售易、环信、GrowingIO……这些公司现在很好,我们也能看到它们五年后都会很好。

    大核心、大前提还是投到最优秀的公司。我很喜欢《孙子兵法》里面的一句话——先胜而后战,你要先确保你大概率能赢的再去打。张颖有一句话,叫自强则万强,只要把产品、技术做到行业内非常领先,我觉得融资的问题都是业务问题。“企业服务这么火,创业到底是该切入大客户还是小客户?

    熊飞:经纬投企业服务五年时间,这个行业的发展是超出预期的。几点原因:

    中国人力成本的提高到了一个转折点。我经常举例子,六年前一个人工资大概3000元 / 月,一台电脑5000元。现在反过来了,一个人工资5000元,笔记本电脑的价格只有2000元。企业主是很理性的,以前2:1,现在变1:2了,他希望更大投入提高效率。而且,最近中国经济增长放缓,三年前企业主都在谈拉贷款、扩产能,但是现在想的是如何高效地去提高利润,也落在软件上。

    我有个观察,ToB市场爆发,不是留给海外巨头,而是给国内创业企业的巨大机会。很像七八年前智能手机的市场,当时移动手机市场刚起来,大家知道苹果、三星非常好,可是一台手机要六七千块。所以需求起来的时候,性价比更高的国产手机,小米、OPPO、华为、中兴爆发式增长。ToB领域也类似,软件从最初大型和超大型企业的刚需,过渡到中型以上企业的刚需,而这个爆发的市场更关注性价比和产品体验,使得国内创业公司成为最大受益方。

    Q:那么现在如果再做企业服务创业的话,是否理想的客户反而不是中海油、中石油,而应该是中型企业?

    熊飞:我们投的大部分成功企业服务公司,不是一上来就瞄准中海油等超大型企业,无法一击即中,因为超大型企业的功能需求太多了。它们往往是先瞄准100人到300人的中型企业,或者是中型偏小型企业,要先快速上手,再逐年向上走,今年可能是服务100人到300人的企业,明年可能是300人到800人,后年可能是1000人到2000人。随着功能不断地添加,这是一个“逆流而上”的策略。

    Q:有个现象非常有趣——很多企业服务创业者会在两头摇摆,以前做大客户出身的会非常痛恨做大企业,过去诸如催款、服务等等小事,CEO、工程师动不动就被叫过去处理问题。 经历过做大客户的,现在就愿意做小企业或者中小企业,他觉得我是产品说话,不会像以前那样被牵着鼻子走;但又会发现一个新问题:收费有点困难。小企业消失得快,或者是需求率不高。他们就像一个钟摆在不断摇摆。你怎么看?

    熊飞:我觉得一定要做中大企业。一点一点往上。全球IT投入90% 来自于财富两千强,再90% 来自于两万强,你做不到两万强的生意,你就只有1% 的市场,自然这个公司能够成为一个很大的、很牛的公司的概率也变得很小。“投资的魅力所在:不断地去证伪。

    Q:经纬企业服务团队做的最快的一次决策多长时间?为什么?

    熊飞:最快决策是当天见完觉得可以投,就签下TS。能这么快的原因是,团队在该领域已做了足够多思考,见了足够多公司,当遇到这家公司时,其实是捅破了这层“窗户纸”。

    另外,我认为投资的魅力所在,是一个不断证伪的过程。VC这个行业是一个idea business,所有的回报取决于你的idea质量,本质在于两点:

    第一,generate idea的能力,就是说你的视野够广,经常在一线跑,有很多的思考。

    第二,证伪idea的能力。如果你没有证伪idea的能力,那就变成了自己做空中楼阁的假设。

    经纬企业服务团队每天都在不断地拼命去证伪——比如17年初定了三四个ToB的主方向,现在看有两个觉得不错;但是已有一个觉得机会不大,还有一个待判断。所以每个季度都在推翻自己投资的思路和假设。

    Q:Peter Thiel的书《Zero to One》里说过创投要有一个非常规的想法。如果说你提一个跟ToB相关的观点,比如“我觉得我这么认为,但是其他的投资人未必是这么认为的”。如果有,是什么?

    熊飞:我觉得是中国企业服务创业公司机会规模,10倍于目前美国企业服务创业机会。原因在于,美国在enterprise是三波的创业浪潮,第一波是上世纪70年代到80年代,像SAP、微软、Oracle,他们现在都是1000亿到3000亿美金的公司。第二波是云计算,从上世纪90年代末到2000下半叶,这时崛起了Salesforce、workday、NetSuite、ServiceNow这一系列公司,从几十亿美金到六百亿美金。第三波就是现在,现在有一些AI企业服务创业公司开始起来。

    在中国,这三波发展是融合在一起爆发的,三、四年前没有人谈企业服务,现在所有人都在谈企业服务,所有人都在谈企业服务直接上云计算,所有人都在谈企业服务和AI的结合。所以三波浪潮的合并,使得目前中国企业服务创业公司的天花板显著的高。

    Q:会不会有这样一个趋势,SAP这些公司等于是压在中国公司头上的石头,首先会有一批企业服务本土企业。未来中国公司出海,反过来最后会不会变成中国公司把SAP干掉?

    熊飞:第一,我不知道会不会干掉,但我相信未来的5 到10年中国的企业服务公司会在全球企业服务市场将占据重要地位,原因有两点:一是随着中国企业的出海而出海;二是价格优势,SAP、Oracle现在是一个85分到90分的产品,但我们中国的企业服务产品现在很努力地在赶上,虽然可能还是一个75分的产品,但是价格是其1 /3。三是,未来中国企业的最佳实践,会成为第三世界国家(企业服务下一波机会所在地)的最佳实践。 收起阅读 »

    【环信征文】Android程序员北漂记-从逃离北上广到逃回北上广

    司马雼是我的学长,先后在国内两家top 10大厂担任资深Android工程师,对Android技术有如痴如醉的热情,并且乐于帮助同行,最难得的是他还有一个漂亮的女朋友,不愧是Android程序员中的人生赢家。我将他的经历稍作加工后用明清小说的笔法写出来,希望每...
    继续阅读 »
    司马雼是我的学长,先后在国内两家top 10大厂担任资深Android工程师,对Android技术有如痴如醉的热情,并且乐于帮助同行,最难得的是他还有一个漂亮的女朋友,不愧是Android程序员中的人生赢家。我将他的经历稍作加工后用明清小说的笔法写出来,希望每个读到这篇文章的Android工程师都能走他的路。

    第一回:小庙无地容巨擘 大厂有礼迎硕士
    诗曰:

    老板抠门巧计乖,却将忠义苦挤排。

    基础扎实绩点高,苍天岂能误人才。


    司马雼2008年考入合肥工业大学,2012年保研本校,2014年进入合肥某小公司实习。

    司马雼一开始选择的是JavaEE方向,他在实习期间就以专家的标准严格要求自己,不但让服务端的内核稳定度提升了好几个档次,还让内存消耗下降了好多个数量级。完成本职工作后还帮助运维那边修复了几次硬件的故障。不料老板嫉贤妒能成性,只爱奴才,不要人才。这个老板不但不给司马雼升职加薪,还侮辱司马雼:““雼”是“宕”的繁体字,你越俎代庖搞运维不怕把服务器搞宕机?”信而见疑、怀才不遇的司马雼愤而辞职。司马雼辞职刚好赶上某大厂(国内top 10)招Android实习生,他突击学习了几天Android就去面试了。

    一面的时候主要考察Android和Java的基础知识,比如Java的数据类型、运算符优先级和Android的布局以及生命周期,基础扎实的司马雼都能准确无误地回答。

    二面的时候面试官问了许多数据结构和算法、设计模式、架构的方面的问题,司马雼不但能画出好几种设计模式的UML图,还对MVC、MVP、MVVM的区别和优缺点发表了自己的看法。

    最后HR面的时候收了司马雼的成绩单复印件,对他4.0的GPA和专业top 5%感到很满意。

    司马雼通过了面试,顺利成为该厂的Android实习生。不久,司马雼以专业top 5%的优异成绩硕士毕业,转正成为Android工程师。而那家小公司呢,不知道什么时候就因为bug太多导致用户严重流失而倒闭了。

    异史氏曰:Java玩得6的学生选择Android作为发展方向是一个明智的抉择,这个世界正处于、并将长期处于移动互联网时代。校招面试除了考察Android和Java基础知识,还考察你学习的基础理论课程的知识,最后通常还要收成绩单的复印件。大厂的校招面试一般有固定的问题和模式,比如阿里校招笔试题来自《技术之瞳》,微软校招笔试题来自《编程之美》等,尽管临阵磨枪也有一定的成功几率,但别忘了玩3年LOL的枪不可能比刷6年LeetCode的枪更快。(时间没错,沉迷LOL的大学生都考不上硕士)

    第二回:荣升高级愁田舍 游子低头思莼鲈
    诗曰:

    当年许汜初炒房,羞无才气见刘郎。

    如今司马有远志,却愁无房迎新娘。


    炒房团自古有之,祖师爷是东汉末年的许汜。当年许汜空有国士之名,却全无救世之意,整天就知道求田问舍,因此被胸襟海阔,志向山高,忧国忘家的刘备鄙视。此事有辛弃疾《水龙吟》为证:“求田问舍,怕应羞见,刘郎才气。”

    司马雼和许汜的志向有天壤之别,他的梦想就是把有限的生命投入无限的Android技术中,他不甘心每天只做UI的微调,他发现App存在很大的改进空间,并付诸行动。

    司马雼对App的代码进行了大规模重构,在MVP与MVVM中选择了MVP架构,并自主研发了一套的网络请求框架(结合了OKHttp和Gson,可以理解为国产的Retrofit)(该框架不开源,类似框架的源码:https://github.com/qiujuer/OkHttpPacker)代替OKHttp。这样一来不但减少了大量冗余代码,层次结构也变得更加清晰。


    订单状态这种需要和服务器实时同步的数据,以前一直用每秒一次的轮询,司马雼发现这是App又费电又费流量的祸根,采取了用推送代替轮询的解决方案。


    APK瘦身也是Android性能优化的重要组成部分,司马雼去掉了很多不必要依赖和重复的工具类,让APK打包后的体量轻了一半。

    两年后,这个App完成了从3.3到6.3共13个版本的迭代,App的启动速度提升了120%,Crash 率也由8‰降低到1‰。立下汗马功劳的司马雼被任命为项目组长、技术指导、高级工程师。

    尽管司马雼工作兢兢业业,也为我国的开源事业添砖加瓦,还写技术博客帮助了很多人。北京高昂的房价却让他有点羡慕那个被他鄙视了多年的许汜。

    异史氏曰:Android工程师(在没有“高级”等前缀时)每天最多的工作都是UI的改来改去,想在平凡的工作中取得不平庸的业绩就要付出努力,提升App的性能是有效途径之一。贡献开源代码和分享技术文章的时间也是可以挤出来的。如果在工作中有出色的成绩,升职加薪只是时间问题。

    第三回:桑梓惜别因缘浅 楷模入职即资深
    诗曰:

    北京买房要筑台,还有堵车与雾霾。

    回到省会想定居,一问工资又回来。


    北京的房价、堵车、雾霾逼得司马雼决定裸辞,逃离北上广,他的目的地是上了七年学的合肥。他刚辞职,老东家的最大竞争对手(全国top 20)和另一家全国top 10的大厂都邀请他去面试。他两个月来参加了这两家大厂和合肥当地两家大厂的面试。

    面试官首先询问的总是Java和Android的高级特性,Java的高级特性主要有JVM模型、类加载机制和GC原理等,Android的高级特性主要有几大FLAG和LauchMode的区别和使用场景、Binder的引用和实体以及权限系统的交互等。司马雼对技术钻研很有深度,总是对答如流。


    面试的第二阶段就是让司马雼自己去讲他做过的项目,然后面试官会冷不丁的让他去解释其中某一部分,有时候让他解释当时为什么要这么做,有时候问他现在觉得有没有更好的办法。司马雼处理问题的思路和解决问题的能力给面试官留下了深刻印象。


    面试官有时候会问一些该企业所在行业需要关注的Android技术,比如研究输入法的公司会询问他Android手势和多点触摸,研究物联网的公司会问他Bluetooth相关知识等。因为司马雼广泛涉猎Android知识,他的技术广度也让面试官啧啧赞叹。

    每次面试官问司马雼:“你还有什么想和我说的吗?”的时候,司马雼就把他的技术博客和开源项目一股脑砸向面试官,面试官是司马雼的粉丝或者面试官正在用司马雼的开源项目的情况发生了好几次。

    司马雼在合肥拿到了两个资深Android工程师的offer,尽管合肥房价不到北京的1/3,可是最多30W的年薪让司马雼在合肥买房遥遥无期。这时司马雼接到了一个电话,逃离北京前面试的全国top 10的大厂给了他60W年薪和项目经理、技术经理、资深工程师的title。他决定逃回北上广,逃离北上广的计划刚开始就结束了。

    异史氏曰:有多年工作经验的求职者几乎不需要在求职网站上投简历,想让你做他的同时的同行朋友会内推你。社招面试和校招面试是不同的,社招面试没有固定的问题和模式,临时抱佛脚是行不通的。社招面试基本都会考察这几个问题:第一个阶段是Android和Java的高级特性,考察技术深度;第二个阶段是讲述自己的项目,并在中间穿插着问题,考察解决问题的经验;第三个阶段(未必有)是问该公司所在行业需要掌握的Android知识,考察技术广度和快速上手情况。技术博客和开源项目是很重要的加分项,如果平时不积累、不分享,求职者会失去很多机会。二三线城市的房价更亲民,但工资非常不人性,逃离北上广需谨慎。

    第四回:专家立功施小计 淑女出闺成大礼
    诗曰:

    经验丰富技术精,消除隐患立大功。

    全球大会登讲台,抱得淑女入后宫。


    话说司马雼所在的团队负责公司的Android客户端的安全工作,工作内容包含保活、防拦截、防篡改和防反编译等工作。他发现自家App存在不少可能被恶意利用的隐患:

    首先,坏人可以通过NotificationListenerService拦截自家App的推送,给用户造成自家App没有推送的假象。


    其次,在上一条基础上。坏人可以在虚拟机里运行一个窃取推送App,收到自家App推送后,用AccessibilityService打开Notification对应的Activity,找到里面的WebView,然后取得链接及网页中的内容,稍加修改(换logo、改名字)推送给坏人自己的App。


    此外公司的微信公众号打开自己App需要用浏览器打开链接,这也给坏人以可乘之机。


    更有甚者,坏人最丧心病狂的手段就是卸载了自家App后,在肉鸡中安装一个与自家App的packgaeName一致,但Signature不一样而且没有launcher的假App,这样肉鸡的用户永远也安装不了自家App,而且还不能用长按拖拽桌面icon进垃圾桶的方式删除假App。

    司马雼花了两年时间为公司消除了以上隐患,荣升架构师、技术专家(时间没错,这是小说,出现未来时间很正常)。各大IT论坛、IT活动的聘书和邀请函也如雪片般飞来,不是邀请他做特约作者,就是邀请他当讲座嘉宾。

    某IT大会在北京举行,司马雼作为特约嘉宾在台上妙语连珠、口若悬河。大会期间,司马雼结识了某IT社区的技术编辑椎名,这位淑女负责大会的后勤和报道工作。椎名不但知书达理、兰心蕙质,相貌也倾国倾城,有诗为证:
    乐天浔阳歌《长恨》,陈王洛水赋《感甄》。

    摩诘青溪《西施咏》,潇湘红楼《明妃吟》。


    没错,这诗集合了白居易《长恨歌》、曹植《感甄赋》、王维《西施咏》、林黛玉《明妃吟》,椎名的美貌用古往今来的美女诗都搁一块也写不完。淑女椎名倾慕司马雼的才华,从此司马雼正式脱单。

    不久,年薪100W的司马雼在北京买房定居。又过了几个月,这对为我国IT事业做出了巨大贡献的情侣在北京举办了盛大的婚礼。

    异史氏曰:公司大到一定程度,别有用心的竞争对手就会搞小动作,因此想成为大厂的技术专家,懂点安全方面的知识是很有帮助的。程序员是经常被嘲笑为“注定孤独一生”的群体,但出人头地的程序员抱得美人归的可能性非常大,毕竟女人的颜值通常和她的男朋友的收入成正比。
     
    本文首发于51CTO的IT故事汇:http://mdsa.51cto.com/art/201707/543909.htm 收起阅读 »

    微信后台基于时间序的海量数据冷热分级架构设计实践

       微信的后台数据存储随着微信产品特性的演进,经历了数次的架构改造,才形成如今成熟的大规模分布式存储系统,有条不紊的管理着由数千台异构机型组成的机器集群,得以支撑每天千万亿级的访问、键值以及 PB 级的数据。    作为以手机为平台的移动社交应用,微信...
    继续阅读 »
       微信的后台数据存储随着微信产品特性的演进,经历了数次的架构改造,才形成如今成熟的大规模分布式存储系统,有条不紊的管理着由数千台异构机型组成的机器集群,得以支撑每天千万亿级的访问、键值以及 PB 级的数据。

       作为以手机为平台的移动社交应用,微信内大部分业务生成的数据是有共性可言的:数据键值带有时间戳信息,并且单用户数据随着时间在不断的生成。我们将这类数据称为基于时间序的数据。比如朋友圈中的发表,或者移动支付的账单流水等业务生成的数据都满足这样的特征。基于时间序的数据都天然带有冷热分明属性――这是由手机的物理特性决定的,它的尺寸有限的屏幕所展示的数据只能分屏,通过手指的滑动,平滑而又连续的沿时间轴依次访问――通常是由最新生成的数据,慢慢回溯到较早前的数据。同时朋友圈等业务都是信息读扩散的应用场景,这就意味着它们生成的后台数据具有读多写少的鲜明特征。
    1. 在微信的实际应用场景中,这类数据的主要特点包括:数据量大、访问量大、重要程度高等。这些特点在现网的实际运营过程中,给我们带来了非常大的挑战,主要包括:
    2. 数据量大,需求的存储容量高――基于时间序的数据通常不会删除,而是随着时间不断积累,数据量达到 PB 级别,相应需要的存储空间也与日俱增;
    3. 访问量大,节日效应明显――基于时间序的数据往往是热点业务生成的数据,它们的访问量居高不下,基本维持在每分钟数十亿次的级别。尤其是在节日期间,瞬发访问量更可达平日的三至五倍;
    4. 重要性高,用户感知明显,数据一旦丢失,导致用户不能正常使用产品,并因此而转化成的投诉率高。


       通过堆机器来横向扩展存储自然可以应对如上的各种挑战,然而在成本预算紧张的前提下,机器数目是有限的。在这种情况下,基于时间序的海量数据的冷热分级架构便应运而生。该架构正是为了应对后台日益膨胀的这类数据,本着充分利用机器资源,发挥各种硬件介质特长的原则,结合数据的冷热分明、读多写少的访问特征而开发和设计出来的。它基于数据分层的理念,根据不同时间段的数据在访问热度和数据量上的差异,定制不同的服务策略,在纵向上扩展存储的边界。横向扩展存储是易于理解的,通过向原集群中增加相同类型的机器――其中必然涉及到一轮历史数据的迁移――最终新旧机器负载均衡,彼此之间并无差异的对外提供服务。在这种方案下,数据横向流动,系统一视同仁的对待,显然并无因地制宜思想的容身之所。而纵向扩展存储的架构便提供了这样一种思路:

       对热点数据,数据量少,但承担的访问流量大,我们当然是希望它们能常驻内存,因此系统提供了有强一致保证的内存层,在应对突发流量时,也可在不涉及历史数据迁移的前提下,单独、动态的快速扩展内存层。

       对历史数据,数据存量大,但承担的访问量非常有限,我们当然是不希望用昂贵的固态硬盘来存储它们,因此,系统提供了廉价的机械盘层,并且有一套透明的冷数据剥离和批量下沉的流程,将存储层中历史数据源源不断的抽离到机械盘层。

       通过这样的一种纵向分层、单独扩展的思路,即为我们系统提供了极大的灵活性,解决了节日期间存储层面临的内存瓶颈,以从长远的角度为我们缓解了成本压力,解决了存储层面临的磁盘容量瓶颈。

       当然一套成功的大型分布式系统仅有这些是不够的,还必须包括数据多副本复制策略以及分区算法等,也要有能应对复杂的现网运营环境的能力。我们结合各层的服务特点,制订了相对应的数据强一致算法,如内存层通过版本号控制来保证与存储层的完全一致,存储层通过 Paxos Group 实现多副本容灾,而机械盘层则通过串行写来保证。我们同时也实现了自己的去中心化的数据路由算法,确保了数据和流量的均匀分布,并且保证这种特性在横向扩展后依然成立。

       通过如上工作的努力,环环相扣,我们的基于时间序的海量数据的冷热分层架构成功的应对了 PB 级数据、千亿级访问以及万亿级键值带来的挑战。

    系统设计
    数据模型
    本文提及的海量数据的冷热分级架构是专门服务于基于时间序的数据,它们主要特征为:

    a). 数据键值带有时间戳信息 ;

    b). 单用户数据随着时间在不断的生成。

       我们设计的架构强依赖于特性 a),各个环节基本上是依赖于键值中的时间戳来分发数据或者进行数据排序的。至于键值中的时间戳如何生成、全局是否维持统一时间、如何维持等则不在本文的讨论范围,通常这由前端的业务特性以及后台的时间服务器策略决定的。

       而特性 b) 则保证了本架构的必要性、实用性。如果数据规模有限,以用户的账户信息举例,它就像我们日常生活中的户口本,它只有一份,对单用户而言不会新增。则我们通常用固定的机器集群存储就可以,并且鲜有变更。而我们要处理的是用户的日记本、或者记账簿,它们每天都在不断生成新数据。

    我们以现网某个集群的实例情况举例,说明下此类业务数据有如下的特点:

    1.、数据量大,PB 级数据,万亿级键值,并且在源源不断的生成中,然而新生成的数据相较于历史存量数据占比小。下图展示了该集群数据在各时间段的一个占比情况。

    001.jpg


    2、访问量大,峰值可达每分钟数十亿次访问,尤其是在节日期间,用户高涨的热情更可以转化成平日三至五倍的访问量。同时具有冷热分明、读多写少 (读写比例甚至可达 100:1) 的访问特征,比如节日期间倍增的访问通常是对节日期间生成的新增数据的访问。下图展示了该集群访问在各时间段的一个占比情况。

    002.jpg


    3、数据安全性要求高,这类数据通常是用户感知敏感数据,一旦丢失,转化成的用户投诉率高。

    003.jpg


    存储层


    004.jpg


    数据强一致性保证
     
    业务要求系统必须保证在数据的多份副本之间保持强一致性。――这是一个历久弥新的挑战。我们将分内存层、存储层、机械硬盘层分别来考虑数据的强一致性维持。
     
    强一致缓存
     
    正如前文描述,内存层作为一种强一致性分布式缓存,它完全是向存储层对齐的,自身无法判别数据有效性,本身多副本之间也没有交互的必要。它对前端而言是只读的,所有的写请求并不通过它,它只能算是存储层中数据的一个视图。所以它对前端数据有效性的承诺完全是依赖于存储层的正确性的。
     
    Paxos Group
     
    我们基于 Paxos Group 实现了存储层的数据一致性,通过采用无租约的方式,使得系统在保证强一致性的前提下达到了最大的可用性。Paxos 算法是由 Lesile Lamport 在论文中首提的,它唯一的作用是在多个参与者之间唯一的确定一个常量值。――这点同分布式存储没有直接关联的。我们在 Paxos 算法的基础上,设计出基于消息驱动的 Paxos Log 组件――每一条操作日志都要 Paxos 算法来确定,再进一步实现了基于 Paxos Log 的强一致性读写。

    Paxos Group 因为采用了无主模型,组内所有机器在任一时刻都处于相同的地位。Paxos 算法本质是个多副本同步写算法,当且仅当系统中的多数派都接受相同值后,才会返回写成功。因此任意单一节点的失效,都不会出现系统的不可用。

    强一致性写协议的主要问题来源于 Paxos 算法本身,因为要确保数据被系统内的多数派接受,需要进行多阶段的交互。我们采用如下的方法,解决了 paxos 算法写过程中出现的问题:基于 fast accept 协议优化了写算法,降低了写盘量以及协议消息发送、接收次数,最终实现了写耗时和失败的降低;基于随机避让、限制单次 Paxos 写触发 Prepare 的次数等方法,解决了 Paxos 中的活锁问题。

    强一致性读协议本身和 Paxos 算法并没有太大的关系,只要确认多副本之间的多数派,即可获取到最新的数据。我们通过广播的方式获取到集群中多数机器(包含自身)的 paxos log 的状态,然后判断本机数据的有效性。

    当系统中的单机节点失效,数据完全丢失的时候――这种情况是可以算是 Paxos 算法的盲区,因为该算法基于所有的参与者都不会违背自己曾经的承诺,即拜占庭失败而导致的数据不一致。――而这种情况在现网运营中可谓是常态,因此,我们引入了 Learner Only 模式。在该模式下故障机只接收已提交的数据,而不参与 Paxos 协议的写过程,意即不会因数据丢失而违背任何承诺。然后通过异步 catch up 和全量数据校验快速从其它副本中恢复数据。

    为了防止多节点同时失效,我们将数据的多副本分布在不同园区的机器上。园区是同一个城市不同数据中心的概念。如此,我们的结构足以应对单数据中心完全隔离级别的灾难。
     
    串行写入
     
    因为对客户端透明,冷数据下沉流程作为机械硬盘层的唯一写者,则该层的数据一致性是易于实现的。我们通过三副本串行写入、全部提交才算成功的方式来实现了多副本之间的数据一致性。

    作为补充,冷数据集群为数据块增加了 CRC 校验和一致性恢复队列,当单机数据不可用 (丢失或者损坏) 时,首先客户端会跳转到其它备份中读 (三机同时对外提供读服务),一致性恢复队列会异步的从其它备份数据块中恢复本机数据。

    因为采用了 No Raid 方式组织的盘组,并且同组机器间盘级别数据文件一致,在单盘故障引发数据丢失时,只要从其它机器相同序盘中传输数据文件即可。

    数据分区
     
    静态映射表
     
    数据分区的主要目的是为了确保同层机器间的负载均衡,并且当机器规模发生变化后,在最终仍然可以达到负载均衡的一种状态。

    经典的一致性哈希算法的初衷是为了健壮分布式缓存,基于运行时动态的计算哈希值和虚拟节点来进行寻址。数据存储与分布式缓存的不同在于,存储必须保证数据映射的单调性,而缓存则无此要求,所以经典的一致性哈希通常会使用机器 IP 等作为参数来进行哈希,这样造成的结果一方面是数据的落点时而发生改变,一方面是负载通常不均衡。因此我们改造了此算法。

    我们通过预计算虚拟节点随机数的方法,生成了割环点同实体机器之间的映射表。该映射表最多可支持一千组的集群规模,满足在任意组数情况下,实体机器间割段长度维持差异在 2% 以内;并且增加任意组数 (总组数上限不超过一千组),变动后的实体机器间的割段长度依然维持差异在 2% 以内。我们将此映射表硬编码,在运行时避免了计算的过程,数据根据键值哈希值寻址时,只要经过一次二分查找即可获取到对应的实体机器的编号。我们在内存层、存储层以及机械硬盘层都采用了这个映射表,保证了数据在各层路由算法的一致。在工程实现方面,我们可以合理使用这个特性来批量合并请求,以降低资源消耗,这在稍后的章节会有详细描述。
     
    组内均衡
     
    组是数据分区的独立单元,是虚拟节点对应的实体单位。组之间是互相独立的。每组由多台物理机器组成,这是 Paxos Group 生效的基本单位。一份数据包括的多份副本分别散落在组内的各台机器上。为了在组内机器上保证负载均衡,我们同样设计了一套算法,规定了数据副本之间的访问优先级,前端会依优先级逐一的请求数据,只要成功获取,即中断这个过程。然后我们再将副本按优先级均匀的散落在组内机器上,如此即可实现组内负载的均衡。
     
    数据迁移
     
    静态映射表是非常灵活的,在不达到组数上限的情况下,可以任意的增加一组或者多组机器。当然这个过程中一些数据的路由映射发生了改变,则就涉及到了历史数据的挪腾。为了在挪腾的过程中不影响服务,保证数据依然可读可写,我们开发出了对前端透明的,基于迁移标志位,通过数据双写和异步挪数据的方式实现的安全的、可回退的数据迁移流程。
     
    最小不变块
     
    存储层和机械硬盘层通过冷数据链接耦合在了一起。因为两层使用了相同的映射表,那么当存储层因扩容而发生迁移时,那么冷数据链接无疑也要重新寻址,进行一轮重新定位。如果我们以单键值为粒度记录冷数据链接和进行冷数据下沉,那么在万亿键值的语境下,效率无疑是低下。因此我们设计了最小不变块的算法,通过两阶段哈希,使用中间的哈希桶聚集数据,将数据键值和冷数据存储层的机器路由隔离开来。通过该算法,我们可以实现:批量的转存冷数据、热数据存储层批量的以块 (block) 为单位记录冷数据链接、当热数据存储层发生扩容时,块 (block) 内的数据不因扩容被打散掉,而可以整体的迁移到新目标机上。
     
    工程实现
     
    糟糕的工程实现可以毁掉一个完美的系统设计,因此,如何在工程实现的过程中,通过技术的手段,提升系统的表现,同样值得重视。
     
    高效缓存
     
    内存层的设计严重依赖存储层数据版本号的高效获取,那自然是版本号请求全落在内存中就可以了。因此,针对这种情况我们为定长的版本号设计了一套极简的、轻量的、行之有效的缓存――内存容量不足以支撑版本号全缓存。

    005.jpg


    它的数据结构只是一个二维数组,一维用来构建 hash 链,一维用来实现 LRU 链。每次读或者写都需要通过数组内数据的挪动,来进行更新。如此一来,我们就通过千万级数目的 LRU 链群,实现了缓存整体的 LRU 淘汰。它具有定长,可共享内存搭载,进程重启不丢失、内存使用率高等优点。
     
    批量操作
     
    对系统服务器而言,前端访问过来的某个请求,其对应的逻辑操作都是串行的,我们自然可以梳理这个串行流程中的 CPU 消耗点进行优化。然而当主要的瓶颈被逐渐的消灭掉后,CPU 消耗点变得分散,优化效果就变得微乎其微了。因此,我们只能寻找其它突破点。

    我们发现在存储引擎、一致性协议算法的实现流程中,逻辑操作步骤多,涉及到网络交互,硬盘读写等过程。因此,我们决定合并不同请求中的相同步骤,实现批量化操作,极大的优化了 CPU 消耗。

    合并的代价即是耗时略有增加,我们通过快慢分离,只针对热点数据请求中的逻辑操作进行合并,去掉了耗时中的不稳定因子,减少了耗时抖动。
     
    请求合并
     
    既然单机的逻辑操作性能已经得到了极大的提升,那么前后端的网络交互阶段,包括接入层的打包解包、协议处理等环节,成为了资源的主要消耗点。参考批量操作的经验,我们同样使用批量化的技术来优化性能――即将后台访问过来的单条请求 (Get) 在内存层聚合成一次批量请求 (Batch Get)。
     
    路由收敛
     
    因为每个数据都是根据键值单独进行路由的,如果要进行请求合并,我们就必须确保同一个批量请求内的数据,都会寻址到相同的 Paxos Group 上。因此,我们必须在内存层将落到同一台存储机器上的 Get 请求聚合起来。我们首先在内存层和存储层采用了相同的路由算法,然后将内存层的组数同存储层的组数进行对齐,来完成了这一目标。


    006.jpg



    相关工作
     
    在设计的阶段,我们充分的调研了业界的各类方案,大到系统的整体架构,小到具体的技术点。各种方案自有应用场景、各有千秋,不能单纯以好坏区别,我们同样基于自己的业务场景,谨慎的选择合适的方案,或者弃而不用。在此尽量叙述。

    处理 SNS 类业务生成的数据,业界有多种的冷热分离架构可以参考。我们以 Facebook 的 Cold Storage 系统举例而言,它也是基于冷热分层的想法,设计出了服务它们照片业务数据的存储方案。不同的是它采用了软硬件结合的方法,一方面定制专门的服务器(包括硬盘、电源等)和数据中心,一方面降低冷数据的备份数、增加纠删码等手段。

    然而它们的经验我们是无法彻底套用的,主要两种原因:我们可使用的机器机型是固定的,不存在自己定制硬件的条件。同时它处理的是照片这种大 value 的数据。而我们基本上是文本这种类型的小 value 数据。从前文提及的 TB 访问量角度来看,它们处理的数据是容量瓶颈的,而我们处理的是 IO 瓶颈的,可以算是不太冷的冷数据带来的挑战。所以,我们只能实现自己的冷数据管理策略。

    同样,业界有诸多关于如何实现数据一致性的方案。包括我们微信自研的 Quorum 协议,它是一种 NWR 协议,采用异步同步的方式实现数据多副本。即然是异步同步,那在多副本达到最终一致,必然存在一个时间差,那么在单机出现离线的情况下,就会有一定概率导致数据的不可用。而我们追求的是在单点故障下,所有的数据都保证强可用性。

    因此,我们采用了无主的去中心化的 Paxos Group 实现了这一目标,其中非租约是 PaxosStore 架构的一个创新亮点。在故障时通常系统是抖动的,会有时断时续的状况,常见的租约做法在这种场景下容易出现反复切换主机而导致长期不可用,而 PaxosStore 的非租约结构能够轻松应对,始终提供良好的服务。PaxosStore 核心代码正在整理开源当中,预计四季度会正式发布,同时该项目的底层框架也基于我们已开源的协程库 github.com/libco。
     
    转自“计算机与网络安全”,作者杨平安 收起阅读 »

    环信移动客服v5.21已发布,支持客服发送语音消息、语音转文字及支付功能

    客服模式 支持客服发送语音消息 Web版客服工作台支持发送语音消息。与app渠道的客户聊天时,客服可以向客户发送语音消息。 点击输入框上方的麦克风按钮,开始录音并发送。每条语音消息最多为60秒,达到60秒后自动发送。 注:发送语音消息功...
    继续阅读 »
    客服模式

    支持客服发送语音消息

    Web版客服工作台支持发送语音消息。与app渠道的客户聊天时,客服可以向客户发送语音消息。

    点击输入框上方的麦克风按钮,开始录音并发送。每条语音消息最多为60秒,达到60秒后自动发送。

    注:发送语音消息功能仅Chrome浏览器在https模式下支持。 

    001.png


    管理员模式

    语音转文字beta版

    Web版客服工作台支持将app、微信、微博渠道的客户的语音消息自动转为文字,并显示在语音消息下方。方便客服快速识别客户的消息内容,并作出回应。

    客服模式的会话、待接入、历史会话、客户中心页面,管理员模式的搜索、历史会话、客户中心、当前会话、质量检查页面,均支持显示语音消息对应的文字。 

    002.png


    语音转文字功能正在beta测试阶段,如果您希望先行体验,请提供租户ID,并联系环信商务经理。

    开通语音转文字功能后,需要进入“管理员模式 > 设置 > 系统开关”页面,打开“启用语音转文字服务”开关。 

    003.png


    在线支付

    在线支付功能全新上线。支持在web版移动客服工作台购买标准版坐席、对租户进行续费、增购坐席,并查看订单信息。

    进入“管理员模式 > 设置 > 企业信息”页面,点击“购买”按钮。 

    004.png


    选择“缴费类型”、购买期限,填写坐席数量,确定并支付订单。

    目前,只提供标准版坐席的在线支付功能。缴费类型包括:

    • 新购:第一次购买坐席时,请选择“新购”;

    • 续费:需要延长租户的到期日,请选择“续费”;

    • 增购:在已有坐席的基础上,增加坐席数量,请选择“增购”。



    注:增购坐席时,坐席的到期日与租户的到期日一致,我们按比例收取坐席费用。 

    005.png


    【优化】客服超时未回复提醒客服

    原“客服超时未回复访客端提示”开关更名为“客服超时未回复提示”,并支持设置“提醒客服”和“提醒访客”。

    进入“管理员模式 > 设置 >系统开关”页面,对“客服超时未回复提示”的开关进行设置。

    “提醒客服”开关打开,客服超时未回复时,会话主动排在进行中会话列表的顶部并标注颜色。
    “提醒访客”开关打开,客服超时未回复时,系统自动发送一条提示语给客户。


    006.png


    进行中会话列表提醒示例: 

    007.png


    【优化】工作量、工作质量支持导出客服的真实姓名

    对客服的工作量、工作质量详情进行导出时,导出文件包含客服的真实姓名,便于识别对应客服,使数据更直观。
     
    环信移动客服更新日志http://docs.easemob.com/cs/releasenote/5.21

    环信移动客服登陆地址http://kefu.easemob.com/  收起阅读 »

    【环信公开课第14期视频回放】情感计算:如何用人工智能解读人类“情感”

    朱泙漫学屠龙于支离益 , 殚千金之家,三年技成而无所用其巧。 ——《庄子·列御寇》       6月25日,EmoKit创始人兼CEO魏清晨在环信公开课上以“情感计算”为主题做...
    继续阅读 »
            朱泙漫学屠龙于支离益 , 殚千金之家,三年技成而无所用其巧。

    ——《庄子·列御寇》

          6月25日,EmoKit创始人兼CEO魏清晨在环信公开课上以“情感计算”为主题做了人工智能解读人类“情感”的分享。魏清晨称,机器人未必像人的形态一样,有胳膊、有腿、有眼睛、有嘴,但如果要让机器实现真正智能,并且跟我们产生自然而然的交互,需要具备情绪识别和表达的能力。
     
      魏清晨讲到, EmoKit主要专注于机器人情感的研发,让机器人从一个多模态的形式了解人的情感,从渠道数据来源的角度去做综合判断,可以预见的未来,曾经独属于人类的情感将“赋能”人工智能!
     
    公开课课程大纲 
    • 情感计算概述与发展
    [list=1]
  • 情绪是人类社会奖惩机制最底层的编码
  • 情感计算包含的模块和价值
  • 情感计算,是人工智能的下一个未来
  • 情感计算的技术实现
    • 情感信号的获取与量化
    [list=1]
  • 分析、建模与识别
  • 情感理解和反馈
  • 情感合成与表达
  • 人机交互的实现
    • AI+情感计算的应用
    [list=1]
  • 情感计算在环信IM的最佳实践
  • 环信客服通过情感计算实现智能质检
  • 更多落地场景
  • 商业变现
    • AI火爆背景下的冷思考

     
    视频回放

     






     
    已有8625名开发者加入环信公开课,妹子比例10%!还有最强王者等你开黑!赶紧加入我们一起玩耍吧!

    扫码.gif


     
      收起阅读 »

    《IT经理世界》特写:环信的Alpha刘,布局未来的商业智能!

    6月20号刊 新疆界 刘俊彦说不想做一家小老头公司——规模不大,每年挣个几千万元,日子过得滋润,但每年只有10%左右的增长。 技术男刘俊彦的思维很跳跃,2014年做即时通讯云,一年后开始做客服云,不到一年,又开辟了智能机器人业务。看起...
    继续阅读 »


    微信图片_20170627113413.gif

    6月20号刊

    新疆界


    微信图片_20170627111638.jpg


    刘俊彦说不想做一家小老头公司——规模不大,每年挣个几千万元,日子过得滋润,但每年只有10%左右的增长。

    技术男刘俊彦的思维很跳跃,2014年做即时通讯云,一年后开始做客服云,不到一年,又开辟了智能机器人业务。看起来好像在分片作战,但突然有一天他已经在一个更大的战略布局里了。

    这些年,云的概念被炒到火热,企业不惜花血本布局云计算,可一轮下来之后,不同的业务还是要各养一套人马,各养一套软件系统,说好的大数据,量是上去了,但是实际利用率却如挤牙膏,效用微乎其微。很多企业现在正处在一个升级也不是,不升级也不是的难受期。

    见到刘俊彦的时候,他刚送走一家航空公司的几位管理人员,他们现在的烦恼是,守着一大批高净值的用户,只能卖个机票,最多再卖个保险,利润已经碰到天花板,有种守着宝藏却挖不出金子的感觉。刘俊彦在他的小会议室的黑板上,画了一个完整的从用户服务到用户营销的闭环图,这张图里包含了航空公司乃至一些大企业当下的几大痛点及应对招数,如同在下一盘围棋,细节处棋势做得够厚,大局又跳出常人思维之外,细看与AlphaGo的风格颇为相似。

    这是刘俊彦第一次将自己成熟的大局想法展示给外界。
     
    高效融资与快速换挡
     
    刘俊彦毕业于英国伦敦大学国王学院计算机专业,后一直在IT外企从事技术研发工作,2013年,离职创业前已经成为红帽开源软件领域领先的专家。这一年,他已经年过40。

    最初的一年多时间,是在海淀图书城的车库咖啡里度过的,当时刘俊彦和另外三位合伙人都刚从外企里出来,各自都已经是行业里优秀的技术人才,都实现了财务自由,清楚自己要的是什么,且志趣相投,所以走到了一起。

    刚开始,大家专注于做产品,也没有急着去找投资。一年后,一个偶然的机会,投资自己找上了门。

    2014年5月,刘俊彦他们进驻到氪空间的当天下午,经纬的投资人找到了他们,大概聊了两个多小时,双方就达成了合作意向。紧接着不到半年,SIG和红杉资本相继成为投资方。几家投资方看中的是刘俊彦等人创立的环信公司在即时通讯领域的开发能力和社交大数据分析能力,以及环信自主研发的高并发可扩展架构。

    此前,刘俊彦拥有17年的开发经验,其擅长的领域在于实时消息系统和高并发消息中间件等。2013年,社交软件开始大行其道,当时很多人找他为APP开发即时通讯聊天功能,一般如果企业自己开发的话,怎么都需要好几个月时间,而使用刘俊彦的团队的产品只需一天功夫就出来了。因此,最初的产品并非他们刻意做出来的,而是需求在先,而且令他们也没想到的是,做着做着就成“风口”了。

    很快,使用了环信即时通讯功能的APP上的用户从几万飞速上升到几千万,乃至后来的几个亿,每天下发的消息达20亿条。曾经在短信高峰时代,中国移动每天的消息量是7亿,目前国内能支撑并发连接几千万的团队不超过5个,包括腾讯、阿里、新浪微博、陌陌等,另外还有一个就是环信。

    用户上去之后,新的需求又来了。开始,很多人只是把APP内的聊天功能用作连接人与人的社交管道,但很快就不断有人找上门来,希望把APP内的聊天功能做成淘宝旺旺那样连接人和商业的客服工具。

    从本质上来讲,环信早期推出的即时通讯云是基于PaaS平台的服务,而要做客服云则需建立在SaaS平台上,如此跨平台的转变,对于一家创业公司,无论是人才、资本、研发或渠道等各方面都会带来严峻的挑战。

    2015年4月,A轮的三家投资方在前几个轮次共900万美元的基础上,再次追加了共1250万美元的B轮投资,在资本方的财力和战略加持下,一个月后,环信客服产品线上市,一年后环信客服产品的客户量、销售额等硬指标均达到几十倍上百倍的增长。

    据刘俊彦介绍,早期客服云的客户几乎一半多来自即时通讯云,相当于后者是前者的流量导入渠道,后者反过来巩固了前者的价值所在。

    目前,环信客服产品的企业用户已经超过5万多家,用户也从国美在线、58到家、新东方等扩展到了十几个行业当中。

    然而,IT业一年相当于传统行业十年,这是一个变换以秒速推进的行业,刘俊彦很快又迎上了新的挑战。

    痛点与前瞻

    随着产品的积累和行业的扩展,刘俊彦开始接触到一些保险、证券、航空等行业大客户。曾经有一家保险公司的客户跟他提到亲身经历的一件事情,以往保险公司客户经理做客户维护的通常做法就是每年会定期提前一两个月给老客户打电话,提醒他们保险快到期,可以续费了。其中有一个老客户,关系维护得挺好,但是这个老客户最近新买了辆哈雷摩托车,而他的客户经理没能及时了解并提供摩托车的保险报价,结果错失了老用户。

    这种个案在保险公司普遍存在。如果有更懂用户的数据,进行再分析和精准营销,就能很快帮老用户接上新的业务,还可以把以前让利给渠道的部分,直接反馈给用户,大幅提高销售成功率。

    刘俊彦说,做即时通讯,做客服,真正的差距在于,怎么通过商业智能帮助企业去挖掘以前看不到的客户信息,提高销售转换率,发掘新销售机会,以及人工智能技术怎么代替人工,怎么帮企业营销,这都是未来技术。

    2016年年初,环信基于企业一体化智能商业的需求,开始推全媒体智能客户服务。所谓全媒体就是不管客服请求来自微信、微博或APP,还是网页或电话,都可以同时呈现在一个界面上,由专人统一处理。

    以前企业不同的渠道由不同的人马在支持,各自软件系统也不一样,信息也是各自孤立的,片段化的,环信做到了让一个支持人员同时监控所有渠道,客户身份也可以从孤立的信息中关联起来,形成一个统一身份。也就是说,同一个用户打完电话,再用微信接入,通过各种技术方法可以跨屏身份合并被识别为是同一个人。

    此外,一家企业如果每天进来10万条消息,环信的技术可以识别出来自不同渠道不同数据格式的信息,然后对其进行数据清理,再做主题分析和情感分析,从而知道用户今天都反馈了什么问题,情感是愤怒还是高兴,可能的消费趋势是什么?进一步还可以給出用户画像,画像信息详尽,一直可追溯到用户城市、职业、性别、喜好、消费能力、行为轨迹,等等。

    这些数据对于企业至关重要。不仅是保险公司,证券公司、航空公司等等行业都存在类似的强烈需求。

    环信还在自己研发客服机器人。刘俊彦认为,环信既有SaaS客服软件高市场占有率的通道优势,又有了大量的数据积累,加上对垂直行业的深度理解,在开发具有高度行业特征的客服机器人上,又领先了其他对手。

    2017年 ,环信整合旗下即时通信云、移动客服、智能客服机器人和主动营销产品线,推出环信CEC (Customer Engagement Cloud),向企业提供从客户互动渠道,到客户服务,再到精准客户营销的全流程客户互动解决方案。

    技术出身的刘俊彦,既可以不断挖掘出用户的痛点,在技术细节上下足功夫,又可以跳出来,把握住前瞻性技术,果断出击。当一个个看似不大相关的痛点技术在量的积累上突破一个爆发性临界点时,全新的需求与应用又把之前所有的技术关联在了一起。

    这一切使得刘俊彦像一个“做局”的高手。

    转变与坚持

    创业仅仅4年,刘俊彦已经看惯了互联网领域的迎来送往,2014年,他还经常在微信里看见做社交应用的CEO们发朋友圈,到2015年左右,这些人大多看不到了,换了一批做O2O的CEO,一年以后,这些人又看不见踪影了。大浪淘沙,互联网的残酷淘汰是铁律。

    当年那些做即时通讯服务的环信的老对手们,现在大多还在做老业务,日子过得还不错。刘俊彦却早已不在当初的格局里了。

    做即时通讯云有一个特点,从几十万用户到几百万用户是一个技术节点,从几百万到几千万又是一个节点,用户过亿之后则是一个更大的节点。每一个节点处,基本上架构要推倒重写一遍。这要求技术团队快速的迭代和积累,一旦有一个环节出问题,就有可能导致服务不可用。

    这期间,环信团队也经历了重大考验,也被客户骂过,好在最后都坚持过来了。现在环信即时通讯技术架构早已稳定下来,即使再扩容4~5倍也不成问题。

    然而,就在这么一个节点上,刘俊彦毅然决定再另外做一个SaaS平台,这对于整个团队是一种怎样的震撼。虽然对于技术能力强悍的环信团队来讲,技术难题最终都是可以克服的,而对市场的敏锐嗅觉以及果断决策,却非易事。事实上刘俊彦的判断是精准的。

    环信最初的客户群主要集中在互联网领域,这些客户的生命周期比较短,付费能力比较低,好处是决策周期短,商业谈判简单,能迅速达成交易,迅速验证需求,这适合早期创业。

    有了这段经历也让刘俊彦开始明白,为什么美国的SaaS软件同行们天天讲生命周期价值,讲内容营销,因为他们也跟环信一样做的是小客户,可见对于小客户这一招中外通吃。而大客户不是这么玩的。

    在美国做企业服务,底层有一批创业公司,天花板是做到几亿美元到几十亿美元市值,基本很难再往上突破了。这是因为大客户都被微软、甲骨文、Salesforce这样的公司牢牢掌握着,小企业根本没机会进入那个圈子。

    某种程度上,中国也差不多,但也有很大不同。中国大型企业还没有强大的科技公司可以很好地服务于他们,这些年主要依赖于一些大型系统集成商,系统集成商的做法跟甲骨文等这些科技巨头又不一样,他们以项目运行的方式推进,在创新和积累上相对较弱。

    以前中国的大型国企或私企也认可这种做法,但随着整体经济环境进入L型经济,增长放缓,企业追求利润的结果就是更加注重创新,尤其是服务创新,这两年刘俊彦明显地感觉到国内大型企业有一种创新急迫感,他意识到谁能服务中国500强企业,谁就会成为中国的甲骨文。

    由于求稳,当年环信的竞争对手就没赶上这波新的机会。“如果我们到现在还只是在做最初的一个业务,我们也就成为了一家小老头公司。”刘俊彦平静地说。

    2017年3月,环信完成1.03亿元的C轮融资,由经纬领投,银泰嘉禾跟投。

    当然,考验仍然存在。SaaS是一种功能密集型的技术,最考验大规模研发团队的研发效率和管理能力。2016年新组建的智能机器人团队则是资本密集型,这个团队虽然人不多,但是一年投入却上千万元。

    不同的技术、人才、资本结构,对于管理是一大考验。不过刘俊彦认为,既然创业就要全力以赴去做,“挖人要看眼光,选择很重要,路线很重要,信任也很重要,既然选择上了火箭飞船,就不要考虑是几等舱。”
     
    作者 | 刘晓芳

    微信编辑 | 李昊原

    原文发表于《IT经理世界》,转载请注明
    收起阅读 »

    【开源OA项目】基于环信IM开发完整的企业通讯解决方案-Dolores

         前阵子钉钉在微信楼下刷了一波#创业很苦,坚持很酷#的广告,浓浓的“丧”文化风格文案受到了各界褒贬不一的评价,也引起了大家对OA办公系统的关注。    对企业而言,初选OA办公系统是为了满足需求,解决当下问题,由于OA办公系统的在公司运作流程中扮演的...
    继续阅读 »
      

      前阵子钉钉在微信楼下刷了一波#创业很苦,坚持很酷#的广告,浓浓的“丧”文化风格文案受到了各界褒贬不一的评价,也引起了大家对OA办公系统的关注。
       对企业而言,初选OA办公系统是为了满足需求,解决当下问题,由于OA办公系统的在公司运作流程中扮演的重要性,安全与隐私等问题急需未雨绸缪,“可定制”、“可私有化部署”的OA办公系统成为了更多企业的首选。
    公司想自己开发一套IM系统应该从哪里开始呢? 企业通讯录怎么保持同步呢? 企业通讯录的权限管理应该怎么做?

       三个关于OA办公系统的究极问题,从开源的OA办公项目-Dolores(朵拉)诞生迎刃而解了。Dolores项目遵循Apache Licence 2.0 开源协议,可以直接拿来用,也可以修改代码来满足需要并作为开源或商业产品发布/销售。

    OA广告图.jpg


    关于Dolores?


    Dolores是一套完整的企业通信解决方案,一个完整的企业沟通工具(以下简称企业IM),支持以下几个功能:IM消息服务、组织架构管理、工作流集成。


    Dolores项目源码地址:https://github.com/DoloresTeam​ 
    技术讨论群:641256202(QQ群)

    整个解决方案都包括了什么?
    • 企业通讯录的管理:部门/员工的增删改查
    • 通讯录全量更新:全量/增量更新 
    • 企业通讯录权限管理:基于RBAC权限管理模型
    • 企业即时通讯IM:企业通信对IM这块的可靠性要求高,选择了目前比较成熟的IM云服务厂商-环信
      组织架构企业通讯录可以说是企业沟通中最重的业务之一,能够提供员工各种服务的认证,获取员工的联系方式等。 组织架构-Server服务端主要包括以下功能:[list=1]
  • 支持管理人员(例如HR)对部门和员工进行增删改查
  • 支持部门和员工自定义排序,自定义元信息存储
  • 权限管理
  • 员工通讯录视图 (员工根据自己的权限生成通讯录)
  • 通讯录增量更新 (鉴于移动端特殊的网络环境和设备,通讯录应该支持差量更新)
  • 集成 IM 用户系统
  • 在这里我们主要讨论以下两个问题: 权限管理  随着企业逐渐的发展,团队壮大为了更有效的沟通,以及保护公司内部的一些商业信息不被泄漏,我们应该为通讯录添加权限管理。基于Role-based access control(RBAC)的权限管理模型为了介绍此权限管理模型,我们先解释一下基本概念
    • 角色:通常是指企业中某一个工作岗位,这个岗位具有特定的权利和职责。被赋予此角色的员工,将获得这种权利与职责
    • 权限:被赋予访问实体的权利。在本项目中是指访问部门和访问某一个或者某一类员工的权利
    • 用户-角色分配(User-Role Assignment URA):为某个用户指定一个或者多个角色,此员工将获得这些角色所具有权利的集合
    • 角色-权限分配(Role-Permission Assignment RPA):将权限分配给角色,一个角色可以包含多个权利。在本项目中是指多个访问部门和访问员工的权限
    在用户和权限之间引入角色中介,将用户与权限的直接关系弱化为间接关系。
    |ˉˉˉ|           |ˉˉ ˉ|          |ˉˉˉˉ ˉˉ|  | User |---URA---> |  Role |<---RPA---| Permission  ||______|           |_______|          |_____________|
        以角色为中介,首先创建访问每个部门和员工的访问权限,然后创建不同的角色,根据这些角色的职责不同分配不同的权限,建立角色-权限的关系以后,不同的角色将会有不同的权限。根据员工不同的岗位,将对应的角色分配给他们,建立用户-角色关系,这就是RBAC的主要思想。一个员工可以用户多个角色,一个角色可以用于多个访问权限。RBAC 极大的简化了员工的授权管理。   由于企业的部门和员工数量很多,在创建权限时管理员不可能去设置每一个权限可以访问的每一个部门和每一个员工。所以本项目将功能和指责类似的部门和员工看作是同一类型,在创建部门和员工的时候为每一个部门和员工分配固有属性type,管理员在设置权限规则的时候只需要指定可访问的部门类型和员工即可。增量更新   鉴于移动终端计算资源有限,如网络,存储,电量等,所以通讯录的更新技术应该保证尽量少的资源。另外由于通讯录的特殊性,通讯录的变化需要能实时通知到受影响的在线员工。基于版本号与变更日志的增量更新模型   客户端第一次登陆系统以后,我们根据当前登录角色生成对应的通讯录视图,并以当前时间戳作为版本号,返回给客户端。客户端后续通过此版本号增量更新通讯录。版本号   版本号有两种:一是客户端当前通讯录版本 c-version, 二是服务端通讯录每一次变化时的版本号s-version变更日志   在管理员修改权限规则,或者修改某个岗位的访问规则时会影响大面积员工的通讯录视图,此时如果用增量更新会导致服务器流量异常,因此在这2中情况会清空原来的变更日志并且要求客户端进行一次全量更新。   如果管理员新增了员工,服务端会根据被修改的员工或者部门type, 反推出所有受影响的员工,然后生成一条变更日志, 例如:
    {       "content" : [        {          "cn" : "Lucy.Liu",          "id" : "b4vlfg91scgi1dcju8v0",          "title" : "市场运营负责人",          "email" : [            "lucy.liu@dolores.store"          ],          "priority" : "101111",          "name" : "刘小飞",          "telephoneNumber" : "18888888888"        }      ],      "createTimestamp" : "20170614063303Z",      "category" : "member",      "action" : "add"    }
    客户端在请求增量更新的时候,通过当前登陆ID与版本号,可查找出所有与自己相关的变更日志,然后在客户端数据库中应用这些变更,即可完成同步。组织架构-Client   由于现在员工办公设备的多样性,客户端要根据自己公司的情况,覆盖的足够完整,常见的平台有 iOS Android windowsmac linux , 对于后三个平台可以用 Web APP 来覆盖,iOS&Android 用原生的app来提升用户体验。客户端App主要包括以下功能:[list=1]
  • 会话列表
  • 优秀的聊天界面,历史记录
  • 组织机构全量/增量更新
  • 员工个人资料展示
  • 客户端数据库设计IM数据库设计 当前版本使用环信SDK 组织架构数据库设计表设计客户端组织架构较服务端简单,不关联用户Role,客户端本地存储Staff(员工)和Department(部门)信息:
    • 一个部门可以包含相关子部门和部门员工。该部门员工和部门在视图上处于同级关系。
    • 员工隶属于部门,同一员工可以存在于多个部门。
    • 员工角色用title来表示。


    用户在登录客户端成功后,会根据该用户信息创建用户对应的数据库文件,用户表(User)保存用户相关信息,关联该用户staff信息。

    客户端组织架构同服务端逻辑。

    工作流集成

    (TODO)
     
    如何使用Dolores

    本项目现在已经完成了第一个测试版本,本小节将指导您如何安装使用。

    后端数据库

    鉴于通讯录对数据库操作的特点多度少写,以及部门之间的树状关系,我们选择LDAP协议来存取数据。

    我们有独立的repo来帮助您完成数据库的安装与初始化。请移步这里

    组织架构管理

    Dolores 初始版本使用Golang实现,大家既可以下载各个平台的可执行包,也可以安装Go语言的开发环境自己编译。

    我们有独立的repo来帮助您,运行后端服务。请移步这里

    客户端

    我们现在有提供一个iOS版的Demo。请移步这里

    Done

    如果您顺利的完成以上三步,访问 http://localhost:3280 (端口号根据自己的配置,可能会有差异),使用 username: admin, password: dolores 登陆后端管理页面,添加权限规则,添加角色,添加员工、部门,然后使用iOS客户端登陆,就可以愉快的开始聊天啦~
     
    负载均衡

    (TODO)

    多机容灾

    (TODO)

    LICENSE
     Apache License
    Version 2.0, January 2004
    http://www.apache.org/licenses/

    更多信息请前往github项目主页

     
    这里我对每个repo做一个简单的介绍


    Dolores: 项目简介, 整个项目的架构, 数据库设计等等 你想了解的一切都可以在这里看到
    dolores-ios: iOS版demo,可以聊天查看组织架构
    dolores-android: 哈哈 还没有,当然我们欢迎各路安卓大牛贡献安卓版demo
    organization: 组织架构的创建管理、更新、审计等等核心的东西都在这里啦
    dolores-server: 为客户端提供restfull api 与环信服务器集成
    dolores-admin: 后台管理网站,用于管理部门员工。一个基于React的webapp还很基础,欢迎各位大牛pr.
    dolores-ldap-init: 后台数据库的初始化工具,详情可以查看readme
    easemob-resty:对环信rest api的封装,让调用环信api更简单
    dolores-avatar:生成类似钉钉那样的默认头像


    最后再说一点整个服务端是用go来写的,作者也是golang的初学者,如果代码哪里写的有问题或者架构有问题欢迎大家指正
    THE CALM BEFORE THE STORM.
    暴风雨前的宁静

    ONE MORE THING 最后附上Dolores项目LOGO
    当时作者正在二刷 《西部世界》这部剧,所以选择了女主的名字dolores作为整个项目的名字,而这个logo则寓意剧中的host。

    687474703a2f2f6f7131696e636b76692e626b742e636c6f7564646e2e636f6d2f646f6c6f726573313032342e706e67.png

    收起阅读 »

    视频超过三十秒后再接受 无数据

    iOS 根安卓的  视频聊天 超过三十秒之后在接受就没有画面了 都是黑的 小窗口是有画面的是因为 超时了吗 ? 还是什么原因该怎么解决呢  谢谢
    iOS 根安卓的  视频聊天 超过三十秒之后在接受就没有画面了 都是黑的 小窗口是有画面的是因为 超时了吗 ? 还是什么原因该怎么解决呢  谢谢

    【环信征文】Android程序员的十大转型之路

    IT行业是一个瞬息万变的行业,程序员是一个不进则退的职业。我作为一个Android程序员,多年来一直保持随时可以转型其他技术领域的状态,保持对新技术敏感的嗅觉。   我先说说Android程序员不可能转型的几个方向,以下四个不靠谱方向的靠谱性递减: 首先不会转...
    继续阅读 »
    IT行业是一个瞬息万变的行业,程序员是一个不进则退的职业。我作为一个Android程序员,多年来一直保持随时可以转型其他技术领域的状态,保持对新技术敏感的嗅觉。
     
    我先说说Android程序员不可能转型的几个方向,以下四个不靠谱方向的靠谱性递减:
    首先不会转型iOS,iOS和Android工程师的工作内容都是大同小异的。
    其次不会转型Windows Phone,好多Andr oid程序员就是受不了产品经理唠叨:“像QQ客户端那样做成和iOS一样”才转型的,怎么会转型比Android还难做成和iOS一样的WP?
    再次不会转型Windows和MacOS等桌面软件,桌面开发周期长、难度大、升级不易,这是一个已经接近穷途末路的夕阳产业。
    最后不会开JavaME或者Symbian的历史倒车,除非他有本事让每个用户都买(就一个“买”字,同时包含“想买”和“买得到”的意思)停产多年的机型。
     
    我观察如今的技术形势,并亲身探索了一个Android程序员转型的几个技术方向的可行性:
     
    Android病毒和恶意应用
    最近肆虐全世界的WannaCry让安全成了IT圈最热的话题,开发腻了善意应用的Android工程师最便捷的转型方向就是开发Android病毒和恶意应用。在4.x时代对Android对敏感权限还不是很敏感的时候,我就研究过给肉鸡伪造短信记录和让肉鸡给通讯录里所有(或特定)联系人发送短信的病毒。去年还研究过窃取友商App推送内容、强杀友商App进程、卸载友商App甚至让友商App被卸载后就再也不能在这台肉鸡上安装的恶意应用(或应用里的恶意功能)。

     
    转型建议:此外锁定肉鸡里的重要文件勒索用户(Android上的WannaCry?)和窃取肉鸡用户的支付密码的实现在技术上也像强奸8岁女童一样简单,只不过事后逍遥法外很难。这个转型方向只适合拿自己的手机当肉鸡玩玩,千万不要用这些技术赚钱

    SDK
    开发SDK本质上仍然在为Android应用开发软件,只是不直接开发Android应用。
     
    每个Android程序员工作几年后都积累了属于自己的或大或小的类库,比如封装好的LogUtils和ToastUtils等;也都或多或少研究过常用开源框架的底层原理,比如了解Picasso和EventBus等;还应该对不开源的第三方服务有自己简单的二次封装,比如我就封装了一键实现支付宝和微信支付的moudle(免费的Ping++?)。
     
    转型建议:尽管看见自己的链接出现在无数Android应用的Gradle文件的compile后面,开发了无数软件的一部分的成就感不会比开发完整的软件差。但是几乎没有老板会为了支持你开发开源软件发你工资。
     
    JavaEE
    Android程序员转型Java在基础知识方面是没什么难度的,毕竟语言相通,特性相似。同时每个Android程序员在大学时J2EE课程学得都不会很差,不过有些知识是该忘掉的,比如Hibernate已经落后于时代了,SpringMVC的全面使用才是Java后台的大势所趋。
     
    转型建议:建议不想每天改UI的刚入行不久的Android工程师转型,我有好几个学弟就是参加工作后从Android转型Java的,他们过得都不错。很多工作年限较长的Android工程师本来就是JavaEE转型来的,就别转回去了。
     
    手游
    首先考虑不放弃Java语言和Android开发习惯的情况:最合适的就是能把游戏view直接插入普通layout里的AndEngine,前几年大红大紫的Flappy Bird就是用它开发的。AndEngine的开发方式和Android别无二致,且有丰富的开源demo。不过AndEngine没有官方文档,理论学习上有一定难度。我用AndEngine开发了我的毕业设计,参加工作后也用AndEngine获得了几个奖,我珍藏着一本AndEngine的非官方文档《Android游戏开发实践指南》(全新未拆封),期待着有一天能回到2014年把它送给那个买不起它的毕业生。

     
    提到了AndEngine就不得不提国产AndEngine——OGEngine,它是基于AndEngine衍生的游戏引擎,有详细的纯中文文档和说汉语的技术支持杨城(笔名:小城),极适合开发Android TV游戏。OGEngine目前已停止更新,这个国产游戏引擎的悲剧在于推出时间太早,希望Android TV普及的时候卷土重来的OGEngine能让中国在游戏引擎方面领跑全世界。
     
    LibGDX是一个跨平台的游戏开发框架,同样使用Java作为开发语言,前文所说的AndEngine就是基于LiBGDX实现的。LibGDX最大的优点就是极强的兼容性,不仅兼容Android和iOS,还兼容Windows、Linux、Max OS X等桌面系统。极强的兼容性还为开发提供了便利——不必打开Android模拟器,直接用电脑debug你的应用。在LibGDX和Android之间相互转型都很容易,知名的Android专家宋志辉、吴佳俊等都是从LibGDX转型Android的。
     
    如果不要Java语言,那就有Cosos2d-x可供选择。《Cocos2d-x游戏开发实战精解》的作者欧桐桐(笔名:OTT)认为Android程序员一般对面向对象的知识掌握的比较全面,上手Cosos2d-x比较容易,并且Cosos2d-x是中国人维护的,文档全、资源多、教程多。OTT在得知我是和他一样的藏书人士后还特地送我一本他的大作鼓励我。

    转型建议:做好心理准备,国内手游行业比普通的移动互联网行业加班更疯狂,建议刚入行没多久的Android工程师为了加班费转型,不建议30岁以上的Android工程师转型。
     
    HTML5
    HTML5也是Android工程师改行的好方向,HTML5在移动互联网领域应用非常广泛,比如混合开发、手机站、小游戏、微信公众号、微信小程序等。简单的手机站和对性能要求不高小游戏直接用从懒人模板(http://www.lanrenmb.com/)上找到的资源稍微修改一下即可,这里我只说说的混合开发应用和的小游戏怎么开发。
     
    最著名的HTML5移动开发框架当属Facebook发布于2015年的React Native,这是一套跨平台、动态更新的 Javascript 框架,口号是“Learn once, write anywhere”。与之类似有同属舶来的PhoneGap等。
     
    国产的HTML5开发框架在国内也百家争鸣,常见的有HBuilder和AppCan,二者共同特点是都为了便于新手入门制作了专用的编译器。2016年,在Qcon大会上宣布开源的Weex也异军突起,来自阿里的它因为开发的软件与原生App别无二致受到很多人的青睐。
     
    开发对性能要求比较高的HTML5游戏,靠模板是不行的。2014年2月创立于北京的Egret是一套完整的HTML5游戏开发解决方案,其核心产品白鹭引擎(Egret Engine)凭借上手简便、性能强大已占据国内超七成的手机页游引擎市场份额。
     
    Egret布道师徐聪(笔名:臭臭打不死人)还送我了Egret官方教程《Egret——HTML5游戏开发指南》和Egret吉祥物。
     
    转型建议:一般来说,除非手机页游或商场,大多数用HTML5开发的Android应用就是胡闹。这条路线几乎是专为电商和小游戏行业准备的,如果公司有这方面的需求,Android程序员可以凭借平时自学的这方面技术完成任务。
     
    VR
    2015年底游戏外设王者雷蛇推出了VR游戏头显,2016年各大游戏厂商和小工作室争先恐后开发VR游戏争夺市场,开启了“中国VR元年”。虽然目前VR主要用在娱乐领域,被很多人视为玩具,但是VR所具有的价值却远远超出“玩具”的范畴。
     
    前文讨论游戏引擎的时候没说Unity-3d不是疏漏,而是要把Unity-3d放在这儿谈。Unity-3d 是Unity公司开发的一个3D游戏开发工具,近年来的新版本不断加强对VR硬件系统的支持。Android程序员转型VR不仅可以实现自己从小就想让游戏跳出四角方框的梦想,还有Unity-3d所用的C#语言本来就是嚷着“我不是Java语言”的Java语言的学习优势。
     
    转型建议:VR现在正是一片蓝海,只要自学能力够强,转型VR就像2015年在合肥买房一样明智。当然前提是你能找到愿意出钱的老板或投资人。
     
    大数据
    移动互联网时代是一个科技发达,信息流通的时代,大数据就是这个高科技时代的产物。马云曾在演讲中提到:未来的时代将不是IT时代,而是DT的时代。DT就是Data Technology(数据科技)的缩写,大数据的合理利用与否成了很多行业成败的关键。
     
    移动互联网经过这些年的发展,拿O2O和当噱头已经唬不住投资人了。Hadoop也就自然而然受到了青睐,很多每4个月“生产”一批“两年经验”的“程序员”的培训机构也问我:“Android和iOS现在不吃香了,你能帮我介绍几个Hadoop讲师吗?”
     
    转型建议:与转型Java后台一样,Android程序员转型Hadoop也具备语言相通,特性相似的优势。目前各大培训机构已经如蝇逐臭争相批量生产Hadoop程序员,如果你是因为陷入了他们培训的Android程序员造成的红海才转型的话,建议你不要转型,提升自己的竞争力才是王道。
     
    人工智能和深度学习
    前一阵子AlphaGo战胜了人类世界的围棋世界冠军柯洁,轰动了全世界。柯洁认为AlphaGo是能够打败一切的围棋上帝,这个说法我不敢苟同,毕竟它没有和“天”对弈过,但存在能“胜天半子”的人类——祁同伟。即使AlphaGo不能打败一切,也没有人有理由认为人工智能和深度学习不能成为IT届的重要发展方向。
     
    TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,具备极佳的灵活性和可延展性,在和人工智能相关的领域都有广泛的应用。TensorFlow是开源的,会大大降低深度学习在各个行业中的应用难度,有远大的发展前景。
     
    转型建议:尽管我坚信将来会T(ensor)F(low)的boys受女性欢迎程度不亚于TFboys,但TensorFlow暂时很不成熟,这个“将来”距今多久还是未知数。
     
    Android系统
    Linux作为目前大多数服务器的操作系统,学习Linux的大多数人的目的是做一个运维。然而把脑洞再开大一点的话,Android程序员精通了Linux之后可以开发一套属于自己的Android系统。《Linux大棚命令百篇》的作者吴鹏冲(笔名:Roc,和我一样也是水浒迷)和《循序渐进Linux》的作者高俊峰都送了一本自己的作品鼓励我开发属于自己的Android ORM。

    这张照片摄于2016年3月30日我拿着《循序渐进Linux(第二版)》回到母校的自习室里攻读想成为像高老师一样能定制自己的Android系统的Linux专家的路上(双关)
     
    转型建议:如果Android程序员准备跳槽到生产手机等搭载Android系统的硬件的厂商的话学习Linux再合适不过了,否则就只能自己刷机玩了。
     
    产品经理
    每个人都可能变成自己最讨厌的人,我也不例外。我从《人人都是产品经理》中学到了产品经理的情怀,还从《从点子到产品》中学到了产品经理的技术。还有幸赶上了今年3月《从点子到产品》的作者刘飞收徒。关于我转型产品经理失败的情况是一个发生在我和刘飞之间的“挖隋炀帝坟墓的开发商名叫杨勇”的故事:
    2016年初,我带新人,没有收刘飞(同名学弟)为徒
    2017年初,刘飞带新人,不肯收我为徒
     
    转型建议:产品经理也是技术岗位,只不过写的是给人看的需求文档。如果一个Android程序员写的代码只能让电脑看懂而不能让负责维护的程序员看懂,那么就不要转型产品经理。
     
    Android程序员转型机会虽然多,但不要因为看招聘网站上某个职业平均工资高就转型,随波逐流的弄潮儿必然会在浪潮之巅摔得好惨。培训机构常说“Android不吃香了,移动互联网的寒冬来了”来吸引人报名学习速成的Hadoop和TensorFlow,其实遭遇寒冬的不是某个行业,而是某些没有打好基础的人。
      收起阅读 »

    Android 头像和昵称的修改

    1.在EaseChatFragment中的EaseChatFragmentHelper类中的onSetMessageAttributes的方法中设置自己的头像和昵称, @Override public void onSetMessageAttri...
    继续阅读 »
    1.在EaseChatFragment中的EaseChatFragmentHelper类中的onSetMessageAttributes的方法中设置自己的头像和昵称,
        @Override
    public void onSetMessageAttributes(EMMessage message) {
    String username = xxx;//自定义名称
    String avatar = yyy;//自定义头像

    message.setAttribute("avatar", avatar);
    message.setAttribute("username", username);
    }


    2.在easeUI中的EaseUserUtils类里面有两个方法setUserNick和setUserAvatar,分别是设置昵称和头像。
    将setUserAvatar改为:
    /**
    * 显示头像
    * set user avatar
    * @param message
    */
    public static void setUserAvatar(Context context, EMMessage message, ImageView imageView){
    if (message == null){
    return;
    }

    //发送消息 显示本地头像
    if (message.direct() == EMMessage.Direct.SEND){
    Glide.with(context).load(localUrl).into(imageView);
    return;
    }else {
    EaseUser easeUser = UserProfileCache.GetSpCacheUser(context, message.getFrom());
    //本地已缓存了这个用户信息 直接绑定
    if (easeUser != null){
    String avatar = easeUser.getAvatar();
    if(avatar != null){
    try {
    Glide.with(context).load(avatar).into(imageView);
    } catch (Exception e) {
    //use default avatar
    Glide.with(context).load(R.drawable.ease_default_avatar).into(imageView); }
    }else{
    Glide.with(context).load(R.drawable.ease_default_avatar).into(imageView);
    }
    }
    //本地没有缓存了这个用户信息 保存本地
    else {
    try {
    String avatar = message.getStringAttribute("avatar");

    if(avatar != null){
    try {
    Glide.with(context).load(avatar).into(imageView);
    } catch (Exception e) {
    //use default avatar
    Glide.with(context).load(R.drawable.ease_default_avatar).into(imageView); }
    }else{
    Glide.with(context).load(R.drawable.ease_default_avatar).into(imageView);
    }
    EaseUserUtils.getUserInfo(context, message);
    } catch (HyphenateException e) {
    e.printStackTrace();
    }
    }
    }
    }

    public static EaseUser getUserInfo(Context context, EMMessage message){

    EaseUser user = null;
    try {
    String avatar = message.getStringAttribute("avatar");
    String nick = message.getStringAttribute("username");

    user = new EaseUser(message.getFrom());
    user.setAvatar(avatar);
    user.setNickname(nick);
    EaseCommonUtils.setUserInitialLetter(user);
    UserProfileCache.setSpCacheUser(context, message.getFrom(), user);
    } catch (HyphenateException e) {
    e.printStackTrace();
    }
    return user;
    }

    UserProfileCache为用户缓存类。
    public class UserProfileCache {

    private static Gson gson = new Gson();
    public static String SP_CACHE_USER = "sp_cache_user";

    private static SharedPreferences spf;

    public static void setSpCacheUser(Context context, String user_id, EaseUser cacheUser){
    if (user_id == null){
    return;
    }
    if (spf == null){
    spf = context.getSharedPreferences(SP_CACHE_USER, Context.MODE_PRIVATE);
    }
    SharedPreferences.Editor editor = spf.edit();
    editor.putString(user_id, gson.toJson(cacheUser));
    editor.commit();
    }

    public static EaseUser GetSpCacheUser(Context context, String userId){
    if (userId == null){
    return null;
    }
    if (spf == null){
    spf = context.getSharedPreferences(SP_CACHE_USER, Context.MODE_PRIVATE);
    }
    String cacheUserString = spf.getString(userId,null);
    if (cacheUserString == null){
    return null;
    }else {
    return gson.fromJson(cacheUserString,EaseUser.class);
    }
    }

    }

    注:这种方式不用再创建数据库,只是对本地消息记录的显示做了下调整。其实是可以做的更好,比如把消息记录存到自己服务器,什么问题都不是问题,但是目前这里没有过多要求,所以还是不去麻烦后台爸爸,自己在客户端改了。
      收起阅读 »

    环信进阶篇-实现名片|红包|话题聊天室等自定义cell

        伴随着即时通讯成为了越来越多APP的刚需,匿名社交、阅后即焚、红包等新玩法层出不穷,基本的聊天方式越来越难以满足变态的需求。环信提供的自定义扩展属性功能非常的强大,能够帮助我们在cell中的各种需求做定制处理。这是分享一个之前做过的方法及实现,大家可以...
    继续阅读 »
        伴随着即时通讯成为了越来越多APP的刚需,匿名社交、阅后即焚、红包等新玩法层出不穷,基本的聊天方式越来越难以满足变态的需求。环信提供的自定义扩展属性功能非常的强大,能够帮助我们在cell中的各种需求做定制处理。这是分享一个之前做过的方法及实现,大家可以借鉴处理的过程及思路,如有不妥之处,请大家及时留言告知,谢谢。 
    今天就给大家介绍下怎么对cell中的各种需求的定制处理


     类型一:在现有会话cell上修改UI效果

    类似于上面给出的截图,我们有时候需要对环信官方给出的cell进行些许的调整。例如:项目中加入了不同于普通群聊或者聊天室的功能需求
    点击话题聊天,大家加入聊天室,这里发出的各种就是不同于普通聊天,普通的聊天只需展示文字、地址、图片等等,但是这里的需求是得加上时间、私聊按钮,没砍需求之前是还有点赞和取消赞的按钮。
    我们在普通聊天的基础上新建几个cell,文字、语音、图片、地图等等,不能和原有的普通cell混合起来,因为需求有普通聊天。

    直接把普通聊天cell中的代码拷贝过来,再在此基础上进行cell的UI自定义处理,就拿文字聊天时的处理情况为例:


    1、拷贝复制原有普通聊天cell内的代码

    2、把需要的新增的UI控件初始化

    3、适配各类控件

    4、传值及赋值

    5、新增按钮点击和本身cell的点击效果处理(别和cell上的点击效果混到一起)

    6、耐心调整cell上UI效果

    以上基本就是简单的自定义cell步骤了,有基础的小伙伴看下步骤应该就有思路了


    类型二:类似于红包和名片Cell的UI效果


    通常在我们项目中,并不只有文字、图片等等这些简单的聊天内容,有时候我们需要把自己的信息作为一张名片发给对方、发个红包给好朋友、发一个项目中的一个模块介绍给对方等等功能要求。
    我们就拿雷哥的这张假名片为例:
    /*!
    @method
    @brief 新增一个新的功能按钮
    @discussion
    @param image 按钮图片
    @param highLightedImage 高亮图片
    @param title 按钮标题
    @result
    */
    - (void)insertItemWithImage:(UIImage*)image
    highlightedImage:(UIImage*)highLightedImage
    title:(NSString*)title;
    /*!
    @method
    @brief 修改功能按钮图片
    @discussion
    @param image 按钮图片
    @param highLightedImage 高亮图片
    @param title 按钮标题
    @param index 按钮索引
    @result
    */
    - (void)updateItemWithImage:(UIImage*)image
    highlightedImage:(UIImage*)highLightedImage
    title:(NSString*)title
    atIndex:(NSInteger)index;
    /*!
    @method
    @brief 根据索引删除功能按钮
    @discussion
    @param index 按钮索引
    @result
    */
    - (void)removeItematIndex:(NSInteger)index;
    *  消息体类型
    typedef enum{
    EMMessageBodyTypeText  = 1,    /*! \~chinese 文本类型 \~english Text */
    EMMessageBodyTypeImage,        /*! \~chinese 图片类型 \~english Image */
    EMMessageBodyTypeVideo,        /*! \~chinese 视频类型 \~english Video */
    EMMessageBodyTypeLocation,      /*! \~chinese 位置类型 \~english Location */
    EMMessageBodyTypeVoice,        /*! \~chinese 语音类型 \~english Voice */
    EMMessageBodyTypeFile,          /*! \~chinese 文件类型 \~english File */
    EMMessageBodyTypeCmd,          /*! \~chinese 命令类型 \~english Command */
    }EMMessageBodyType;
    如果环信把这个开放出来,或许我们就更加简单了我们只需自己修改成自己对应的类型即可。但是这个目前就想想,所以我们可以在以上类型中找一个出来,在它的基础上做些文章,变成我们想要的类型。

    红包和名片最像什么。。。。对,不就和图片差不多嘛,不过小伙伴也不要以为只能拿图片来做文章,其他的我们都可以拿来用,这里就拿文字类型来作为例子(原理都一样)。

    01.jpg


    名片类型
    这里我们只简要介绍怎么根据会话类型来显示名片,具体传值等怎么做,有基础的小伙伴应该都懂,不懂的小伙伴见文章底部。
     
    1. 我们需要在发送名片时,在拓展消息里面存一个名片的字段,这个字段可以被用来判断是名片、红包等等。
    2. 名片、红包等等中内容,同样也存在拓展属性中(这里不做过多介绍)
    3. 我们在展示自己的消息和接收到对方的消息时,在文字类型的基础上再进一步判断是什么类型,加载对应类型的视图,如果是红包就加载红包的view,如果是名片就展示名片view......



    02.jpg


    加载不同类型的cell
    好了,以上就是我们所要介绍的两种不同类型cell的处理办法。


    以下是补充自定义cell时遇到的各种情况及处理:
    1、cell上语音、图片等原始点击和新增按钮点击冲突处理:

    注释掉原有的点击方法,把原有的点击方法放到具体的控件上去,避免cell上多个控件点击的冲突

    重点:记得把气泡上的点击权限打开
    _backgroundImageView.userInteractionEnabled = YES;



    03.jpg


    解决点击冲突
    2、cell上语音气泡长度的改变,避免过段影响布局

    我们只需把原有语音上的语音长度Label距语音图片控件调大一点距离就能自动把语音类气泡拉长。(其他类型一样处理原理)

    04.jpg


    语音气泡拉长
    3、因新增控件导致在原有cell上高度的变化处理
    /*! @method @brief 根据消息的内容,获取当前cell的高度 @discussion @param model        消息对象model @result 返回cell高度 */
    + (CGFloat)cellHeightWithModel:(id)model
    在原cell高度处理的情况下,根据各种类型的判断进行cell高度的自适应。

    05.jpg


    cell高度处理
    4、文字类型气泡长度的处理

    我暂时的处理方法:判断输入的文字长度,加入文字长度小于10,我会在后面自动补全5个空格,被动撑长气泡的长度。

    假如小伙伴们有更好的建议也可以留言,谢谢! 收起阅读 »

    环信Web IM 新版本发布,提供更为丰富的群组、聊天室功能,现在更新就送小风扇!

      六月的骄阳,暑气留恋,但这风风火火却远不能掩盖季节的丰富内涵。环信发布了WEB新版本,十余项更新,带来了更加丰富的群组、聊天室功能。环信还为小伙伴们准备了一批小风扇,参与使用新版本并在文章下方跟帖使用反馈,就能获得环信usb小风扇,数量有限,先到先得! ...
    继续阅读 »
      六月的骄阳,暑气留恋,但这风风火火却远不能掩盖季节的丰富内涵。环信发布了WEB新版本,十余项更新,带来了更加丰富的群组、聊天室功能。环信还为小伙伴们准备了一批小风扇,参与使用新版本并在文章下方跟帖使用反馈,就能获得环信usb小风扇,数量有限,先到先得!



    d1fddd2e88747ea05968d89f6b696963.jpg


    环信USB小风扇


    Web IM v1.4.11 2017-06-14

     新功能:
    • [sdk] debug.js融合到sdk当中,优化日志内容输出
    • [sdk] 通过Rest屏蔽群组
    • [sdk] 通过Rest发出入群申请
    • [sdk] 通过Rest获取群组列表
    • [sdk] 通过Rest根据groupid获取群组详情
    • [sdk] 通过Rest列出某用户所加入的所有群组
    • [sdk] 通过Rest列出群组的所有成员
    • [sdk] 通过Rest禁止群用户发言
    • [sdk] 通过Rest取消对用户禁言的禁止
    • [sdk] 通过Rest获取群组下所有管理员
    • [sdk] 通过Rest获取群组下所有被禁言成员
    • [sdk] 通过Rest设置群管理员
    • [sdk] 通过Rest取消群管理员
    • [sdk] 通过Rest同意用户加入群
    • [sdk] 通过Rest拒绝用户加入群
    • [sdk] 通过Rest添加用户至群组黑名单(单个)
    • [sdk] 通过Rest添加用户至群组黑名单(批量)
    • [sdk] 通过Rest将用户从群黑名单移除(单个)
    • [sdk] 通过Rest将用户从群黑名单移除(批量)
    • [demo] 聊天窗口中记录可清空
    • [demo] 聊天窗口中发送方聊天记录显示状态(未送达、已送达、已读)
    • [demo] 查看聊天室成员
    • [demo] 通过链接直接打开与好友的对话框
    • [demo] 新增申请加入公开群面板
    • [demo] 在申请加入公开群面板可下拉分页获取公开群
    • [demo] 在申请加入公开群面板可点击群名称可查看群详情
    • [demo] 在申请加入公开群面板可搜索群查看群详情
    • [demo] 在申请加入公开群面板群详情页面可申请加入群组
    • [demo] 群主可同意、拒绝加群申请
    • [demo] 在群主的群成员列表中新增添加/移除管理员、禁言/解禁群成员按钮
    Bug修复:
    • [sdk] 添加好友会产生多余的订阅消息
    • [sdk] 频繁的发送消息会导致消息id重复的问题
    • [sdk] 适配SDK发送文件和图片的大小
    • [demo] 优化sdk/demo.html,修复某些依赖文件找不到的问题
    • [demo] 修复离线消息数量统计不准确问题

     
    webim在线体验:https://webim.easemob.com

    版本历史:更新日志
     
    SDK下载:下载地址 收起阅读 »

    Android 守护进程的实现方式

         “我的APP像微信那样能一直在手机运行吗?”关于 Android 平台的进程保活,一 直是所有Android 开发者瞩目的内容之一,也是环信小伙们比较关心的问题,本篇文章给大家分享关于微信进程保活的原理及Android守护进程的实现教程。   为什么...
    继续阅读 »
     
       “我的APP像微信那样能一直在手机运行吗?”关于 Android 平台的进程保活,一 直是所有Android 开发者瞩目的内容之一,也是环信小伙们比较关心的问题,本篇文章给大家分享关于微信进程保活的原理及Android守护进程的实现教程。
     
    为什么微信可以一直在手机后台跑着能收到消息?

        国内手机厂商对 android rom 进行了定制,对后台服务以及运行在后台的程序进行了严格的限制,微信等这些大厂商的 app 都已经通过和设备厂商合作在安装时都已经加入了系统的白名单,因此设备并不会限制对方 app 在后台运行;

    我自己的APP该如何实现进程保活?
     
    1. 引导用户把当前 app 加入到设备的白名单中,解除设备对 app 的限制;
    2. 小米和华为设备可以集成对应的推送实现在app 被干掉后依然收推送通知;
    3. 可以自己在 app 端实现守护进程的方式,让 app 在系统级别自动回收的情况下减少被杀死的概率,这种方式对用户主动回收无效。


    第一条和第二条就不多说了,环信imgeek社区里已经有了相应的文章(http://www.imgeek.org/article/825308754 )接下来介绍守护进程的实现。
     
    友情提示:
       本篇教程能让我们的程序在后台运行的时间长一些,或者在被干掉的时候,能够重新站起来,需要注意不是每次都有效,也不是在所有的设备的上都有效的,所以,想让自己程序在Android里永生不死的,请忽略本文!请忽略!
     什么是守护进程?

        守护进程能让我们的程序在后台运行的时间长一些,或者在被干掉的时候,能够重新站起来,需要注意不是每次都有效,也不是在所有的设备的上都有效的。
     
    守护进程的实现,本文两个核心观点:
     
    1. 提高进程优先级,降低被回收或杀死概率
    2. 在进程被干掉后,进行拉起

     要实现实现上边所说,通过下边几点来实现,首先我们需要了解下进程的优先级划分:

    Process Importance记录在ActivityManager.java类中:
    **
    * Path:SDK/sources/android-25/android/app/ActivityManager#RunningAppProcessInfo.java
    *
    * 这个进程正在运行前台UI,也就是说,它是当前在屏幕顶部的东西,用户正在进行交互的而进程
    */
    public static final int IMPORTANCE_FOREGROUND = 100;

    /**
    * 此进程正在运行前台服务,即使用户不是在应用中时也执行音乐播放,这一般表示该进程正在做用户积极关心的事情
    */
    public static final int IMPORTANCE_FOREGROUND_SERVICE = 125;
    /**
    * 这个过程不是用户的直接意识到,但在某种程度上是他们可以察觉的。
    */
    public static final int IMPORTANCE_PERCEPTIBLE = 130;

    /**
    * 此进程正在运行前台UI,但设备处于睡眠状态,因此用户不可见,意思是用户意识不到的进程,因为他们看不到或与它交互,
    * 但它是相当重要,因为用户解锁设备时期望的返回到这个进程
    */
    public static final int IMPORTANCE_TOP_SLEEPING = 150;

    /**
    * 进程在后台,但我们不能恢复它的状态,所以我们想尽量避免杀死它,不然这个而进程就丢了
    */
    public static final int IMPORTANCE_CANT_SAVE_STATE = 170;

    /**
    * 此进程正在运行某些对用户主动可见的内容,但不是直接显示在UI,
    * 这可能运行在当前前台之后的窗口(因此暂停并且其状态被保存,不与用户交互,但在某种程度上对他们可见);
    * 也可能在系统的控制下运行其他服务,
    */
    public static final int IMPORTANCE_VISIBLE = 200;

    /**
    * 服务进程,此进程包含在后台保持运行的服务,这些后台服务用户察觉不到,是无感知的,所以它们可以由系统相对自由地杀死
    */
    public static final int IMPORTANCE_SERVICE = 300;

    /**
    * 后台进程
    */
    public static final int IMPORTANCE_BACKGROUND = 400;

    /**
    * 空进程,此进程没有任何正在运行的代码
    */
    public static final int IMPORTANCE_EMPTY = 500;

    // 此过程不存在。
    public static final int IMPORTANCE_GONE = 1000;
    进程回收机制

    了解进程优先级之后,我们还需要知道一个进程回收机制的东西;这里参考AngelDevil在博客园上的一篇文章:
     
    详情参考:【Android Low Memory Killer】
     
    Android的Low Memory Killer基于Linux的OOM机制,在Linux中,内存是以页面为单位分配的,当申请页面分配时如果内存不足会通过以下流程选择bad进程来杀掉从而释放内存:
    alloc_pages -> out_of_memory() -> select_bad_process() -> badness()
    在Low Memory Killer中通过进程的oom_adj与占用内存的大小决定要杀死的进程,oom_adj越小越不容易被杀死;
    Low Memory Killer Driver在用户空间指定了一组内存临界值及与之一一对应的一组oom_adj值,当系统剩余内存位于内存临界值中的一个范围内时,如果一个进程的oom_adj值大于或等于这个临界值对应的oom_adj值就会被杀掉。

    下边是表示Process State(即老版本里的OOM_ADJ)数值对照表,数值越大,重要性越低,在新版SDK中已经在android层去除了小于0的进程状态
    // Path:SDK/sources/android-25/android/app/ActivityManager#RunningAppProcessInfo.java 
    // 进程不存在。
    public static final int PROCESS_STATE_NONEXISTENT = -1;
    // 进程是一个持久的系统进程,一般指当前 UI 进程
    public static final int PROCESS_STATE_PERSISTENT = 0;
    // 进程是一个持久的系统进程,正在做和 UI 相关的操作,但不直接显示
    public static final int PROCESS_STATE_PERSISTENT_UI = 1;
    // 进程正在托管当前的顶级活动。请注意,这涵盖了用户可见的所有活动。
    public static final int PROCESS_STATE_TOP = 2;
    // 进程由于系统绑定而托管前台服务。
    public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 3;
    // 进程正在托管前台服务。
    public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
    // 与{@link #PROCESS_STATE_TOP}相同,但设备处于睡眠状态。
    public static final int PROCESS_STATE_TOP_SLEEPING = 5;
    // 进程对用户很重要,是他们知道的东西
    public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;
    // 进程对用户很重要,但不是他们知道的
    public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;
    // 进程在后台运行备份/恢复操作
    public static final int PROCESS_STATE_BACKUP = 8;
    // 进程在后台,但我们不能恢复它的状态,所以我们想尽量避免杀死它,不然这个而进程就丢了
    public static final int PROCESS_STATE_HEAVY_WEIGHT = 9;
    // 进程在后台运行一个服务,与oom_adj不同,此级别用于正常运行在后台状态和执行操作状态。
    public static final int PROCESS_STATE_SERVICE = 10;
    // 进程在后台运行一个接收器,注意,从oom_adj接收器的角度来看,在较高的前台级运行,但是对于我们的优先级,这不是必需的,并且将它们置于服务之下意味着当它们接收广播时,一些进程状态中的更少的改变。
    public static final int PROCESS_STATE_RECEIVER = 11;
    // 进程在后台,但主持家庭活动
    public static final int PROCESS_STATE_HOME = 12;
    // 进程在后台,但托管最后显示的活动
    public static final int PROCESS_STATE_LAST_ACTIVITY = 13;
    // 进程正在缓存以供以后使用,并包含活动
    public static final int PROCESS_STATE_CACHED_ACTIVITY = 14;
    // 进程正在缓存供以后使用,并且是包含活动的另一个缓存进程的客户端
    public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 15;
    // 进程正在缓存以供以后使用,并且为空
    public static final int PROCESS_STATE_CACHED_EMPTY = 16;
    Process State(即老版本的OOM_ADJ)与Process Importance对应关系,这个方法也是在ActivityManager.java类中,有了这个关系,就知道可以知道我们的应用处于哪个级别,对于我们后边优化有个很好地参考
    /** 
    * Path:SDK/sources/android-25/android/app/ActivityManager#RunningAppProcessInfo.java
    *
    * 通过这个方法,将Linux底层的 OOM_ADJ级别码和 android 层面的进程重要程度联系了起来
    */
    public static int procStateToImportance(int procState) {
    if (procState == PROCESS_STATE_NONEXISTENT) {
    return IMPORTANCE_GONE;
    } else if (procState >= PROCESS_STATE_HOME) {
    return IMPORTANCE_BACKGROUND;
    } else if (procState >= PROCESS_STATE_SERVICE) {
    return IMPORTANCE_SERVICE;
    } else if (procState > PROCESS_STATE_HEAVY_WEIGHT) {
    return IMPORTANCE_CANT_SAVE_STATE;
    } else if (procState >= PROCESS_STATE_IMPORTANT_BACKGROUND) {
    return IMPORTANCE_PERCEPTIBLE;
    } else if (procState >= PROCESS_STATE_IMPORTANT_FOREGROUND) {
    return IMPORTANCE_VISIBLE;
    } else if (procState >= PROCESS_STATE_TOP_SLEEPING) {
    return IMPORTANCE_TOP_SLEEPING;
    } else if (procState >= PROCESS_STATE_FOREGROUND_SERVICE) {
    return IMPORTANCE_FOREGROUND_SERVICE;
    } else {
    return IMPORTANCE_FOREGROUND;
    }
    }
    一般情况下,设备端进程被干掉有一下几种情况

    QQ截图20170615143439.jpg


    由以上分析,我们可以可以总结出,如果想提高我们应用后台运行时间,就需要提高当前应用进程优先级,来减少被杀死的概率

    守护进程的实现

    分析了那么多,现在对Android自身后台进程管理,以及进程的回收也有了一个大致的了解,后边我们要做的就是想尽一切办法去提高应用进程优先级,降低进程被杀的概率;或者是在被杀死后能够重新启动后台守护进程

    1.模拟前台进程

    第一种方式就是利用系统漏洞,使用startForeground()将当前进程伪装成前台进程,将进程优先级提高到最高(这里所说的最高是服务所能达到的最高,即1);

    这种方式在7.x之前都是很好用的,QQ、微信、IReader、Keep 等好多应用都是用的这种方式实现;因为在7.x 以后的设备上,这种伪装前台进程的方式也会显示出来通知栏提醒,这个是取消不掉的,虽然Google现在还没有对这种方式加以限制,不过这个已经能够被用户感知到了,这种方式估计也用不了多久了

    下边看下实现方式,这边这个VMDaemonService就是一个守护进程服务,其中在服务的onStartCommand()方法中调用startForeground()将服务进程设置为前台进程,当运行在 API18 以下的设备是可以直接设置,API18 以上需要实现一个内部的Service,这个内部类实现和外部类同样的操作,然后结束自己;当这个服务启动后就会创建一个定时器去发送广播,当我们的核心服务被干掉后,就由另外的广播接收器去接收我们守护进程发出的广播,然后唤醒我们的核心服务;
    /**
    * 以实现内部 Service 类的方式实现守护进程,这里是利用 android 漏洞提高当前进程优先级
    *
    * Created by lzan13 on 2017/3/7.
    */
    public class VMDaemonService extends Service {

    private final static String TAG = VMDaemonService.class.getSimpleName();

    // 定时唤醒的时间间隔,这里为了自己测试方边设置了一分钟
    private final static int ALARM_INTERVAL = 1 * 60 * 1000;
    // 发送唤醒广播请求码
    private final static int WAKE_REQUEST_CODE = 5121;
    // 守护进程 Service ID
    private final static int DAEMON_SERVICE_ID = -5121;

    @Override public void onCreate() {
    Log.i(TAG, "VMDaemonService->onCreate");
    super.onCreate();
    }

    @Override public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i(TAG, "VMDaemonService->onStartCommand");
    // 利用 Android 漏洞提高进程优先级,
    startForeground(DAEMON_SERVICE_ID, new Notification());
    // 当 SDk 版本大于18时,需要通过内部 Service 类启动同样 id 的 Service
    if (Build.VERSION.SDK_INT >= 18) {
    Intent innerIntent = new Intent(this, DaemonInnerService.class);
    startService(innerIntent);
    }

    // 发送唤醒广播来促使挂掉的UI进程重新启动起来
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent alarmIntent = new Intent();
    alarmIntent.setAction(VMWakeReceiver.DAEMON_WAKE_ACTION);

    PendingIntent operation = PendingIntent.getBroadcast(this, WAKE_REQUEST_CODE, alarmIntent,
    PendingIntent.FLAG_UPDATE_CURRENT);

    alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
    ALARM_INTERVAL, operation);

    /**
    * 这里返回值是使用系统 Service 的机制自动重新启动,不过这种方式以下两种方式不适用:
    * 1.Service 第一次被异常杀死后会在5秒内重启,第二次被杀死会在10秒内重启,第三次会在20秒内重启,一旦在短时间内 Service 被杀死达到5次,则系统不再拉起。
    * 2.进程被取得 Root 权限的管理工具或系统工具通过 forestop 停止掉,无法重启。
    */
    return START_STICKY;
    }

    @Override public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("onBind 未实现");
    }

    @Override public void onDestroy() {
    Log.i(TAG, "VMDaemonService->onDestroy");
    super.onDestroy();
    }

    /**
    * 实现一个内部的 Service,实现让后台服务的优先级提高到前台服务,这里利用了 android 系统的漏洞,
    * 不保证所有系统可用,测试在7.1.1 之前大部分系统都是可以的,不排除个别厂商优化限制
    */
    public static class DaemonInnerService extends Service {

    @Override public void onCreate() {
    Log.i(TAG, "DaemonInnerService -> onCreate");
    super.onCreate();
    }

    @Override public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i(TAG, "DaemonInnerService -> onStartCommand");
    startForeground(DAEMON_SERVICE_ID, new Notification());
    stopSelf();
    return super.onStartCommand(intent, flags, startId);
    }

    @Override public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("onBind 未实现");
    }

    @Override public void onDestroy() {
    Log.i(TAG, "DaemonInnerService -> onDestroy");
    super.onDestroy();
    }
    }
    }
    当我们启动这个守护进程的时候,就可以使用以下adb命令查看当前程序的进程情况(需要adb shell进去设备),
    为了等下区分进程优先级,我启动了一个普通的后台进程,两外两个一个是我们启动的守护进程,一个是当前程序的核心进程,可以看到除了后台进程外,另外两个进程都带有isForeground=true的属性:
    # 这个命令的 services 可以换成 service,这样会只显示当前,进程,不显示详细内容
    # dumpsys activity services <Your Package Name>
    root@vbox86p:/ # dumpsys activity services com.vmloft.develop.daemon
    ACTIVITY MANAGER SERVICES (dumpsys activity services)
    User 0 active services:
    * ServiceRecord{170fe1dd u0 com.vmloft.develop.daemon/.services.VMDaemonService}
    intent={cmp=com.vmloft.develop.daemon/.services.VMDaemonService}
    packageName=com.vmloft.develop.daemon
    processName=com.vmloft.develop.daemon:daemon
    baseDir=/data/app/com.vmloft.develop.daemon-1/base.apk
    dataDir=/data/data/com.vmloft.develop.daemon
    app=ProcessRecord{173fe77f 2370:com.vmloft.develop.daemon:daemon/u0a68}
    isForeground=true foregroundId=-5121 foregroundNoti=Notification(pri=0 contentView=com.vmloft.develop.daemon/0x1090077 vibrate=null sound=null defaults=0x0 flags=0x62 color=0xff607d8b vis=PRIVATE)
    createTime=-6s196ms startingBgTimeout=--
    lastActivity=-6s157ms restartTime=-6s157ms createdFromFg=true
    startRequested=true delayedStop=false stopIfKilled=false callStart=true lastStartId=1

    * ServiceRecord{2fee4f84 u0 com.vmloft.develop.daemon/.services.VMCoreService}
    intent={cmp=com.vmloft.develop.daemon/.services.VMCoreService}
    packageName=com.vmloft.develop.daemon
    processName=com.vmloft.develop.daemon
    baseDir=/data/app/com.vmloft.develop.daemon-1/base.apk
    dataDir=/data/data/com.vmloft.develop.daemon
    app=ProcessRecord{18c6a1b4 2343:com.vmloft.develop.daemon/u0a68}
    isForeground=true foregroundId=-5120 foregroundNoti=Notification(pri=0 contentView=com.vmloft.develop.daemon/0x1090077 vibrate=null sound=null defaults=0x0 flags=0x62 color=0xff607d8b vis=PRIVATE)
    createTime=-28s136ms startingBgTimeout=--
    lastActivity=-28s136ms restartTime=-28s136ms createdFromFg=true
    startRequested=true delayedStop=false stopIfKilled=false callStart=true lastStartId=1

    * ServiceRecord{2ef6909e u0 com.vmloft.develop.daemon/.services.VMBackgroundService}
    intent={cmp=com.vmloft.develop.daemon/.services.VMBackgroundService}
    packageName=com.vmloft.develop.daemon
    processName=com.vmloft.develop.daemon:background
    baseDir=/data/app/com.vmloft.develop.daemon-1/base.apk
    dataDir=/data/data/com.vmloft.develop.daemon
    app=ProcessRecord{29f8734c 2388:com.vmloft.develop.daemon:background/u0a68}
    createTime=-3s279ms startingBgTimeout=--
    lastActivity=-3s262ms restartTime=-3s262ms createdFromFg=true
    startRequested=true delayedStop=false stopIfKilled=false callStart=true lastStartId=1
    然后我们可以用下边的命令查看ProcessID
    # 这个命令可以查看当前DProcessID(数据结果第二列),我们可以看到当前程序有两个进程
    # ps | grep com.vmloft.develop.daemon
    root@vbox86p:/ # ps | grep com.vmloft.develop.daemon
    u0_a68 2343 274 1012408 42188 ffffffff f74f1b45 S com.vmloft.develop.daemon
    u0_a68 2370 274 997012 26152 ffffffff f74f1b45 S com.vmloft.develop.daemon:daemon
    u0_a68 2388 274 997012 25668 ffffffff f74f1b45 S com.vmloft.develop.daemon:background
    有了ProcessID之后,我们可以根据这个ProcessID获取到当前进程的优先级状态Process State,对应Linux层的oom_adj
    可以看到当前核心进程的级别为0,因为这个表示当前程序运行在前台 UI 界面,守护进程级别为1,因为我们利用漏洞设置成了前台进程,虽然不可见,但是他的级别也是比较高的,仅次于前台 UI 进程,然后普通后台进程级别为4;当我们退到后台时,可以看到核心进程的级别变为1了,这就是因为我们利用startForeground()将进程设置成前台进程的原因,这样就降低了进程被系统回收的概率了;
    # 这个命令就是通过 ProcessID 输出其对应 oom_adj
    # cat /proc/ProcessID/oom_adj
    # 程序在前台时,查询进程级别
    root@vbox86p:/ # cat /proc/2343/oom_adj
    0
    root@vbox86p:/ # cat /proc/2370/oom_adj
    1
    root@vbox86p:/ # cat /proc/2388/oom_adj
    4
    # 当程序退到后台时,再次查看进程级别
    root@vbox86p:/ # cat /proc/2343/oom_adj
    1
    root@vbox86p:/ # cat /proc/2370/oom_adj
    1
    root@vbox86p:/ # cat /proc/2388/oom_adj
    4
    可以看到这种方式确实能够提高进程优先级,但是在一些国产的设备上还是会被杀死的,比我我测试的时候小米点击清空最近运行的应用进程就别干掉了;当把应用加入到设备白名单里就不会被杀死了,微信就是这样,人家直接装上之后就已经在白名单里了,我们要做的就是在用户使用中引导他们将我们的程序设置进白名单,将守护进程和白名单结合起来,这样才能保证我们的应用持续或者

    2.JobScheduler机制唤醒

    Android系统在5.x以上版本提供了一个JobSchedule接口,系统会根据自己实现定时去调用改接口传递的进程去实现一些操作,而且这个接口在被强制停止后依然能够正常的启动;不过在一些国产设备上可能无效,比如小米;
    下边是 JobServcie 的实现:
    /**
    * 5.x 以上使用 JobService 实现守护进程,这个守护进程要做的工作很简单,就是启动应用的核心进程
    * Created by lzan13 on 2017/3/8.
    */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP) public class VMDaemonJobService extends JobService {

    private final static String TAG = VMDaemonJobService.class.getSimpleName();

    @Override public boolean onStartJob(JobParameters params) {
    Log.d(TAG, "onStartJob");
    // 这里为了掩饰直接启动核心进程,没有做其他判断操作
    startService(new Intent(getApplicationContext(), VMCoreService.class));
    return false;
    }

    @Override public boolean onStopJob(JobParameters params) {
    Log.d(TAG, "onStopJob");
    return false;
    }
    }
    我们要做的就是在需要的时候调用JobSchedule的schedule来启动任务;剩下的就不需要关心了,JobSchedule会帮我们做好,下边就是我这边实现的启动任务的方法:
    /**
    * 5.x以上系统启用 JobScheduler API 进行实现守护进程的唤醒操作
    */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void startJobScheduler() {
    int jobId = 1;
    JobInfo.Builder jobInfo = new JobInfo.Builder(jobId, new ComponentName(this, VMDaemonJobService.class));
    jobInfo.setPeriodic(10000);
    jobInfo.setPersisted(true);
    JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
    jobScheduler.schedule(jobInfo.build());
    }
    3.系统 Service START_STICKY 机制重启

    在实现Service类时,将onStartCommand()返回值设置为START_STICKY,利用系统机制在Service挂掉后自动拉活;不过这种方式只适合比较原生一些的系统,像小米,华为等这些定制化比较高的第三方厂商,他们都已经把这些给限制掉了;
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i(TAG, "VMDaemonService->onStartCommand");
    /**
    * 这里返回值是使用系统 Service 的机制自动重新启动,不过这种方式以下两种方式不适用:
    * 1.Service 第一次被异常杀死后会在5秒内重启,第二次被杀死会在10秒内重启,第三次会在20秒内重启,一旦在短时间内 Service 被杀死达到5次,则系统不再拉起。
    * 2.进程被取得 Root 权限的管理工具或系统工具通过 forestop 停止掉,无法重启。
    * 3.一些定制化比较高的第三方系统也不适用
    */
    return START_STICKY;
    }
    这种方式在以下两种情况无效:
    • Service第一次被异常杀死后会在5秒内重启,第二次被杀死会在10秒内重启,第三次会在20秒内重启,一旦在短时间内Service被杀死达到5次,这个服务就不能再次重启了;
    • 进程被取得Root权限的管理工具或系统工具通过fores-top方式停止掉,无法重启;
    • 一些定制化比较高的第三方系统也不适用
    4.其他保活方式

    • 利用 Native 本地进程,这个主要使用到 jni 调用底层实现,而且在 Android 5.x 以后对这个限制也比较高,不适用了,暂时不研究
    • 集成第三方SDK互相唤醒,这个只要正常集成了第三方的SDK,并使用了他们对应的服务,当一个设备安装的多个应用都集成了某一个第三方SDK时,启动任意一个 app 都会唤醒其他的 app,不过这个在一些新版的国内厂商系统也是做了限制,这种方式并没有什么效果
    • 一像素的 Activity 方式(流氓方式),经测试一些手机系统无法检测到解锁和锁屏,不确定是否系统修改了解锁或者锁屏的广播,还是禁用了这些广播,因此此方式无效;


    结语

    事事没有绝对,万物总有一些漏洞,就算上边的那些方式不可用了,后边肯定还会出现其他的方式;我们不能保证我们的应用不死,但我们可以提高存活率;

    其实最好的方式还是把程序做好,让程序本身深入人心,别人喜欢你了,就算你被干掉了,他们也会主动的把你拉起来,然后把你加入他们的白名单,然后我们的目的就实现了不是 收起阅读 »

    获取好友列表,报错SERVER_UNKNOWN_ERROR = 303

    List<String> usernames = EMClient.getInstance().contactManager().getAllContactsFromServer(); 获取好友列表在第一次登录成功后获取正常,但是当我在其他界面调...
    继续阅读 »
    List<String> usernames = EMClient.getInstance().contactManager().getAllContactsFromServer();

    获取好友列表在第一次登录成功后获取正常,但是当我在其他界面调用这个方法的时候去报错如下:
     
    com.hyphenate.exceptions.HyphenateException: Unknown server error
     
    解决方法:要放到子线程中。
     
    注:我想知道why,why,why!!!!!!!! 收起阅读 »

    环信移动客服v5.20已发布,支持自助开通工单功能以及客服直接处理工单

    客服模式 支持自助开通工单功能以及客服直接处理工单 新增工单页面,支持自助开通工单功能,以及客服直接处理工单,包括新建工单、回复工单、分配工单、修改帮助主题、修改工单状态,筛选工单,等等。 工单功能为增值服务,如需开通,请在工单页面提交申请,环信商务经理...
    继续阅读 »
    客服模式

    支持自助开通工单功能以及客服直接处理工单

    新增工单页面,支持自助开通工单功能,以及客服直接处理工单,包括新建工单、回复工单、分配工单、修改帮助主题、修改工单状态,筛选工单,等等。

    工单功能为增值服务,如需开通,请在工单页面提交申请,环信商务经理会主动联系您。

    申请开通工单功能

    工单功能可以帮助您实现高效的跨部门协作,只需提交申请,并绑定邮箱,即可启动您的工单功能服务。

    步骤如下:
    1. 在工单页面,点击“申请工单功能”;
    2. 填写姓名、电话、企业名称、邮箱,点击“下一步”;
    3. 填写帮助主题(帮助主题为工单的类别),点击“下一步”;
    4. 填写系统邮箱(用于接收和发送工单相关的邮件),点击“提交”。


    提交申请后,请耐心等待,环信商务经理会尽快与您联系。 


    01.png


    新建工单

    客服与客户聊天过程中,可以为客户创建工单。

    步骤如下:
    1. 在会话页面,点击输入框上方的工单按钮;
    2. 填写工单标题,选择优先级、帮助主题、分配技能组、分配坐席,填写工单内容,勾选“附带访客信息”,并保存。


    勾选“附带访客信息”时,工单包含对应的客户信息,可以在工单详情的“客户资料”页签查看。 


    02.png



    处理工单

    客服可以对工单进行回复,分配工单给技能组或坐席,修改帮助主题、优先级、工单状态,查看工单进度,查看客户资料。

    在工单页面,点击任意工单,即可查看工单详情。并执行下述工单处理操作:

    回复工单:回复工单时,如果勾选“发布为公开回复”,工单系统将回复内容通知客户;不勾选时,回复仅客服可以查看。
    • 工单处理:分配技能组、分配坐席、修改帮助主题、优先级、状态。
    • 工单进度:查看工单进度。
    • 客户资料:查看客户资料。

    03.png

    筛选工单在工单页面已为您创建一些默认工单筛选器,帮助您对工单进行分类管理。您还可以创建自定义的筛选器,以满足更具体的需求。创建自定义筛选器步骤如下:在工单页面,点击“自定义筛选”;填写筛选器名称,选择筛选条件,如工单创建时间段、工单创建人、客户名称、工单编号、工单标题、分配技能组、分配坐席、帮助主题、工单状态,并点击“确定”。创建成功后,可以根据自定义筛选器对工单进行筛选。您还可以编辑或删除自定义筛选器。 

    04.png

    工单通知当工单创建成功、分配技能组或客服、得到回复、状态变更时,创建工单的客服将会收到系统消息。 

    05.png

    会话面板聊天窗口优化会话面板聊天窗口优化,支持拖动扩展输入框,以显示更多正在输入的内容。 

    06.png

    留言支持根据更新时间进行筛选留言页面显示留言的更新时间,并支持根据更新时间进行筛选和排序。更新时间指,留言分配的客服变更或留言状态变更的时间。
    • 筛选:点击“自定义留言筛选”,选择“更新时间”范围,点击“筛选查询”,对留言进行筛选。
    • 排序:点击留言列表中“更新时间”右侧的箭头,使留言按照更新时间升序或降序排列。

    07.png

    客户中心显示客户的真实姓名客户中心新增“名字”一列,显示客户的真实姓名。 

    08.png

    管理员模式新增REST API渠道环信移动客服新增REST API渠道。开通REST API渠道并配置服务器信息后,客服向客户回复的消息,将被环信转发到服务器的回调地址中。该功能可用于环信移动客服与第三方服务器之间的消息传递。REST API渠道支持创建多个REST关联,每个REST关联均可作为环信与您的服务器之间收发消息的通道。创建REST关联:[list=1]
  • 进入“管理员模式 > 渠道管理 > REST API”页面;
  • 点击“添加REST关联”按钮,填写关联名称、回调地址,并保存。


  • 系统自动为您生成Client ID、Client Secret、POST API。Client ID和Client Secret用于向环信发送消息时的身份认证;消息API为您向环信发送消息时使用的REST API接口,方法为POST。 


    09.png




    关于REST API渠道的身份认证方式、消息格式,请参考:REST API渠道集成

    注:REST API渠道为增值服务,如需开通,请提供租户ID并联系环信商务经理。

    新增APP关联演示视频

    APP关联信息页新增APP关联的演示视频,视频说明了APP关联的Client ID和IM服务号与即时通讯云的应用之间的关系,以及如何添加APP关联。

    如果已有即时通讯云的应用,可以采取“关联IM账号”的方式创建APP关联。对应关系如下:

    Client ID: APP关联的Client ID与即时通讯云的应用的Client ID一致;
    IM服务号:APP关联的IM服务号对应即时通讯云的应用的一个IM用户。

    进入“管理员模式 > 渠道管理 > 手机APP”页面,点击APP关联信息页中Client ID和IM服务号右侧的问号,可以查看相应的演示视频。

    客户标签支持导入导出


    10.png





    客户标签支持下载模版、导入、导出,方便管理员对客户标签进行批量整理。

    在导入客户标签时,会自动过滤已存在的客户标签,只导入新增的客户标签。 
    attach]7544[/attach]
    “不活跃会话超时自动结束”开关优化

    优化“不活跃会话超时自动结束”开关,该开关不再对待接入会话生效。优化后,该开关打开时,对于客服的进行中会话,如果客户和客服在设定时间内均未回复消息,系统将自动发送提示语给客户,并结束会话。

    如果需要自动结束超时的进行中会话,进入“管理员模式 > 设置 > 系统开关”页面,打开“不活跃会话超时自动结束”开关。
    如果需要自动结束超时的待接入会话,进入“管理员模式 > 设置 > 系统开关”页面,打开“待接入超时结束会话”开关。

    客服列表优化

    优化“管理员模式 > 成员管理 > 客服”页面的客服列表,删除原导出日志按钮。所有客服的登录日志,均可以在“管理员模式 > 统计查询 > 客服时长统计”页面查看并导出。

    Android客服工作台

    当前版本:V3.0

    新功能:

    管理员模式,当前会话支持筛选、转接、关闭
    留言支持批量分配

    iOS客服工作台

    当前版本:V2.1.9

    新功能:

    新增管理员模式,包含管理员首页的数据展示
    支持查看通知详情

    移动客服Android SDK

    当前版本:V1.0.7

    新功能:

    新增发送和接收短视频功能

    移动客服iOS SDK

    当前版本:V1.1.0

    新功能:

    SDK全面升级为动态库,集成更简单,功能更全面
    离线推送支持推送详情
    优化升级HelpDeskUI

    环信移动客服更新日志http://docs.easemob.com/cs/releasenote/5.20 

    环信移动客服登陆地址http://kefu.easemob.com/ 收起阅读 »

    环信网页的onready 轨迹回调在电脑浏览器上有效 但是在手机浏览器上就不会触发了

           环信网页的onready 轨迹回调在电脑浏览器上有效 但是在手机浏览器上就不会触发了 有大神指导是怎么回事吗? 附上代码: <script>     var saleprice = document.getElementById(&...
    继续阅读 »
           环信网页的onready 轨迹回调在电脑浏览器上有效 但是在手机浏览器上就不会触发了 有大神指导是怎么回事吗?

    附上代码:
    <script>
        var saleprice = document.getElementById("spSalaPrice");
        var productName = document.getElementById("productName");
        var productPic = document.getElementById("productPic").src;
        window.easemobim = window.easemobim || {};
        easemobim.config = {
            
            //是否隐藏小的悬浮按钮
            hide: true,
            //自动连接
            autoConnect: true,
            //聊天窗口加载成功回调
            onready: function () {
                easemobim.sendExt({
                    ext: {
                        "imageName": "mallImage3.png",
                        //custom代表自定义消息,无需修改
                        "type": "custom",
                        "msgtype": {
                            "track": {
                                "title": "我正在看:",
                                "price": "$: " + saleprice.textContent,
                                "desc": productName.textContent,
                                "img_url": productPic,
                                "item_url": window.location.href
                            }
                        }
                    }
                });
            },
        };
    </script> 收起阅读 »