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

【产品经理手册】twitter高级PM的产品经

$
0
0

chanpinjingli

PAUL ROSANIA

Twitter高级PM,2005年他毕业于Dartmouth学院计算机专业,在创办CollegeJobConnect之前他曾做过几年咨询。该项目夭折了,但他这次失败经历让他接到了一位著名的硅谷创始人的电话,这位创始人听过PAUL,他想了解PAUL是否适合加入他们的初创作为首位高级产品经理(Growth Hacker)Paul同意了,于2011年进驻硅谷,并在那里工作了一年,不久他接到了Twitter的来电;他之前成功让初创企业实现10倍增长,搬砖coding、产品战略都很行,但他觉得自己应该做更纯产品的职位,并想在大舞台上施展拳脚。所以他接受了Twitter的邀请,现在已经入职10个月了。

访谈总结

PM跟运动教练有哪些相似之处?

站在用户的角度意味着什么?

成功的产品经理必备三素质;

在Twitter做PM学到的最重要的东西;

问:在进入Twitter之前你的背景非常有意思。能聊聊你这一路是如何走过来的吗?

答:我职业生涯的早期,有点走偏了。在Twitter之前,我在两家初创做程序猿,有家是我自己创办的,我还做过三年的管理咨询。上一家初创,我首次把全部时间花在保持产品增长上。逐渐,我把时间分摊给产品管理、头脑风暴、路标规划、功能优先排序等方面,当然还有Coding。

来Twitter之后,我决定完全投入到产品管理中。Twitter有很多世界顶级的程序猿,我觉得自己能在产品层面贡献更多力量。我虽是一名计算机专业的学生,但我的热情一直都在产品上,并会想尽一切办法设计这些产品并将其上线。进入Twitter,我想要锻炼这些能力,特别是产品领导力、长远规划以及一切能让产品上线的能力。所以我决定在Twitter做PM,从促进产品的增长做起。我的职能在过去的几个月内不断演进,不只是专注于产品的增长,我开始拓宽职能做一些与公司相关的其他事情。

问:你觉得,产品经理的目标和目的是什么?在短期的产品实习期内哪些能力是最值得我们去培养的?

答:产品管理的职能在每个公司都不尽相同。在初创企业,有很多公司都把产品管理和项目管理合并到一个职能中了。也有一些公司把他们拆分为好几块职能。选择拆分的公司一般都有自己的方法在二者间取得平衡。在项目管理中, 你的首要任务是确保你做的东西能按时交付。在产品管理中, 你的目标是确定你在做对的产品,并结合公司的目标对产品功能进行正确的优先级组合,当然同时也要站在用户的一边。

在Twitter,我们一般会与技术项目经理(Technical Program Manager)协作,他们一般是跨领域的,但更接近项目经理的职能。在我们最大最复杂的项目里,我会和一名技术项目经理合作。其他项目里,我则直接行使项目管理职能。

我觉得有一点对于PM的成功特别重要:为了将产品送到用户手中去做任何事。我工作的大头之一就是去做那些能让事情办妥的脏活累活。也就是说,你得经常写邮件、代表团队出席会议blabla,任何能帮助团队顺利完成项目的事情都得去做。

曾经我有次听某人问另一人:PM职位真的重要吗?虽然,我和很多看似有不错产品感的工程师一起工作过。但如果有工程师问我这个问题,我会反问他:你愿意花所有的时间去打造一款产品吗?或者说你愿意话费所有的精力去做计划和协调吗?PM除了写代码和把控制量外,需要专注于让产品上线。

当你全身心投入到产品开发中时,你不能一直与用户保持直接接触。PM的一部分职责便是保持与产品用户的联系。在Twitter这尤为困难,你有两亿活跃用户,真的很难通过直觉或与朋友交谈就能推断出用户的需求。因为这些都不能代表用户样本。

所以提炼出正确的能设计我们产品的心理框架是比较耗费时间的,但这个心理框架却是PM的重要价值。我觉得你现在炒掉Twitter或任何一家公司的所有产品经理,几个月内产品也不会有太大问题。但接下来你就会发现,你的产品的市场关注度在下降,或是你在发布一些用户根本不关心的新功能。所以必须要有人成天盯着你的用户。而PM就是帮你干这事儿的。

优秀PM最后的一项技能,用个比方来说。PM有点像体育教练。你不直接管理球员或是跟他们谈签约。你所有的影响都是非直接的。你的成就,最后你团队的成就,都靠你自己了。如果你的队员不尊重你,那么这活儿你也甭干了。

优秀的PM总是能领导团队走向成功,尽管他们从未踏上那虚拟的竞技场。他们就是团队的粘合剂,给团队胜利的力量,让团队专注于团队目标。

对于PM应该关注的技能,我觉得有三方面:组织、沟通和思想领导力。

组织能力是成功的关键。话虽然老掉牙,但却是实话。我之前说过PM要做任何能帮助产品上线的事,其中一部分工作就是谨记那些应该被完成任务。找到能组织你的思维、问题和待完成事项的方法。我花了很长时间去建立适合自己的组织机制,而且我在不断改善。最终,我的方法使得我的上级能相信我可以干成事情,他们不需要监督我,而我的团队也明白他们交给我的事情我一定不会忘记或搞砸。

沟通会有直接帮助。作为一名PM,在别人眼里,你就是产品的全权接口。否则,别人会直接去找你的团队成员,这会分散成员的注意力并降低团队效率。最低的要求是你要能对问题有即时、清晰、简洁的回应。(大量的邮件)。再进一步,你要能将产品的中长期目标规划出路标,并向别人阐述清楚。当别人明白你要干嘛且为什么那么干之后,他们才更可能放手让你和你的团队去实现你的愿景。

思想领导力是指你对产品和行业有冷静客观的认识,并对产品未来的走向有一个清晰且饱含热情的蓝图。这貌似是最重要的能力了,但没有组织和沟通能力,你将会得到一份糟糕的领导力,以及一份没人知道或关心的美好产品规划。

问:你说“用户的支持者”是什么意思呢?

答:让我用Twitter的一个具体例子来说明吧。请想一下我们的注册流程。每位Twitter用户都能凭直觉去解释你为什么需要一个用户名。因为没有用户名,别人就找不到你的资料并关注你,也就不能@你了。但是当你和潜在用户交谈时,你会发现有些人就是不明白为什么注册流程是那样的。什么是用户名?我为什么要个用户名?

最终,你开始从用户反馈中去查找这种模式,你就发现你的用户并不像你想的那样去理解你的产品。作为一名PM,找出这些模式是你的职责。随着时间推移,这些模式会在关于用户如何理解你的产品上,形成大量直觉性的东西,那会你就会诧异:我居然能预测用户的反馈?!这就是我说的支持用户了。确保多数用户体验的质量是我的职责。

作为一名新手PM,你的直觉是未经打磨 的,但你会随着跟用户的交流而进步。最初,你找到的模式很简单:用户在跟密码纠缠。后来你发现更广度的启发式思维,网页格式千万不能太简单或太直接。你开始将这些启发式思维联系起来,并产生新的认识。经过不断重复和再造,这些启发式思维便形成了你的产品直觉基础。

问:你在Twitter做PM期间,是如何持续做到跟用户一起并感同身受的?

答:虽然有很多策略,但最重要的一点是:跟你的用户交谈。

我们在Twitter有点被宠坏的感觉,因为我们有一只非常优秀的用研团队负责保持我们与用户的联系。我基本一有时间就会扎进他们给出的研究结果。这样的待遇并不是什么好事,因为这种接触是非直接的。作为PM,将用研结果从抽象中解读出来,并把用户看成是几部分占比不同的人群应该是小菜一碟才对。

量化的数据很关键,在同使用你产品的用户真身保持联系时也同样关键。我有时候会志愿帮助别人修修电脑神马的,这期间经常就有人问关于Twitter的问题。即便看着用户做最简单的事,如登录,也是非常有意义的。很多人会犯一些常见错误,如重复输入错误的密码。在尝试了几次后,他们甚至会认为Twitter的登录功能有问题,而不会意识到自己一直在输入错误的密码。

这些都是普通的用户错误,而现场观看他们犯错的过程也是很有用的。不然这件事情感觉起来总是很抽象。我们毕竟还是普通人。

所以我认为“共情”一词较为贴切,但我也不认为你能靠共情能力去搞清楚所有的问题。

我很羡慕那些拥有纯付费用户团队。付费用户要么会高兴地给你反馈,要么会气愤地要求你给出答复。有时候听到这些抱怨你会觉得不爽,但至少他们给了你明白的反馈。但我不能寄希望从两亿用户中找出一小撮,他们就能准确代表庞大的用户群体,我从不认为这样做有很大作用。所以我在理解“普通用户”上有很大的困难。这才是我们的用研团队真正的用武之地。他们用能准确代表大量用户群体的方式,针对各种问题进行各种规模的用户研究。

问:如果你在Twitter做PM时有学到最重要的东西,你觉得是什么?

答:我过去,在知道别人会怎么回答的情况下,仍会经常问别人某些问题。或者我在交付某物时后脑勺总会发麻提醒我说:是不是有啥东西漏掉了?比如,有人问我项目接下来要干嘛,我会写封邮件分条列出,即便在我按下发送按钮时我就知道他们的第一个问题是什么,但我也不会把他们的疑问写进邮件里,这或许是因为懒惰吧。如果我预测没错,他们就会来问那个问题。那时你就会想:擦,我是怎么知道的?nnd我怎么当时没回答它?

在职业生涯前期我经常遇到这样的事,但自从做了PM,我才明白我要从根本去解决这个问题。对于PM来说,这是致命的失败。你确实需要认真解决它。当你或别人在做某事时,你就是那个留意那些未完成工作的人。不然,你到时候职能交出一个A-级的产品。你会打心底里明白它是个A-级别的产品,也就只会有A-的表现。作为一名PM,那是不可接受的。钱在你那里打了水漂。

如果你的产品很逊,你不能指望有人会帮你指明方向。你被招聘过来做一名决策者,其他人甚至不需要知道该问什么问题就最好。(因为所有的问题你都应该考虑和解决)

问:你在Twitter做PM的职责有哪些?

答:我之前说过:组织、沟通和思想领导是要培养的重要能力。这些也是Twitter的PM核心职能的一部分。

勤奋是每位PM的另一项职责。你的产品是你本人和你付出的写照。这意味着你对待自己、团队和工作要实诚(有时甚至需要苛刻一点)。一名优秀的PM想做正确的事,即便那样做可能会比较痛苦。也就是说,多做工作并向自己和他人证明你的产品和你想象的一样棒,你的愿景是正确的。

对我来讲, 这种级别的勤奋并不是先天的。每天会发生很多事情让你的大脑过载。我很快意识到我不能试图把每件事都记在脑子里。有那么几次我忘记了别人要我做的事,或当我步入会议室才发现对于我想要说的并不像我想的那样准备充分。

现在,我会记下所有的事情,即便我准备马上做这件事。一些简单任务,我使用Mac电脑上的Things应用来记。当我遇见别人,我会用Evernote记下我们谈话的内容。这样,我再不会忘记要做的事了,也不会忘记跟团队成员的谈话内容。当我有一个产品idea时,我会在相应的项目Google Doc里记下来。这些工具把我的脑子从记事中解脱出来了,使我能够专注于组织和计划。

我还发现书写帮助我保持诚实:有时候想起来很酷的点子文字解释起来却不容易。那表明你的思考并不完善。

最后我要说的是,作为PM,你对你的时间没有完整控制权。你经常要辗转于各种别人的会议、邮件和问题中。你很想反抗,但这些障碍确实就是你工作的一部分。你要清楚的认识到某个会议是否重要,但也要意识到你度过了充满干扰的一天,却为你的团队排除了干扰。(有时候那些会议可以帮助你搜集信息并调整你的产品规划,这能让你关注到正确的目标,从长远来看也是省时间的。)

如果你觉得有点扛不住了,不要害怕腾出时间来做长时思考。当我很忙时,我会在一周的几天中留出1-2小时的时间,以确保我有足够的时间去思考。你需要时间去整合你的思维,如果你自己不预留这些时间,别人就会占用它。

问:我能用python和r编程,但却没有我听过的其他PM那么扎实的开发经验。作为一个有点技术背景的人,我能做些什么来弥补呢?

答:很强的技术背景对于你做PM有两方面好处:

一,它能帮助你与工程师建立良好的关系。如果你能接地气地干活,他们则更愿意相信你做决定时会真正考虑到他们,而不是在哄他们。而且你在向他们描述你想要实现的功能时也不怎么会说错话。

二,很强的技术背景帮助你更好的去评估成本,这能使你觉察到激发团队能力的时机从而让你的团队更优秀。当你跟一支真正优秀的团队工作时,你知道怎么去激发他们,大家都会成长,你的团队,你的公司和你自己都能从中受益。

所以,为了弥补经验的欠缺,集思广益一些方法如:找机会去“黑”一个项目,最好是跟你的团队一起写代码。在Twitter我们每个季度都有黑客周,那对我来说是一个向团队展示我的能力的好时机,也是一种锻炼。

问:我比较担心我刚进公司三个月不能有太大影响力。我想学很多东西,我知道我会学好,但我想表现自己的影响力。你的PM头3个月时怎么度过的?如果重来一次,你会做些什么不同的事呢?

答:我立马就动手表现自己了,我推荐那样做。在Twitter,我们一直在寻找那些内容充实的实习项目,就是那些能让实习生独立负责完成的项目,且要能在他们实习的三个月内能够发布。此外,这些项目都是正式的。不是练手或赶工项目。

你的公司提供这样的机会最好,但如果他们没有那样做,那么请告诉他们。你也许确实没有机会展示自己的影响力。但你一定是有影响力的,在Twitter我见过很多实习生做出一些有影响力的事。一定要确保你做的是一个能在你离开之前发布的正式项目,当你离开后也才能拿出来说说。

问:你在看待一款教育类产品是都有哪些心理标准?换句话说,你在评判一款产品有多成功时会有哪些标准?

答:我对教育软件了解不多,但我可以说点通用的标准:做用户喜欢的产品。与他们交谈,聆听他们的反馈。从用户的角度去清楚、直接地描述你正在解决的问题。将任务细化。专注于更重要的项目。上线发布。

我特别推荐Marty Cagan写的Inspired。这是一本适合快速阅读的书,他会为你在学产品开发时提供一个框架。

问:经常有人建议我在做PM之前应该先去做份技术工作,因为在做了PM后很难再转回技术(代码、设计等)。你怎么看这个建议?一毕业就去做PM好还是先做个一般工作再转PM好?

答:我收到的最好的职业建议是:你做其他的事对于你想做的事来讲没有任何好处。做你喜欢的事。少去担心假设中的职业转换。如果你的热情就在产品管理中,你是不会离开这个职业的。

这个社会很需要优秀的程序员和设计师。如果你要转做这些职位,你也能找到工作。

原文: The Product Manager Handbook(包含了十名国外著名PM关于一些产品职位的问答,该系列文章将持续更新)

本文由Tobbi翻译投稿,转载请注明出处并附带本文链接

系列文章导航

【产品经理手册】如何搞定产品经理职位(五)

【产品经理手册】如何搞定产品经理职位(六)---微软SEAN GABRIEL

【产品经理手册】如何搞定产品经理职务(七)--如何成为出色的非技术pm

您可能也喜欢:

【产品经理手册】如何成为出色的非技术PM

【产品经理手册】产品经理问答-微软SEAN GABRIEL

【产品经理手册】如何搞定产品经理职位2

【产品经理手册】如何搞定产品经理职位3

【产品经理手册】如何搞定产品经理职位4
无觅


(关注更多人人都是产品经理观点,参与微信互动(微信搜索“人人都是产品经理”或“woshipm”)


移动互联网用户痛点调查

$
0
0

  一款产品的成功往往来源于对用户真实需求和场景细节的深刻理解。比如,QQ诞生初期之所以击败了更早流行的舶来 品ICQ,正缘于其一项关键性创新:ICQ当初将用户资料、好友关系等数据都保存在客户端即电脑上,但在2000年前后的中国,用户上网环境多为网吧,一 旦换台电脑所有好友就消失不见了,而QQ作出的改变就是将所有资料保存到服务器上,让用户无需再担心这一点。

  现在看来,这是个非常容易得出的洞察,不是吗?但轻易得出的事后总结往往忽略了那些真正在背后起作用的因素:产品经理对未知世界的好奇心,对那些看似不起眼细节的敏锐捕捉,等等。从一线产品经理的独特视角,深度观察三四线地区用户对于移动互联网的需求痛点。

  优秀的产品经理往往比普通用户对产品本身更加敏感。他们多数会体验更多的应用,也善于从散布的案例中归纳出用户潜藏的呼声。作为产品的运营和设计者,他们又有渴望、有激情、有机会将自己对产品的体察,将既有产品不完美或者未能解决的问题的感受融入到自己的产品中。

  以下是他们从实践中得来的一些观察:

  流量。网络质量不好,流量费高,WiFi不普及成为产品经理共同的心声。

  公开数据显示,网速方面,中国的世界排名在80名开外。工程院院士邬贺铨表示,截至2012年底,中国的互联网 干线固网平均下载速率为1.15M(网络传输速度单位),而香港特区为10.5M,整个亚太或全球平均的速率为4.64M。比起一二线城市随处可见的 WiFi作为用户流量的补充,在三四线城市,流量是移动互联网用户的最大制约。他们对流量和资费的在乎,比一线城市用户要高。

  用户对隐私泄露的担心以及引发的不信任感。2G时代的手机安全问题,如病毒威胁、隐私泄露、骚扰 短信等在3G时代已然没有解决。随着智能终端的普及,更多不法软件暗吸用户流量、暗扣用户资费的现象愈发猖狂。在有更多小白用户的三四线城市,这些现象更 为严重。快捷酒店管家产品运营和设计负责人朱坤认为,中国的网民在Web时代和SP时代完全被吓到了,以至于现在通过移动互联网让她们产生信任相对困难。

  内容的获取问题。这其实对于一线的白领用户并不成问题,但对于三四线城市的用户却是掣肘之一。在 虾米音乐无线事业部经理稻草看来,人们的核心内容需求是用户发现自己喜欢的内容,并能够在网络环境变化时能流畅地消费内容,比如视频、音乐等。对于更倾向 于用完整时段而不是碎片时间的三四线城市用户而言,在网络不好,没有WiFi的情况下很难大规模获取。

  痛点还有很多。比如电商方面的物流和支付,已经享受着当日达甚至一小时送货的北上广深用户可能很难接受需要用七八天的时间等待一个包裹的到来。当北上广深用户轻敲几个按键实现快捷支付时,同样从网上购物的三四线用户用着最原始的一手交钱一手交货。

  这样说或许有些矫情。因为照这样想下去,痛点或许数出无限来。我们更关心怎么去解决这些问题。

  移动互联网的产品设计者在带着镣铐跳舞。

  省流量成为问题的关键之一。快牙直接做移动端的分享,天然为省流量而来。专注做三四线城市电商欢购网选择图片压 缩在8K以下,以期省流量流量以及提升加载速度。快捷酒店管家做在做省流量的努力。当然,不止受访的产品经理们的产品,省流量几乎成为所有移动互联网产品 的标配,但这种努力无止境。

  稻草说,如何缩短用户将音乐放入手机的路径是产品经理反复思考的问题。尤其是在没有网络的环境下,用户如何能同 样有选择性地听到自己想听的歌曲。他说,现在不少产品采用二维码、音乐识别或基于音乐算法的缓存问题来提高音乐进入手机的效率问题,但目前还没有找到真正 好的方式。因为没有解决内容获取的问题,在广东东莞,那些打工仔们还在小店铺排队拷贝视频和音乐。这也成为一门生意。

  移动应用多过百万级,真正进入手机的应用不过百个。比起挑剔又容易兴趣迁移的一线城市用户,三四线城市移动互联网用户的需求一直真实而旺盛的存在,不断地发掘其需求,解决痛点问题,才能找到自己的应用的价值。

  这似乎有些老调重弹。在移动互联网环境发生剧烈板块震荡过程中,不太被瞩目的三四线城应该成为移动互联网应用重新整合资源建立商业价值的绝佳地点。

  典型痛点:运营商和用户习惯

  网速方面,中国的世界排名在80名开外。运营商的垄断也使得移动互联网的使用很痛。

  在现阶段,移动互联网给用户带来的还是娱乐、消磨时间的功用,并没有真正的渗入到用户的生活中去,发挥更大的作用。大部分用户不觉得移动互联网好用,也不习惯在手机上解决问题。

  详细案例:移动酒店预订:尚未真正渗入到用户的生活中 (作者朱坤,快捷酒店管家产品经理)

  典型痛点:流量不够用

  首当其冲的是安全问题,尤其是吸费,对用户造成了最直接的经济损失。大量的预装应用对于初级智能手机用户而言还带来不小的使用障碍。

  将会出现很多从功能机转化过来的新用户,而他们以往并没有使用智能手机的经验,系统或应用操作的复杂性便是摆在他们面前最主要的困难。

  详细案例:不完美的智能手机:陷阱和学习成本让用户却步(作者李楠,魅族移动互联网高级总监)

  典型痛点:支付、物流、流量

  三四线城市用户很少开通支付宝、财付通,银行卡普及率不高,用户采用货到付款较多。

  一二线城市一两天到,三四线平均7-8天送达。

  电子商务客户端以呈现图片为主,流量耗费多少将影响用户的选择和停留时间。

  详细案例:移动购物:15%的订单送达后找不到人(作者张小玮,买卖宝CEO)

  典型痛点:流量、内容和配置

  相对智能机的普及,网络、带宽包括成本相对来说没有那么普及。

  有大把的空闲时间,反倒出现内容枯竭的困境。

  多花一千多元换一个好一点的手机,对于农民工来讲还是一个比较贵的成本。

  详细案例:移动分享:时间不是问题 多花钱让用户反感(作者朱燕晨,快牙公司高级副总裁)

  典型痛点:没网络怎么听歌?

  三四线城市等车的人,手机就是手机,他们打电话或发短信。他们更在乎流量和资费,所以对手机的使用还停留在最基础的阶段。

  如何缩短用户将音乐放入手机的路径是产品经理反复思考的问题。尤其是在无网络环境下,用户如何能同样有选择性地听到自己想听的歌曲。

  详细案例:移动音乐:用户对音乐消费的需求参差不齐(作者稻草,虾米无线事业部经理)

  典型痛点:视频中介活跃

  三四线城市的用户在操作手机的时候,很多人都知道可以上下滑动页面来查看更多内容,但是很少知道可以左右滑动。

  在东莞,有很多小店铺提供视频导入服务,工人可以选择需要哪些视频或者音乐,然后店主就会把视频导入到工人的手机里,并收费。

  详细案例:移动视频:用户愿意付费 钱却让中间商赚了(作者豌豆荚产品经理)

  典型痛点:对体验更敏感

  移动网络不好,WIFI的覆盖也并不完善,受到的影响也更严重。一些在一二线城市非常流行的游戏,往往在三四线城市得不到较好的推广。

  玩游戏基本靠可信任的广告与朋友推荐,如果游戏上手比较慢,操作不人性化,在这些用户当中更难推广开来。

 

来源:HTML5中国

财务分析及价值投资精华总结

$
0
0
财务分析及价值投资精华总结
2014-05-05 老虎投资汇

第一部分:财务指标分析
财务分析时,要综合分析企业在各个时期的情况,这样才会知道变动情况。
一、净资产收益率
净资产收益率的高低关系到资本的累积速度,是最重要的财务指标。例如:拥有25%净资产收益率的企业,在盈利不变模型中,4年就可以将股本权益翻番, 10%则需要10年!
此项最好在15%以上,最佳区间为15%~25%。
不要考虑小于10%的企业,除非①处于周期性行业低谷;②因股东权益的变动而被摊薄(增发,配售等);③正在筹建部分项目,尚未产生收益。等等
大于30%的要小心,因为大于30%的净资产收益率往往是不可持续的,此时买入无疑是出了一个过高的价格。因为高的利润率必然吸引竞争,除非企业有强大的优势将潜在竞争者排挤在门外。
注意以下情况可能导致净资产收益率的扭曲:
1、行业:是否因为处于垄断行业而取得如此大的净资产收益率?而这种垄断处于哪种类型?通常完全垄断的企业(如电力、通信、高速公路、石油等)要受到国家的管制,因此要小心政策风险。
2、负债率:因财务杠杆过大,放大了收益(或亏损)。高负债率同时意味着高风险。(高的财务杠杆同时放大了收益和亏损,而且有财务成本和还款压力。)
3、一次性收益:包括投资收益、追回往年已作坏账减值准备的坏账、出售资产、财政补贴(包括连续性的财政补贴,它将面临政策风险。)
4、资产价值低估(或高估):使得账面资产价值与实际资产价值偏离。(可因此寻找隐蔽资产型企业)。通常是一些资本型企业,如房地产、高速公路、机场、港口等)
5、会计折旧方法:以前时间里过度加速折旧,使得目前的账面资产价值以及成本与实际严重不符,等于把以前的收益留到现在来用了。
6、周期;同时注意经济周期和行业周期。周期性行业往往是那些投资大、建设周期长,以及生产耐用品的企业,如造船、航运、汽车、钢铁等。
7、财务造假:分析同行业其他企业的盈利情况,做比较。如果找不到企业能产生如此高收益的理由,则宁可错过也不投入。另:关注现金流量表。
8、股东权益的变化:增发,配售等。
二、市盈率
在稳定盈利前提下,要求一个8%的必要收益率,20%的收益增长率(高于此则是一个风险很大的增长预期),以去年收益为基准,则得到以下一组参考数据:
市盈率倍数

≦9.1
13
15.6
18.7
22.5
27(27刚好是13的两倍)
13*70%
去年
今年
明年
后年
第三年(即行情不好时也可三年解套)
考察市盈率一定要和历史水平相比较。
同时考察:付息率VS一年期银行利率。
 注:此为简单模型,未考虑宏观经理及行业差别。简单理解如下:今年四月份公布年报,计算去年业绩的市盈率为13倍,则收益率为7.7%。在此基础上打7折,得出9.1倍市盈率,视为低估值的买入点。按今年20%增长率计算,得出如果按去年业绩的15.6倍买入,今年动态市盈率仍为13倍。15.6倍市盈率为最高价值投资买入点。再往上,为投机点位,27倍为投机最高点位,也是长线投资的卖出点位,它意味着按20%增长速度,三年后方可达到13倍市盈率水平。
为什么选取20%的增长率和8%的收益呢?因为20%属于稳定值,超过这一数值可能变得不稳定,也算是保守的算法。8%的资产回报率,算是社会平均投资期望回报值。理论上说,回报率高于银行贷款利息(即财务成本),那么追加负债是有利的。
 以上模型适于过往五年平均利润增长率超过20%的股票。
三、总资产收益率:
≧5% 或 ≧一年期银行贷款利率(也可适当参考公司债券利率)
如果息税前总资产收益率小于一年期银行贷款利率,说明公司至少可以通过减少负债来获得更大的收益。
四、市净率。 ≈1 ≦2
1、 市净率过大可能导致大股东或早期创业的股东减持。
2、 市净率大时分红对股东不利。(本来溢价的,可以计入净资产的未分配利润,现在按照不溢价的价格分给你了,而且还要扣税。)
3、 检查一、净资产收益率中谈到的扭曲。
4、 是否有极大的未计入的无形资产(包括品牌价值),或隐蔽资产,或已升值(被低估)而未计入会计项目的资产,来支撑较高的市净率。
五、市销率
对于盈利不稳定的公司,市净率和市销率往往比市盈率更加有效。(尽量选择稳定增长的公司。)
市销率 = 每股价格/每股销售收入。
如果市销率 = 1,没有盈利。那么,在盈利好的年头里如果企业能有10%的净利润率,则那时市盈率为10倍。
六、财务杠杆(负债率) ≧2:1时风险大
要根据经济周期,行业周期,利率周期,企业的扩张周期来判断财务杠杆是否合适。
高的财务杠杆在好的年头放大收益率,在坏的年头则放大亏损。高的财务杠杆意味着高风险,对于周期性行业要特别小心。
负债率低的企业在行业低谷时更有优势。(因为其财务成本低。)
七、流动负债和长期负债的区别
流动负债是马上要还的,而长期负债不必。同样是负债,同样算在资产负债率里面,但要区别对待二者。
破产不是由亏损导致的,而是因为不能偿还到期债务。流动负债更容易导致破产,因为长期负债一般是有计划的,而且可以通过新债换旧债的方式解决,而流动负债可能因为一些突发事件,在到期日当天周转不了。
有的公司流动负债很多,甚至超过长期负债,要小心。
八、应收账款
应该密切注意此项目。结合行业情况来分析,与同行其他企业对比。过大或过小都不是好事。当应收账款大于公司半年净利润时,即使其他财务项目再好,也不应该买入,宜继续观望。
要与历史情况作对比,观察各期应收账款/销售收入的变化,比较应收账款增长率VS
① 销售收入增长率
② 利润增长率
③ 坏账准备增长率
九、净利润增长率(可以为负)
最好稳定,波动较大说明企业正遭受竞争者激烈的攻击。
十、预收账款
此项越多越好,说明产品畅销。
十一、应付账款、应付税金、短期借款
结合流动比率、速动比率,考察短期还款是否会出问题。
十二、存货
存货占用资本。对于商业,如零售,贸易尤其重要。考察:
① 存货周转率
② 总资产周转率
③ 净资产周转率
④ 存货上升速度VS销售收入上升速度
十三、分红率
分红是“是否再投资”的矛盾。但有一点注意:
分红率高至少证明公司账面上的盈利是可以拿出来分的,这样财务造假的可能性大大降低。
十四、管理费用
管理费用/销售收入,管理费用/净利润可以考察公司的管理是否具有规模效应。
由于规模效应,盈利大幅增长时,管理费用应小幅增长。(如不增长则损害管理人员积极性)。而在盈利状况乐观的情况下管理费用上涨幅度超过盈利增长幅度,那么要怀疑管理的效率以及管理层的素质。
十五、现金流量
现金流有问题,而同时负债率很高,是很危险的。
经营活动所产生的净现金流
了解企业在不动用外部筹得资金的情况下,凭借经营活动所产生的净现金流是否足以偿还负债,支付股利,对外投资。
十六、税率
可以是优势,也可以是风险。
十七、费用资本化
小心费用资本化,这样会把费用摊薄到未来几个年度,而使近期的利润增加。

第二部分:经营
盈利增长来源:
1节省成本创造的盈利增长是不可持续的。
2销售收入的增长才可靠,可以通过以下途径实现销售收入增长:
① 销售量增长(抢占市场)
② 提价
③ 开发和销售新产品。
④ 并购。
3税收政策及补贴政策的变动。
竞争优势(企业依靠什么把竞争者阻挡在外)
1、 成本
2、 专利或技术
3、 垄断经营(包括特许经营)
4、 锁定消费者(大的转换成本,如word)
5、 规模效应(如快递业的网络。)
6、 管理效率。
当某个行业利润率丰厚时,将可能导致资本流入,竞争加剧,盈利降低。除非企业能有效将竞争者挡在门外。(类似垄断。)否则任何行业都有可能昙花一现。
竞争激烈的行业意味着企业盈利空间小,同时风险大。(也可能是周期行业。)现象:当某个行业大打价格战时,往往就是“竞争激烈”!
多元化和并购
多元化必须产生协同效应才是成功的(和主业相关,有利主业发展,如有利于减少中间交易费用、谈判费用;减少风险的纵向一体化。)。踏入陌生的行业是失败的多元化。最忌经常变换主业,专注才能做强。
回避过度并购的公司,并购大部分是失败的。即使它一开始盈利丰厚,也可能在突然的一天倒闭,因为并购通常要用到较高的财务杠杆。
有时并购是经理人为自身利益而做出的。(如提高薪酬。)
大股东素质
主要考察:
1、 关联交易
2、 担保
3、 诚实
管理高层主动辞职
高度关注。因为在企业前景乐观时,不会有哪个高层主动辞职的。除非迫于压力。
会计审计
关注会计审计意见,规避经常更换会计事务所的公司。(造假账的可能性大)
警惕“消息”过多
要分析消息的影响力,可靠性。警惕“消息”过多,往往好消息铺天盖地放出来,股价在出消息前已涨,出消息后仍将上涨一段……属利多出尽。
特别是上市公司给出不实际预期(与同行业比较),称未来能如何如何大幅发展的。这与此相悖:管理层往往设定保守的目标,以便超额完成时得到奖励。
例子:蓝田股份。
成长性
找到公司不断快速成长的理由,如果找不到,就不要买他。
公司大小往往影响到成长性。如宝洁的利润要翻番很难,这需要全世界的需求大幅增长。而一家小的洗化品生产厂只要夺取宝洁的一丁点利润,就可能翻番了。
招股说明书
很重要,一定要看。
行业周期
“虽然大多数人口袋里缺钱的时候,麦当劳仍不乏顾客。可是谁会急着买一辆新车呢?”
行业低谷时往往是检验优质企业的好时候,而这时股价往往又相当便宜。(如中集集团)
在行业低谷时,其他企业都在亏损,而这家企业能够保本或盈利,则证明其竞争力较强。(特殊情况以及财务手段处理除外)
替代品
最致命的竞争者往往不是生产同样的产品的企业,而是生产替代品的企业。
制造成本更低,性能更好的替代品尤为致命。
企业生产的产品不具备替代性最好。
分析筹集股本资金的用途
①扩大生产 分析产品供需(是否过度投资,如钢铁)、增长率来判断是否合适。
②改善财务状况,还债。 避开
亏损
不投入长期亏损的企业!优秀的企业即使行业不景气,仍领先于业内其他企业,因此不可能长期处于亏损中。(因为不可能整个行业都长期处于亏损中,必定有部分企业被淘汰。)
不投入创业初期的企业!(你不是VC!)
第三部分:操作
不要在意短期股价走势
下跌是低价买入优质公司的好机会,越大的下跌越让人兴奋。
最后,记住一句话:“耐力胜于头脑”!

  青春就应该这样绽放   游戏测试:三国时期谁是你最好的兄弟!!   你不得不信的星座秘密

D-Link推出DSP-W215 Wi-Fi智能插座 可追踪家庭能源使用情况

$
0
0

作为知名网络设备制造商的D-Link,现在竟也通过Wi-Fi智能插座而进军智能家居市场了! 这款WiFi Smart Plug的型号为DSP-W215,它不仅可以远程控制接入的设备,还能够监控其功耗。配套的应用支持iOS和Android平台,而用户可以自由选择搭配接入空调、点灯、电视,或者提防潜在的过热情况。

正如其名,这款WiFi智能插座支持WPS一键设置,以便于用户的安装和使用。此外,你也可以通过应用程序设定开/关的时间,或者在过热时自动切断电源。

至于DSP-W215的能源追踪功能,则类似于贝尔金(Belkin)的 WiMo Insight Switch。D-Link WiFi Smart Plug现已上市,售价为49.99美元。

[编译自: SlashGear]

Chrombook!你别逼的太紧

$
0
0

30_1jqnjkDgZ

亲爱的用户们,你们可曾想过,花费$199就能享受一台移动办公的笔记本?在此之前,这放在Chromebook上似乎很平常,但是现在微软正在证明Windows 8.1笔记本同样也能以极具吸引力的价格卖出。微软周一在官方Windows博客中公布以$199的价格发售11.6英寸的华硕X200-MA触控屏幕笔记本,在短短几个小时内三款型号(黑色、白色和蓝色)都已经售罄。

今天早些时候,宏碁为旗下的Chromebook C720P升级了配置,搭载英特尔第四代Core i3处理器,意味着性能更加强劲,处理效率大大提升,价格方面虽然比原来贵了100美元,但是性能上的改进似乎足以麻痹用户对价格的敏感。另外,英特尔公司还公布了自己的Chromebook计划,表示未来会面向教育市场。

OEM厂商们,你们到底想些什么呢?

lenovo-n20p

随着XP的告别舞台,Chromebook出现在用户视野中的几率似乎大了不少。前不久,已有相关媒体报道过联想已经开始延伸到了Chrome OS阵营,并且发布了两款Chromebook新机:N20和N20p。这是继三星,宏碁,惠普之后Chrome OS阵营中的第四家OEM厂商。

非常有趣的仍然是售价,N20的售价为279美元,大概1750元人民币,N20p的价格为329美元,大概2050元人民币。N20p会在6月份上市,比N20早一个月。

我们知道联想算是全球最为重要的OEM厂商之一,无论是联想加入Chrome OS阵营,还是英特尔准备推出面向教育市场的Chromebook,微软似乎都看在眼里。低端入门级市场对Chromebook来说非常有吸引力,加上Chromebook如此亲民的定价,看来微软是真的被逼急了。

source: The Verge

它第一个走出谷歌试验室 欲改良建筑业

$
0
0

它第一个走出谷歌试验室欲改良建筑业

从谷歌的 Google X 试验室分拆出来的第一家初创公司 Flux 终于从幕后走到台前,它在本周二推出了一个早期版本的数据驱动型设计软件产品,希望利用软件和数据来增强建筑物的可持续发展性能。

Flux 是两年前从 Google X 试验室分拆出来的第一家初创公司。Flux 的联合创始人米歇尔考夫曼(Michelle Kaufmann)称:“现在的建筑流程太陈旧了。”

考夫曼是一名专注于设计预制建筑和可持续发展建筑的著名设计师,她和公司另外的 3 名联合创始人都是软件工程师,她们开发出来的软件可以将与新建筑的要求有关的数据与各种数据点结合起来并创建算法让建筑开发商和设计师得以合作,有效地输入新数据并精简建筑流程。这款软件还可以帮助开发商和设计师现场作出可持续发展的决策。

考夫曼和联合创始人珍卡莉莉(Jen Carlile)希望改良整个建筑行业,这不但对这个行业里的公司有利,对整个世界也是有好处的。建筑行业消耗了美国将近一半的能源。掌握了更多的数据之后,建筑开发商和设计师就能将建筑物建造得更加智能,同时减少建筑过程中和运营过程中消耗的能源。

Flux 已经完成了A轮融资,从 DFJ、Borealis Ventures、谷歌投资公司和安德森霍洛维茨等投资者那里获得了 800 万美元投资。考夫曼表示,Flux 将把融资所得资金用于软件开发和招募人才。Flux 现有员工 20 人。

Flux 的软件产品可能要等到 2015 年初的时候才会公开发售。目前它已经在某些城区承建了一些项目,但它不愿透露更多的信息。

Google X 试验室中的大多数创意都在研究和讨论阶段被推翻了,只有极少数量的创意比如无人汽车和谷歌眼镜实现了商业化。某些创意依然处于研究之中,还有极少数的创意被分拆出去。

本文链接

中国电信推“添益宝” 年化收益率最高7%

$
0
0

中国电信推“添益宝” 年化收益率最高7%

近日,通信运营商中国电信也宣布推出一款名为“添益宝”的理财产品,该产品是翼支付联合民生银行,向高级实名认证用户提供的一种余额理财服务,其年化收益率可达5%~7%。“添益宝发挥了传统运营商的特色,一方面可替用户赢得收益,另一方面理财收入可直接用于支付通信费。”中国电信翼支付方面介绍道。

值得注意的是,目前余额理财产品年化收益跌破5% 已无悬念,监管层拟要求其缴纳存款准备金的传闻也甚嚣尘上。那么,像中国电信这样的机构为什么仍然选择进入余额理财领域呢?

对此,银率网理财分析师牛雯指出,现在正是余额理财市场“跑马圈地”的时代,今后还会有更多的机构进入余额理财这个领域。

年化收益率可达5%~7%

去年 6 月诞生的余额宝,不到一年时间规模就已突破 5000 亿元,参与人数更是超过了有 20 多年历史的股民数。而 5 月 5 日腾讯财付通总经理赖智明亦对外宣布,腾讯旗下理财产品理财通目前吸纳的资金规模已经超过 800 亿元,理财通上线至今已经有 110 天左右的时间,以此计算每日流入资金量平均可达 7.27 亿元。

正是在余额理财市场快速成长的背景下,近日,记者注意到,传统通信运营商中国电信也推出了一款名为“添益宝”的理财产品。

据了解,“添益宝”是中国电信翼支付联合民生银行推出的理财产品,由中国民生银行发起购买汇添富货币基金,其年化收益率可达5%~7%。该产品主要通过民生银行直销银行“如意宝”产生收益,其将支付账户和理财账户进行整合,面向所有用户开放。同时,用户通过“添益宝”理财收入可以抵消通信费,还可再获赠 4GB 流量,有效期为 3 个月。

“添益宝的优势在于 3 个方面:首先,存入翼支付账户的资金不仅可以随时消费支付,还能获得收益,非常灵活便捷,可以说赚钱花钱两不误;其次,无需认购、账户余额自动理财;最后,全天7×24 小时随时充值、随时消费。”中国电信相关人员指出。

牛雯向记者指出,这预示着中国的通信运营商也加入到了余额理财的大军当中,不过该产品主要通过民生银行如意宝产生收益,而民生银行的如意宝主要挂钩两款货币基金,因此,中国电信的添益宝产品本质还是投资货币基金。

北京君德财富投资管理有限公司首席分析师袁建明也对记者表示,主要是因为中国电信翼支付一直做得不错,再加上有大量的客户沉淀资金,而客户又有对这部分资金管理的需求,添益宝推出之后可以增加用户的粘性。

数据显示,2013 年,中国电信翼支付业务交易额突破 1500 亿元,个人账户用户数突破 5800 万,增长了 242%,企业账户数达到 12.6 万,商户达到 4.5 万家,增长了 263%。中国电信还先后推出了新的支付产品,从常见的公共交通支付到水电煤气、加油、零售商户甚至新型的互联网彩票等均有涉及。

“跑马圈地”时代刚刚开始

“余额宝之后,各大机构去争夺余额理财市场的趋势暂时是挡不住的,它会倒逼整个金融市场的利率市场化。未来,仍将是银行占据主要地位,因为客户存活期储蓄的目的还是用于日常消费购物,而银行在消费支付功能方面具有先天的优势。此外,第三方支付机构也有可能把余额理财做大。”王乐乐向记者指出。

袁建明也对记者表示,余额理财一定会依托于消费支付环境,即需要在消费行为中去获得沉淀资金的收益,所以理财与支付对接比较融洽的平台会走的更长久些,如果脱离了这种消费行为和支付环境,完全为了理财而理财的产品,其竞争力可能会比较弱些。

值得思考的是,伴随银行、第三方支付、通讯运营商的加入,未来余额理财格局会如何变化?哪些余额理财会真正坚持下来?

牛雯向记者指出,余额理财市场“跑马圈地”时代刚刚开始,现在还远未到达“大浪淘沙”这个阶段。但就现在的发展趋势来看,可以预见,大概有三类机构能在这场余额理财市场的圈地运动中占据优势。

首先,理财与支付对接比较融洽的平台。因为这类平台既可以源源不断地提供客户资源,又随时可以将资金用于消费,省去了中间环节的时间损耗。

其次,具有垄断性质的企业,这类企业的垄断特权使它们拥有粘性超强的客户群体。

第三,那些有着广大客户资源的平台无疑会更加持久。虽然这类平台没有集理财与消费支付于一身的优势,也没有垄断性企业的强大客户粘性,但这类平台能够以“量”取胜。这类平台在余额理财市场的跑马圈地中会辛苦一些,前期投入较高,但如果势起则前途不可限量。

分析师:余额理财将成趋势

其实,马年以来随着资金面的逐渐宽松和银行间同业拆借利率的回落,“宝宝军团”收益率也随之大幅下降。公开数据显示,截至昨日(5 月 6 日),余额宝七日年化收益率为 5.022%,理财通则为 4.818%,现金宝为 4.945%,百度百赚为 4.791%。由此可见,收益率破五已无悬念。

同日,大智慧阿思达克通讯社更是引述一位接近央行的权威人士称,(央行)要求(余额理财产品)交存款准备金的态度已明确,只是缴存比未定。

面对余额理财收益率的下降和监管政策的趋严,支付宝等一些较成熟的机构正陆续将目光瞄向定期理财产品,如阿里一号,京东 8.8 等。但是,近期依然有不少机构仍在积极进入余额理财领域,如中国电信“添益宝”、汇付天下“生利宝”等。

“目前来说,即使这类产品的收益在下降,但也还维持在4% 以上;其实这类货币基金吸收的是活期资金,活期资金的成本是非常低的;存款没有利率市场化之前,利差动力始终存在。而活期资金如何盘活,是各大机构都在思考的问题。只要有沉淀资金的地方,都会有货币基金的发展空间。”华泰证券基金行业分析师王乐乐向记者指出。

袁建明告诉记者,任何一个企业,只要手里有大量的客户沉淀资金都会去推余额理财,因此举可以增加用户粘性,所以做余额理财将会成为一种趋势。

牛雯亦向记者分析指出,余额宝的贡献之一就是将余额理财这个概念推向了理财市场的前沿。其认为,虽然余额理财已经被市场炒得沸沸扬扬,但其实这一领域在国内依然有非常广阔的发展空间。可以说,现在正是余额理财市场“跑马圈地”的时代,今后还会有更多的机构进入余额理财这个领域。

本文链接

【How-To】5步创建高性价比的中小企业内容营销计划

$
0
0

编译:梁策

在这篇文章中,你可以学到:

  • 当你想要进行有效的内容营销时,选择营销策略至关重要
  •  如何在选择内容营销战略时节省成本却不影响其效果
  •  如何制定预算和计划,以及如何监测内容营销活动是否成功

已经有足够多的企业通过内容营销取得成功,内容营销策略值得每个企业家思考——即使是最谨慎的商人也不例外。然而,进行出色的内容营销需要相当多时间和资金上的投入,因此对于资源有限的中小企业而言,这确实是一步险棋。

但是,成功的中小企业都明白,想要获得成功就需要承担风险并进行大量实际工作。如果在内容营销战略的选择上深思熟虑一番,你可以找到事半功倍的捷径。

下面是一些绝对不能忽略的内容营销方法步骤,但是不要忘记开动你的脑筋,在其中寻找适合自己的省钱之道!

第一步:确定预算

在你知晓自己能做什么之前,你必须确定自己愿意投入多少。这不仅仅关乎资金,在制定预算时还要编入你能够投入的时间。基于你和你的员工们的可用时间以及团队的力量,确定利用多少团队内部成员来完成多少任务。如果你的团队中有不错的写手,那么你就有了一个不错的开始。现在你要做的就是v减少他们的部分职责,使得他们有时间专注于内容开发。

节流小贴士:如果你能为你和你的员工制定时间预算表,编排你们能够用于内容营销的时间,你就可以节省外包和雇佣新员工进行内容开发带来的成本。

当然你也要注意不要把新的任务加给早已不堪重负的员工。要么减轻他们进行其他工作的负担,要么通过增加福利待遇使员工愿意加班。

第二步:制定营销战略

制定营销战略是整个过程中至关重要的一步,但是很多企业都忽略了这个步骤。战略制定的过程中,你需要做到如下几点:

1、在内容营销活动中,你的目的地是什么?

2、仔细考虑你的目标受众是谁?他们需要什么?他们在哪里寻求解答和帮助?

3、选择聚焦的平台和方式。提示:不要太过于野心勃勃。如果你决定在每种社交媒体上都架设自己的主页或平台,你的时间会完全浪费在社交媒体上,导致在其他方面却会收效甚微。切记,聚焦于你的受众所在之处。

4、创建明确的时间表,将你在接下来3到6个月中所要开发的内容详细列入时间表。

节流小贴士:将你的预算表牢记在心。如果你的计划超过了你力所能及的范围,那这是一个放弃原计划的好机会,否则你很可能冲动草率。如果你的团队只能在一个月中发布两篇高质量的博客,那么就不要制定一个一天发布一篇博客的计划——少而精却能引人注目的内容总比整天发些无人注意的平庸内容要好得多。

第三步:雇佣帮手协助战略实施

如果你的员工有必要的时间和技能来实施营销战略,那么你可以跳过这一步。但是对大多数中小企业而言,需要帮手的情况还是很常见的。

内容营销不仅关乎创造内容。你还需要一定的战略和战术使内容更加友好,更有说服力,更加优化,从而帮助你实现营销目标。学习“最佳实践方法”需要时间,向团队输入新鲜血液可以帮助你和你的团队更快速地学习内容营销基础,从而受益匪浅。

你也可能会产生这样的想法:只是没有相应的技术来实现自己的想法而已。如果团队中没有出色的平面设计师或者有经验的视频制作者,最好聘请有经验的人协助制作这些形式的内容,而不是单打独斗,耗费大量时间制造低水平的内容。

节流小贴士:同本地的承包商和公司合作。这并不是让你想方设法花更少的钱获得同样的服务,而是找找看有没有通过减少工作量来降低收费的方法,比如,如果聘请一个人写博客,可以询问他是否可以通过提供笔记来简化研究程序,使原价100美元一条的博客降至75美元。

招募对口专业的实习生。学平面设计的学生,学电影制作的学生,还有市场营销专业的学生,他们可以从实习中获得丰富的工作经验和现金报酬,而你则从与他们的合作中获得想要的效果。

我强烈建议你向你所招募的实习生支付报酬,因为如果双方共赢而不是让他们感觉你在剥削他们的话,他们会做得更好,并且会更加尊重你和你的企业。

第四步:完善你的计划,以满足预算需求

在计划实施之前,要预测一项工作会花费多少时间和精力是很难的。或许会需要精简原计划,或者足够幸运的话,可能会发现可以做得比预期更多更好。

制定营销战略十分重要,但不要一直固守一项战略。如果跟不上自己的计划,就需要做出抉择:投入更多的时间和资金,还是转变战略,亦或是削减计划内容?

节流小贴士:不要害怕缩减计划内容。制作出能够直达受众内心并能引发共鸣的内容比单纯为达到数量目标而制造质量低下的内容要重要得多。如果完成某些事项所花费的时间和资金比想象中要多的多,不要惊讶,这在内容营销战略实施的前期并不罕见。从其中获得的经验将教会你如何设计未来的营销战略及目标。

第五步:追踪真正有效的策略

在完善营销战略时,一定要集中在那些真正有效的战术和平台上。如果在Twitter上已经得到了很多人的关注,而在Facebook上的互动却没有达到预期,这时你应该砍掉无效的Facebook平台。

做出这一决定可能需要一些时间,你也可能并不清楚哪些措施是有效的或者它们为什么有效,很可能直到实施几个月后一切才会显明。如果在计划实施的最初几个月里注意流量趋向、搜索结果、点击率以及社交媒体互动话题,你将会对自己战略中最重要的部分有一个清晰的认识。

节流小贴士:利用谷歌数据分析以及简单地询问“你们是如何找到我的?”,你可以在这一步里省下支付给数据分析工具的开支。你需要砍掉那些不被关注的平台和无效战术,以此节约时间和资金,并将其投给高投资回报率的部分。

尽管内容营销会花费大量时间,并且可能一会开始使人不堪重负,然而在企业经营中,占用时间和工作负担都是无法避免的。内容营销不仅仅事关获得购买可能性数据和搜索流量(虽然这两点确实很重要),它还可以让你和潜在客户建立关系。这就是对本地中小企业而言的客户长期价值的现代版解释:培养人际关系。如果你想要顾客们信任你,珍惜你,并且在他们需要某种产品或服务时首先想到你,良好的内容营销战略将会使你受益匪浅。

当然,先发制人会使你的内容营销战略最有成效,所以你还等什么?赶快行动吧!

参考资料: http://www.marketingprofs.com/articles/2014/24957/five-steps-to-effective-and-affordable-small-business-content-marketing

您可能也喜欢:

【How-To】成功网站3要诀:内容为王、设计为后、别忘营销小王子

【How-To】借力使力,4招教你如何打造个人品牌

【How-To】企业衡量内容营销是否有效的5个关键指标

【How-To】无“聊”行业内容营销的6条建议

【How-To】2013内容营销制胜的10个方法
无觅

从技术到管理:思维转变是关键

$
0
0

  IT公司研发部门的管理人员大多是从公司内部的技术人员中提拔的。在快速发展的公司里,这样的机会更多。然而这种“半路出家”的转型也给我们带来了很多挑战,其中最关键的部分在于思维方式的转变。

   从个人成就到团队成就。

  无论是做管理还是做技术,成就导向意识是优秀员工的基本素质。只有具备很强的成就导向意识,才能把事情做得超预期,才能追求卓越。

  刚刚上任的管理人员的思维方式往往还处于个人成就导向阶段,他们希望向外界发出一个明确的信号,团队之所以取得这样的成绩或者解决某个难题,是因为我的组织和领导。然而这种信号被团队成员多次接到后,会产生功劳都被领导拿走的感觉,从而导致团队的向心力下降。

  这时,比较好的做法是:要保护团队成员的成就导向,并且进行鼓励,从而刺激大家的积极性。例如,与某个团队成员共同解决了某个难题后,要弱化自己,重点表扬这个团队成员对问题的贡献。这样再遇到某个难题时,这个团队成员才能保持一样或更高的激情。只有将自己的成就感定位在团队成就上,才能站得更高,避免和团队成员产生直接竞争,从而有效地领导自己的团队。

   上下同欲的氛围。

  兵法有云:“上下同欲者胜”。一个团队能够健康运作的基础就是“上下同欲”的氛围。要想拥有这种氛围,必须处理好两件事情:发言权和信息透明。

  发言权:每个人都希望发表自己对某件事情的看法,尤其是比较关键的事情,并获得聆听。如果管理人员屏蔽这些,所表达的就是一种不尊重。当然不是所有的意见都要被采纳,需要需要合理的决策,但要让大家有发言的机会。

  信息透明:这里的信息包括一切可以公开的信息,如上级期望和项目进展等。保持这些信息的透明度,能够提高团队成员对团队绩效的关注度和荣辱感。当大家都站在团队的高度上思考问题时,能够省去很多协调工作。

  转型到管理岗位后,就要多花些时间来考虑团队建设问题。只有团队的氛围比较好,才有机会取得较好的成绩。

   合理计划,要事第一。

  刚刚转型的管理人员往往会有类似这样的抱怨“杂事太多,被不停地打断”。造成这一问题的很大部分原因在于,计划不够周全或者缺乏例行沟通机制。例如,每日站立例会基本上可以消除很多这样的杂事。同时因为管理人员需要接触的人比较多,所以日常处理的事情也会比较多。这与技术人员有很大不同。

  这时就要有非常合理的计划,保证要事被及时处理。需要注意的是,时间的急迫性往往会夸大事情的重要性。如果管理人员总是习惯将任务拖到最后的截止时间处理,则会打乱事情的优先级,导致做事失去计划性。

   培养人才,用人所长。

  杰克·韦尔奇说过:“在你成为领导之前,成功只同自己的成长有关。当你成为领导之后,成功同别人的成长有关。” 管理人员要把培养下属作为一件重要的事情,只有团队里的人才层出不穷,团队才有能力去不断挑战更高的目标。用人所长则指在工作的安排过程中需要多关注下属的长处,不能过度放大他们的缺点。正所谓“用人所长,天下无不用之人;用人所短,天下无可用之人”。人事任命需谨慎考虑,用对一个人,能省很多心;用错一个人,要操很多心。将合适的人放到合适的位置,是管理人员必须面对的一个难题。

   关于作者:梁景波,深信服科技研发经理。

用程序来控制一个网页,实现自动输入等操作

$
0
0
首先今天要说的东西跟游戏无关,你是不是有时候会遇到,在某个网页上重复着几十次的简单而又无聊的录入或点击等工作?比如你的程序需要测试,需要注册大量的测试邮箱。比如你的老板是个变态,让你去各个论坛发大量的垃圾贴子(最无耻行为,纯属举例)。或者,你需要定时的到某一个网页上执行某一些行为,比如上班下班的出勤打卡系统,等等吧,
如果有,那么我今天所介绍的或许会对你有帮助。
当然,如果你要操作的这些网页都是自己开发的,那么无所谓了,你在多开发个工具就行了,但是我说的上面这些都是第三方的网页,你控制不了它们,如果遇到上上述情况,而你是一个挨踢程序员,而你又选择老老实实的重复着这些无聊又费时的工作,那你就真该挨踢了。
要实现这些功能,你只需要用程序控制这些网页,让网页听你的就行了。要动手实现这一系列的功能,你需要做几个简单的准备。
1,OS环境:Windows
2,IE浏览器
3,工具:Excel或者Visual Studio
先来看看如何用Excel来控制一个网页。
新建一个Excel并且进入VBA,标准模式,什么?不知道VBA?你可以找我的两个老师问一下,他们一个姓百,另一个姓谷,诶?你说你也认识?那大家都是自己人了,你什么时候请吃饭啊?
如下图。

我是日文系统,中文的你对照着自己来吧...
要对IE进行操作,首先需要引入两个插件
HTML Object Library
Microsoft Internet Controls
如图

打开IE,你只需要下面几行代码
Sub Main()
    Dim ie As Object
    Set ie = CreateObject("InternetExplorer.Application")
    ie.Visible = True
End Sub

比如我要打开百度,那就这样
ie.Navigate "http://www.baidu.com"

接着你需要等待页面加载
While ie.ReadyState <> 4 Or ie.Busy = True
	DoEvents
Wend

好了,百度打开了,是不是很简单,不过你也会说,打开个网页算什么,随便一个程序都可以吧,好吧,咱们下面来实现自动搜索。
首先,咱们用VBA在百度的输入框里输入几个文字,百度的输入框的代码如下
<input type="text" name="wd" id="kw1" maxlength="100" style="width:474px;" autocomplete="off">

那我们就可以通过这个id来对输入框进行输入,如下
ie.Document.getElementById("kw1").value = "hellow world"

如果你上面都没有出错的话,"hellow world"应该已经被加入到输入框里了。
那么下面用VBA来点击搜索按钮,进行搜索。百度的搜索按钮代码如下
<input type="submit" value="百度一下" id="su1" class="btn" onmousedown="this.className='btn btn_h'" onmouseout="this.className='btn'">

看到id了吧,那就简单了,下面这样来点击它
ie.Document.getElementById("su1").click

怎么样,自动搜索完成了吧
当然,这只是一个最简单的例子而已,如果没有id怎么办?你也可以下下面这样用它
ie.document.all
ie.document.body
ie.document.getElementsByName
ie.document.getElementsByTagName

看到了吧,和JS很像,如果你不愿意查相关的API的话,那你就拿JS的操作方法往上面套用吧
下面来看另一个页面的结构,比如下面这样
<html><frameset cols="25%,50%,25%"><frame src="frame_a.htm" /><frame src="frame_b.htm" /><frame src="frame_c.htm" /></frameset></html>

如果你要操作这个页面的子页面,也很简单
Dim objFRAME As FramesCollection
Set objFRAME = ie.document.frames
Dim HW As HTMLWindow2
Set HW = objFRAME(1)
HW.document.all
...

这个是操作索引为1的子页面,当然你也可以循环所有的子页面,来做的要做的事。
上面所介绍的都是先打开一个页面,然后再进行操作,如果需要操作一个已经打开的页面,你需要这样。
Dim objShell  As Object
Dim objIE     As Object
Dim n         As Integer
Set objShell = CreateObject("Shell.Application")
For n = objShell.Windows.Count To 1 Step -1
	Set objIE = objShell.Windows(n - 1)
	If objIE Is Nothing Then
		Exit For
	End If
	If Right(UCase(objIE.FullName), 12) = "IEXPLORE.EXE" Then
		Debug.Print objIE.document.URL '测试,输入URL
		If objIE.document.URL = "http://www.baidu.com" Then '看看是不是你要的页面
			'找到你要操作的页面了,开始处理
		End If
	End If
Next
Set objShell = Nothing

excel就说这么多了。


下面用.net来做,既然前面用了VBA,这里我就不用VB再重复了,换用C#来实现。
打开Visual Studio,新建一个项目,同样,这次你需要引入三个插件
HTML Object Library
Microsoft Internet Controls
Microsoft Shell Controls And Automation
如图


启动IE,并打开百度
SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorer();
ie.Navigate("http://www.baidu.com");
ie.Visible = true;

获取Document
shtml.HTMLDocument doc = ie.Document;

同样,在输入框里输入文字
doc.getElementById("kw1").value = "hellow world";

开始搜索。
doc.getElementById("su1").click();

下面利用c#如何来操作已经打开的浏览器呢?看下面代码
public static SHDocVw.InternetExplorer getInternetExploer(string url)
{
	var shell = new Shell32.Shell();
	var windows = (SHDocVw.IShellWindows)shell.Windows();
	SHDocVw.InternetExplorer ie;
	foreach (object window in windows)
	{
		ie = window as SHDocVw.InternetExplorer;
		if (ie != null && 
				string.Equals(System.IO.Path.GetFileName(ie.FullName),"iexplore.exe", StringComparison.CurrentCultureIgnoreCase))
		{
			if (ie.LocationURL == url)
			{
				 return ie;
			}
		}
	}
	return null;
}

好了,其他的方法如
doc.body
doc.getElementsByName
doc.getElementsByTagName

等等,自己套用一下就可以了
接下来是frame操作,如下
mshtml.HTMLDocument doc2 = ie.Document;
var frame = doc2.frames.item(int.Parse(configs[2]));
var doc = frame.Document;
doc.getElementById
完了,操作方法基本上都大同小异吧。
在使用.net来操作浏览器的时候,我发现操作同一个页面时,如果页面发生刷新或者跳转等动作后,程序经常会出bug,网上搜索了一下,发现还真不是我一个人,那如何来避免呢?
因为使用.net来第一次操作页面的时候是肯定不会出错的,必须是2次或2次以上才会出现错误,所以我们可以做两个程序,在一个程序中调用另一个,调用完之后,就把它关闭掉,这样每次都相当于启动一个新程序,就不会出bug了。
启动一个新程序用下面代码
public static void runSubWindow(String command)
{
	ProcessStartInfo psInfo = new ProcessStartInfo();
	psInfo.FileName = command; 
	psInfo.CreateNoWindow = true;
	psInfo.UseShellExecute = false;
	psInfo.RedirectStandardOutput = true;
	Process p = Process.Start(psInfo);
	string output = p.StandardOutput.ReadToEnd();
}

传入你的程序的路径,就可以打开它了。

有了上面的知识,你可以自由的发挥了,比如你做一个定时程序,在上班时间自动打卡,然后自己接着睡一会儿....嘘!!这绝对不是我说的。

今天就介绍这么多了,欢迎继续关注我的博客

转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend
作者:lufy_Legend 发表于2014-5-7 10:55:33 原文链接
阅读:0 评论:0 查看评论

JBoss AS 7性能调优(三)

$
0
0

原文: http://www.mastertheboss.com/jboss-performance/jboss-as-7-performance-tuning/page-4


调优Web服务器线程池

还有很多需要调优的地方最终影响Web服务器的性能,其中一个最重要的因素是调优HTTP线程池设置,以匹配web请求的负载。这其实是很难做到的,但可通过调优获得最佳性能。

web服务器的线程数量是通过executor的属性来设置的:

<subsystem xmlns="urn:jboss:domain:web:1.0">

 

 <connector enable-lookups="false" enabled="true"       

 executor="http-executor"

 max-connections="200"

 max-post-size="2048" max-save-post-size="4096"

 name="http" protocol="HTTP/1.1"

 proxy-name="proxy" proxy-port="8081"

 redirect-port="8443" scheme="http"

 secure="false" socket-binding="http" />

. . .

</subsystem>

然后,在线程子系统中,可以定义将要使用的池的线程数,连同其他线程属性(参见第2章,配置应用程序服务器,以获取有关线程子系统详细介绍):

<subsystem xmlns="urn:jboss:domain:threads:1.0">

    <bounded-queue-thread-pool name="http-executor"

        blocking="true">

        <core-threads count="10" per-cpu="20" />

        <queue-length count="10" per-cpu="20" />

        <max-threads count="10" per-cpu="20" />

        <keepalive-time time="10" unit="seconds" />

    </bounded-queue-thread-pool>

</subsystem>

最重要的连接器的属性是 core-threadsmax-threads,这些值设置的太低,可能没有足够的线程来处理所有的请求,在这种情况下,请求不被处理必须等待一段时间,直到另一个请求线程被释放。过低的值也意味着JBoss的Web服务器将无法充分利用服务器硬件的优势。

另一方面,要小心设置这些线程数,线程数设置过高会导致:
•    消耗大量的内存;
•    系统会消耗更多的时间做上下文切换。

你应该首先调查是否存在个别的请求耗用过长的时间,线程是否返回到池中?如果存在这种情况,可能原因是,数据库连接没有释放,线程排队等待获取一个数据库连接,从而使其他请求无法得到处理。

在这种情况下,简单地增加更多的线程会消耗更多CPU,GC更加频繁,从而使事情变得更糟。在应用程序中你可以通过采取简单的线程转储(thread dump),找出web服务器线程究竟在哪里阻塞,例如在这张图片中,从 JConsole的线程选项卡中,通过观察它的堆栈跟踪,你可以看到看起来和下面类似的 空闲线程idle thread):


另一方面,下面的HTTP线程忙于做输入/输出操作,可能的原因是,例如Web服务器正在从外部资源获取数据。


从上面的快照可以指导你如何监视Web服务器上运行的线程,只需在最下面的文本框填写executor的名称(http-executor),就会显示所有Web服务器线程的列表。

作者:wilbertzhou 发表于2014-5-7 10:45:54 原文链接
阅读:5 评论:0 查看评论

企业常用的网络推广方法(总结)

$
0
0
随着互联网的不断发展,越来越多的钢管企业意识到网络推广的重要性。本文小钢为大家列举了一些企业常用的网络推广方法,并简单说说实际操作当中存在的问题。


(1)博客、网站:建立公司网站或者博客,这是企业最常见的网络推广方法。很多企业都建立了自己的网站,但是因为企业网站没有人维护,或者不懂的怎么做SEO优化,所以很多网站都没有发挥到效果,只是作为企业的一个摆设。


(2)微博、微信:随着这几年微博和微信越来越火,而且建设的成本很低,很多企业也都有自己的微博或者微信,也有的企业会专门参加微博、微信的培训,但是因为执行不到位,或者操作方法有问题,能够发挥作用的也很少。


(3)百度竞价:百度竞价是比较好的营销方式,可以快速获取搜索引擎流量。但是对于一些小企业来说,可能成本有点偏大。


(4)QQ群:找到精准的QQ群,每天群发信息,也可以快速获取用户。只要执行的够狠,靠这一个方法就可以支撑一个公司。


(5)电子邮件:收集行业用户的QQ邮箱,定期发送一些有用的信息,可以带来一些客户。通过一些手段对邮箱数据进行筛选,可以逐步让自己的客户群越来越精准。


(6)论坛、贴吧:行业论坛和贴吧,发布一些有意义的信息,或者简单的供应广告,也可以为自己带来客户。


(7)百科、问答营销:问答平台,每天都有大量的人问问题,找到自己行业相关的问题回答,用户名或者个人介绍里面加入自己的资料,也可以为自己带来用户。


(8)视频、图片营销:视频和图片每天都有很多人关注,比文字性的东西更直观。可以拍一些有意义的视频,上传到视频网站,或者上传到自己网站上面,在行业平台上留下链接吸引人过来。


(9)电子书营销:把行业知识收集起来,整理成文档或者电子书,加入自己的公司名或者网址,然后发布到文档下载平台。


(10)数据库营销:这个跟邮件营销有些类似,都是通过各种渠道收集行业用户的数据,然后利用收集过来的数据推送信息,可以起到很好的效果。


(11)软文新闻营销:软文营销是潜力最大的营销方法,如果做得好,几天的时间可以给自己带来大量的客户。但是,里面需要很多的技巧,对新人有难度。


其实,网络推广的方法不在多,找到适合自己的方法,狠狠执行就好了。以上就是企业常用的网络推广方法,以后小钢会针对每种推广手段做详细的介绍。
作者:qq251022135 发表于2014-5-7 9:51:11 原文链接
阅读:60 评论:0 查看评论

面向GC的Java编程

$
0
0

感谢同事【 沐剑】的投稿

Java程序员在编码过程中通常不需要考虑内存问题,JVM经过高度优化的GC机制大部分情况下都能够很好地处理堆(Heap)的清理问题。以至于许多Java程序员认为,我只需要关心何时创建对象,而回收对象,就交给GC来做吧!甚至有人说,如果在编程过程中频繁考虑内存问题,是一种退化,这些事情应该交给编译器,交给虚拟机来解决。

这话其实也没有太大问题,的确,大部分场景下关心内存、GC的问题,显得有点“杞人忧天”了,高老爷说过:

过早优化是万恶之源。

但另一方面, 什么才是“过早优化”?

If we could do things right for the first time, why not?

事实上 JVM的内存模型( JMM )理应是Java程序员的基础知识,处理过几次JVM线上内存问题之后就会很明显感受到,很多系统问题,都是内存问题。

对JVM内存结构感兴趣的同学可以看下 浅析Java虚拟机结构与机制这篇文章,本文就不再赘述了,本文也并不关注具体的GC算法,相关的文章汗牛充栋,随时可查。

另外,不要指望GC优化的这些技巧,可以对应用性能有成倍的提高,特别是对I/O密集型的应用,或是实际落在YoungGC上的优化,可能效果只是帮你减少那么一点YoungGC的频率。

但我认为, 优秀程序员的价值,不在于其所掌握的几招屠龙之术,而是在细节中见真著,就像前面说的, 如果我们可以一次把事情做对,并且做好,在允许的范围内尽可能追求卓越,为什么不去做呢

一、GC分代的基本假设

大部分GC算法,都将堆内存做分代(Generation)处理,但是为什么要分代呢,又为什么不叫内存分区、分段,而要用面向时间、年龄的“代”来表示不同的内存区域?

GC分代的 基本假设是:

绝大部分对象的生命周期都非常短暂,存活时间短。

而这些短命的对象,恰恰是GC算法需要首先关注的。所以在大部分的GC中,YoungGC(也称作MinorGC)占了绝大部分,对于负载不高的应用,可能跑了数个月都不会发生FullGC。

基于这个前提,在编码过程中,我们应该 尽可能地缩短对象的生命周期。在过去,分配对象是一个比较重的操作,所以有些程序员会尽可能地减少new对象的次数,尝试减小堆的分配开销,减少内存碎片。

但是,短命对象的创建在JVM中比我们想象的性能更好,所以,不要吝啬new关键字,大胆地去new吧。

当然前提是不做无谓的创建,对象创建的速率越高,那么GC也会越快被触发。

结论:

分配小对象的开销分享小,不要吝啬去创建。

GC最喜欢这种小而短命的对象。

让对象的生命周期尽可能短,例如在方法体内创建,使其能尽快地在YoungGC中被回收,不会晋升(romote)到年老代(Old Generation)。

二、对象分配的优化

基于大部分对象都是小而短命,并且不存在多线程的数据竞争。这些小对象的分配,会优先在线程私有的 TLAB中分配,TLAB中创建的对象,不存在锁甚至是CAS的开销。

TLAB占用的空间在Eden Generation。

当对象比较大,TLAB的空间不足以放下,而JVM又认为当前线程占用的TLAB剩余空间还足够时,就会直接在Eden Generation上分配,此时是存在并发竞争的,所以会有CAS的开销,但也还好。

当对象大到Eden Generation放不下时,JVM只能尝试去Old Generation分配,这种情况需要尽可能避免,因为一旦在Old Generation分配,这个对象就只能被Old Generation的GC或是FullGC回收了。

三、不可变对象的好处

GC算法在扫描存活对象时通常需要从ROOT节点开始,扫描所有存活对象的引用,构建出对象图。

不可变对象对GC的优化,主要体现在Old Generation中。

可以想象一下,如果存在Old Generation的对象引用了Young Generation的对象,那么在每次YoungGC的过程中,就必须考虑到这种情况。

Hotspot JVM为了提高YoungGC的性能,避免每次YoungGC都扫描Old Generation中的对象引用,采用了 卡表(Card Table)的方式。

简单来说,当Old Generation中的对象发生对Young Generation中的对象产生新的引用关系或释放引用时,都会在卡表中响应的标记上标记为脏(dirty),而YoungGC时,只需要扫描这些dirty的项就可以了。

可变对象对其它对象的引用关系可能会频繁变化,并且有可能在运行过程中持有越来越多的引用,特别是容器。这些都会导致对应的卡表项被频繁标记为dirty。

而不可变对象的引用关系非常稳定,在扫描卡表时就不会扫到它们对应的项了。

注意,这里的不可变对象,不是指仅仅自身引用不可变的final对象,而是真正的 Immutable Objects

四、引用置为null的传说

早期的很多Java资料中都会提到在方法体中将一个变量置为null能够优化GC的性能,类似下面的代码:

List<String> list = new ArrayList<String>();
// some code
list = null; // help GC

事实上这种做法对GC的帮助微乎其微,有时候反而会导致代码混乱。

我记得几年前 @rednaxelafx 在HLL VM小组中详细论述过这个问题,原帖我没找到,结论基本就是:

在一个非常大的方法体内,对一个较大的对象,将其引用置为null,某种程度上可以帮助GC。

大部分情况下,这种行为都没有任何好处。

所以,还是早点放弃这种“优化”方式吧。

GC比我们想象的更聪明。

五、手动档的GC

在很多Java资料上都有下面两个奇技淫巧:

通过Thread.yield()让出CPU资源给其它线程。

通过System.gc()触发GC。

事实上JVM从不保证这两件事,而System.gc()在JVM启动参数中如果允许显式GC,则会 触发FullGC,对于响应敏感的应用来说,几乎等同于自杀。

So,让我们牢记两点:

Never use Thread.yield()。

Never use System.gc()。除非你真的需要回收Native Memory。

第二点有个Native Memory的例外,如果你在以下场景:

· 使用了NIO或者NIO框架(Mina/Netty)

· 使用了DirectByteBuffer分配字节缓冲区

· 使用了MappedByteBuffer做内存映射

由于 Native Memory只能通过FullGC(或是CMS GC)回收,所以除非你非常清楚这时真的有必要,否则不要轻易调用System.gc(),且行且珍惜。

另外为了防止某些框架中的System.gc调用(例如NIO框架、Java RMI),建议在启动参数中加上-XX:+DisableExplicitGC来禁用显式GC。

这个参数有个巨大的坑,如果你禁用了System.gc(),那么上面的3种场景下的内存就无法回收,可能造成OOM,如果你使用了CMS GC,那么可以用这个参数替代:-XX:+ExplicitGCInvokesConcurrent。

关于System.gc(),可以参考 @bluedavy 的几篇文章:

· CMS GC会不会回收Direct ByteBuffer的内存

· 说说在Java启动参数上我犯的错

· java.lang.OutOfMemoryError:Map failed

六、指定容器初始化大小

Java容器的一个特点就是可以动态扩展,所以通常我们都不会去考虑初始大小的设置,不够了反正会自动扩容呗。

但是扩容不意味着没有代价,甚至是很高的代价。

例如一些基于数组的数据结构,例如StringBuilder、StringBuffer、ArrayList、HashMap等等,在扩容的时候都需要做ArrayCopy,对于不断增长的结构来说,经过若干次扩容,会存在大量无用的老数组,而回收这些数组的压力,全都会加在GC身上。

这些容器的构造函数中通常都有一个可以指定大小的参数,如果对于某些大小可以预估的容器,建议加上这个参数。

可是因为容器的扩容并不是等到容器满了才扩容,而是有一定的比例,例如HashMap的扩容阈值和负载因子(loadFactor)相关。

Google Guava框架对于容器的初始容量提供了非常便捷的工具方法,例如:

Lists.newArrayListWithCapacity(initialArraySize);

Lists.newArrayListWithExpectedSize(estimatedSize);

Sets.newHashSetWithExpectedSize(expectedSize);

Maps.newHashMapWithExpectedSize(expectedSize);

这样我们只要传入预估的大小即可,容量的计算就交给Guava来做吧。

反例:

如果采用默认无参构造函数,创建一个ArrayList,不断增加元素直到OOM,那么在此过程中会导致:

多次数组扩容,重新分配更大空间的数组
多次数组拷贝
内存碎片

七、对象池

为了减少对象分配开销,提高性能,可能有人会采取对象池的方式来缓存对象集合,作为复用的手段。

但是对象池中的对象由于在运行期长期存活,大部分会晋升到Old Generation,因此无法通过YoungGC回收。

并且通常……没有什么效果。

对于对象本身:

如果对象很小,那么分配的开销本来就小,对象池只会增加代码复杂度。

如果对象比较大,那么晋升到Old Generation后,对GC的压力就更大了。

从线程安全的角度考虑,通常池都是会被并发访问的,那么你就需要处理好同步的问题,这又是一个大坑,并且 同步带来的开销,未必比你重新创建一个对象小

对于对象池,唯一合适的场景就是 当池中的每个对象的创建开销很大时,缓存复用才有意义,例如每次new都会创建一个连接,或是依赖一次RPC。

比如说:

· 线程池
· 数据库连接池
· TCP连接池

即使你真的需要实现一个对象池,也请使用成熟的开源框架,例如Apache Commons Pool。

另外,使用JDK的ThreadPoolExecutor作为线程池,不要重复造轮子,除非当你看过AQS的源码后认为你可以写得比Doug Lea更好。

八、对象作用域

尽可能缩小对象的作用域,即生命周期。

如果可以在方法内声明的局部变量,就不要声明为实例变量。

除非你的对象是单例的或不变的,否则尽可能少地声明static变量。

九、各类引用

java.lang.ref.Reference有几个子类,用于处理和GC相关的引用。JVM的引用类型简单来说有几种:

· Strong Reference,最常见的引用
· Weak Reference,当没有指向它的强引用时会被GC回收
· Soft Reference,只当临近OOM时才会被GC回收
· Phantom Reference,主要用于识别对象被GC的时机,通常用于做一些清理工作

当你需要实现一个缓存时,可以考虑优先使用WeakHashMap,而不是HashMap,当然,更好的选择是使用框架,例如Guava Cache。

最后,再次提醒,以上的这些未必可以对代码有多少性能上的提升,但是熟悉这些方法,是为了帮助我们写出更卓越的代码,和GC更好地合作。

(全文完)如果您喜欢此文请点赞,分享,评论。





您可能感兴趣的文章

GitHub 上都有哪些值得关注学习的 iOS 开源项目?

$
0
0
GitHub上有很多不错的iOS开源项目,个人认为不错的,有这么几个:
1. ReactiveCocoa: ReactiveCocoa/ReactiveCocoa · GitHub
GitHub自家的函数式响应式编程泛型的Objective-C实现,名字听着很高大上,学习曲线确实也比较陡,但是绝对会改变你对iOS编程的认知,首推之。
2. Mantle: Mantle/Mantle · GitHub
又是GitHub自家的产物,轻量级建模的首选,也可以很好的配合CoreData工作。
3. AFNetworking: AFNetworking/AFNetworking · GitHub :
iOS7之前,苹果自带的网络库有多难用!matt大神的AFNetworking绝对可以解放你。使用苹果的NSURLRequest及iOS7的NSURLSession,清晰的架构,足够的文档,可以认为是第三方开源库的楷模了。
4. BlocksKit: pandamonia/BlocksKit 路 GitHub
本人相当偏爱Functional Programming,Objective-C中的block绝对满足我的口味。但想用好block也不是很容易,如果对block有爱,就请使用这个库吧。
5. Nimbus: jverkoey/nimbus · GitHub
第一次关注nimbus是因为Facebook的Three20开源库。可惜Three20库已死,主要作者跳出来,写了nimbus。
6. pop: facebook/pop · GitHub
facebook出品的paper,动画效果太好了,赶超apple的原生apple一大截。pop就是paper的动画库!
其他。。。待补充,上班时写的,先这么多吧
第一次回答知乎的问题,想着闲了的时候还是要建个blog才行- -

— 完 —
本文作者: 吴辉斌

【知乎日报】 你都看到这啦,快来点我嘛 Σ(▼□▼メ)

此问题还有 32 个回答,查看全部。
延伸阅读:
国内公司在github上有哪些比较出彩的开源项目?
有哪些适合学习的开源项目?

【翻译】高效的double-checked线程锁

$
0
0

      代码的性能是最重要的。然而,在当今复杂的多线程移动应用世界里,我们常常会为保证内存数据的一致性而牺牲一些性能。线程竞争条件的设计和调试是一件非常耗时,且容易令人沮丧的工作,所以线程被锁定太长时间的情况并不少见。幸运的是,现在有一些简单的模式可以使锁定变得更有效率,从而避免对性能产生不必要的影响。

      首先,让我们先预览一下只有简单 setter 代码的基类:

public class Foo {
    private Map<string, string=""> data;

    public Foo() {
        data = new HashMap<string, string="">();
    }

    public void setData(String key, String value) {
        data.put(key, value);
    }
}

       在上面的代码里,每当我们实例化一个Foo对象的同时也在实例化一个HashMap对象,而无论该HashMap是否会被使用。一般情况下,在一个强劲配置的服务器上,前面实例化的开销相对较低。但是相对一个只放在你口袋里,并且整天运行在一块电池上的设备,那样子的开销将会上升得非常快。为了提升效率,我们采用懒加载策略来重写上面的代码。

public class Foo {
    private Map<string, string=""> data;

    public Foo() { }

    public void setData(String key, String value) {
        if (data == null)
            data = new HashMap<string, string="">();

        data.put(key, value);
    }
}

       现在Foo的构造器实质上是空的构造器,而且我们只有在调用setData方法时,才会产生实例化HashMap对象的开销。在这点上,我们快速实现了只有在绝对需要的时候才去使用内存。然而这种实现的方式并非是线程安全的。线程安全是非常重要的,自从Android对线程操作的要求达到了一个根本的层面(你不可以在UI线程上执行IO阻塞的操作)。

       在上面的例子中,有两个地方需要特别注意的。第一,我们需要线程安全的数据结构。使用 ConcurrentHashMap取代HashMap可以简单地解决这点。第二,稍稍复杂一点,我们需要为属性 data 的实例化,设置更微妙的竞争条件。有这样子的可能性,两个线程同时判断属性data是否为null,并尝试为其实例化。更糟糕的是,其中一个线程会对其实例化的map置入一个对象,但该map实例将会丢失,如果两一个线程也实例化了自己的map对象。为了避免这种竞争情况,我们可以为此加上 synchronized 代码块:

public class Foo {
    private Map<string, string=""> data;

    public Foo() { }

    public void setData(String key, String value) {
        synchronized (this) {
            if (data == null)
                data = new ConcurrentHashMap<string, string="">();
        }

        data.put(key, value);
    }
}

       这就确保了同一时间里,只有一个线程进行null检查,并在需要的时候对属性data进行实例化。好像到这里,问题都迎刃而解了,然而,或许你还会记得我们的关注点是在于性能的优化,很不幸,synchronized 代码块的开销往往比较大。在这种情况下,在同一时间里,只有一个线程可以高效地访问方法setData。幸好,我们还有另一个方法可以使用:double-checked locking。在维基百科上有一篇优秀的文章对   double-checked locking 作了详尽的介绍。在我们的例子里,运用该方法后的代码如下:

public class Foo {
    private volatile Map<string, string=""> data;

    public Foo() { }

    public void setData(String key, String value) {
        if (data == null) {
            synchronized (this) {
                if (data == null)
                    data = new ConcurrentHashMap<string, string="">();
            }
        }

        data.put(key, value);
    }
}

       在上面的代码中,有两个非常重要的改变。其一,为属性data添加了volatile声明。这将指示编译器,最终是Dalvik VM,确保数据的读写操作按预读顺序(译者注: happened-before order)执行。换句话说,写数据操作,总是发生在读数据操作之前(没有这个关键字的声明,编译器或JIT优化或会使它们顺序逆转)。其次,我们在synchronized 代码块外面再添加了一层null检查。这就确保一旦属性data已被实例化,我们将不会再执行 synchronized 的代码块。然而,如果属性data确实为null,我们将 synchronize 对象,然后双重检查属性data是否为null,以确保在两次检查之间,没有其他线程没有执行属性data的实例化。如果没有这个竞争条件,代码将继续执行,继而跳出这个 synchronized 代码块。

       到这里,细心而聪明的读者或许会注意到,上述方法在Java1.5之前并不是总是可靠的。Dalvik VM也是有相似的历史,使用该方法前,请从  这里 检查一下。在这里更推荐大家阅览   这篇 描述如何在Android处理内存一致性问题的优秀指南。

 

 

        本文由 zhiweiofli编辑发布,转载请注明出处,谢谢。

 



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


ITeye推荐




(转)ThreadLocal的内存泄漏问题

$
0
0

原文:http://www.godiscoder.com/?p=479

在最近一个项目中,在项目发布之后,发现系统中有内存泄漏问题。表象是堆内存随着系统的运行时间缓慢增长,一直没有办法通过gc来回收,最终于导致堆内存耗尽,内存溢出。开始是怀疑ThreadLocal的问题,因为在项目中,大量使用了线程的ThreadLocal保存线程上下文信息,在正常情况下,在线程开始的时候设置线程变量,在线程结束的时候,需要清除线程上下文信息,如果线程变量没有清除,会导致线程中保存的对象无法释放。

从这个正常的情况来看,假设没有清除线程上下文变量,那么在线程结束的时候(线程销毁),线程上下文变量所占用的内存会随着线程的销毁而被回收。至少从程序设计者角度来看,应该如此。实际情况下是怎么样,需要进行测试。

但是对于web类型的应用,为了避免产生大量的线程产生堆栈溢出(默认情况下一个线程会分配512K的栈空间),都会采用线程池的设计方案,对大量请求进行负载均衡。所以实际应用中,一般都会是线程池的设计,处理业务的线程数一般都在200以下,即使所有的线程变量都没有清理,那么理论上会出现线程保持的变量最大数是200,如果线程变量所指示的对象占用比较少(小于10K),200个线程最多只有2M(200*10K)的内存无法进行回收(因为线程池线程是复用的,每次使用之前,都会从新设置新的线程变量,那么老的线程变量所指示的对象没有被任何对象引用,会自动被垃圾回收,只有最后一次线程被使用的情况下,才无法进行回收)。

以上只是理论上的分析,那么实际情况下如何了,我写了一段代码进行实验。

  • 硬件配置:

处理器名称: Intel Core i7 2.3 GHz  4核

内存: 16 GB

  • 软件配置

操作系统:OS X 10.8.2

java版本:”1.7.0_04-ea”

  • JVM配置

-Xms128M -Xmx512M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -Xloggc:gc.log

测试代码:Test.java 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

    public static void main(String[] args) throws Exception {
        
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int testCase= Integer.parseInt(br.readLine());
        br.close();
        
        switch(testCase){
            // 测试情况1. 无线程池,线程不休眠,并且清除thread_local 里面的线程变量;测试结果:无内存溢出
            case 1 :testWithThread(true, 0); break;
            // 测试情况2. 无线程池,线程不休眠,没有清除thread_local 里面的线程变量;测试结果:无内存溢出
            case 2 :testWithThread(false, 0); break;
            // 测试情况3. 无线程池,线程休眠1000毫秒,清除thread_local里面的线程的线程变量;测试结果:无内存溢出,但是新生代内存整体使用高
            case 3 :testWithThread(false, 1000); break;
            // 测试情况4. 无线程池,线程永久休眠(设置最大值),清除thread_local里面的线程的线程变量;测试结果:无内存溢出
            case 4 :testWithThread(true, Integer.MAX_VALUE); break;
            // 测试情况5. 有线程池,线程池大小50,线程不休眠,并且清除thread_local 里面的线程变量;测试结果:无内存溢出
            case 5 :testWithThreadPool(50,true,0); break;
            // 测试情况6. 有线程池,线程池大小50,线程不休眠,没有清除thread_local 里面的线程变量;测试结果:无内存溢出
            case 6 :testWithThreadPool(50,false,0); break;
            // 测试情况7. 有线程池,线程池大小50,线程无限休眠,并且清除thread_local 里面的线程变量;测试结果:无内存溢出
            case 7 :testWithThreadPool(50,true,Integer.MAX_VALUE); break;
            // 测试情况8. 有线程池,线程池大小1000,线程无限休眠,并且清除thread_local 里面的线程变量;测试结果:无内存溢出
            case 8 :testWithThreadPool(1000,true,Integer.MAX_VALUE); break;
            
            default :break;
        
        }        
    }

    public static void testWithThread(boolean clearThreadLocal, long sleepTime) {

        while (true) {
            try {
                Thread.sleep(100);
                new Thread(new TestTask(clearThreadLocal, sleepTime)).start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void testWithThreadPool(int poolSize,boolean clearThreadLocal, long sleepTime) {

        ExecutorService service = Executors.newFixedThreadPool(poolSize);
        while (true) {
            try {
                Thread.sleep(100);
                service.execute(new TestTask(clearThreadLocal, sleepTime));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static final byte[] allocateMem() {
        // 这里分配一个1M的对象
        byte[] b = new byte[1024 * 1024];
        return b;
    }

    static class TestTask implements Runnable {

        /** 是否清除上下文参数变量 */
        private boolean clearThreadLocal;
        /** 线程休眠时间 */
        private long sleepTime;

        public TestTask(boolean clearThreadLocal, long sleepTime) {
            this.clearThreadLocal = clearThreadLocal;
            this.sleepTime = sleepTime;
        }

        public void run() {
            try {
                ThreadLocalHolder.set(allocateMem());
                try {
                    // 大于0的时候才休眠,否则不休眠
                    if (sleepTime > 0) {
                        Thread.sleep(sleepTime);
                    }
                } catch (InterruptedException e) {

                }
            } finally {
                if (clearThreadLocal) {
                    ThreadLocalHolder.clear();
                }
            }
        }
    }

}

ThreadLocalHolder.java

public class ThreadLocalHolder {
    public static final ThreadLocal<Object> threadLocal = new ThreadLocal<Object>(); 
    public static final void set(byte [] b){
        threadLocal.set(b);
    }
    public static final void clear(){
        threadLocal.set(null);
    }
}

 

  • 测试结果分析:

无线程池的情况:测试用例1-4

下面是测试用例1 的垃圾回收日志

下面是测试用例2 的垃圾回收日志

对比分析测试用例1 和 测试用例2 的GC日志,发现基本上都差不多,说明是否清楚线程上下文变量不影响垃圾回收,对于无线程池的情况下,不会造成内存泄露

 

对于测试用例3,由于业务线程sleep 一秒钟,会导致业务系统中有产生大量的阻塞线程,理论上新生代内存会比较高,但是会保持到一定的范围,不会缓慢增长,导致内存溢出,通过分析了测试用例3的gc日志,发现符合理论上的分析,下面是测试用例3的垃圾回收日志

通过上述日志分析,发现老年代产生了一次垃圾回收,可能是开始大量线程休眠导致内存无法释放,这一部分线程持有的线程变量会在重新唤醒之后运行结束被回收,新生代的内存内存一直维持在4112K,也就是4个线程持有的线程变量。

 

对于测试用例4,由于线程一直sleep,无法对线程变量进行释放,导致了内存溢出。

 

有线程池的情况:测试用例5-8

对于测试用例5,开设了50个工作线程,每次使用线程完成之后,都会清除线程变量,垃圾回收日志和测试用例1以及测试用例2一样。

对于测试用例6,也开设了50个线程,但是使用完成之后,没有清除线程上下文,理论上会有50M内存无法进行回收,通过垃圾回收日志,符合我们的语气,下面是测试用例6的垃圾回收日志

通过日志分析,发现老年代回收比较频繁,主要是因为50个线程持有的50M空间一直无法彻底进行回收,而新生代空间不够(我们设置的是128M内存,新生代大概36M左右)。所有整体内存的使用量肯定一直在50M之上。

 

对于测试用例7,由于工作线程最多50个,即使线程一直休眠,再短时间内也不会导致内存溢出,长时间的情况下会出现内存溢出,这主要是因为任务队列空间没有限制,和有没有清除线程上下文变量没有关系,如果我们使用的有限队列,就不会出现这个问题。

对于测试用例8,由于工作线程有1000个,导致至少1000M的堆空间被使用,由于我们设置的最大堆是512M,导致结果溢出。系统的堆空间会从开始的128M逐步增长到512M,最后导致溢出,从gc日志来看,也符合理论上的判断。由于gc日志比较大,就不在贴出来了。

 

所以从上面的测试情况来看,线上上下文变量是否导致内存泄露,是需要区分情况的,如果线程变量所占的空间的比较小,小于10K,是不会出现内存泄露的,导致内存溢出的。如果线程变量所占的空间比较大,大于1M的情况下,出现的内存泄露和内存溢出的情况比较大。以上只是jdk1.7版本情况下的分析,个人认为jdk1.6版本的情况和1.7应该差不多,不会有太大的差别。

 

———————–下面是对ThreadLocal的分析————————————-

对于ThreadLocal的概念,很多人都是比较模糊的,只知道是线程本地变量,而具体这个本地变量是什么含义,有什么作用,如何使用等很多java开发工程师都不知道如何进行使用。从JDK的对ThreadLocal的解释来看

该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,

它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。 

ThreadLocal有一个ThreadLocalMap静态内部类,你可以简单理解为一个MAP,这个‘Map’为每个线程复制一个变量的‘拷贝’存储其中。每一个内部线程都有一个ThreadLocalMap对象。

当线程调用ThreadLocal.set(T object)方法设置变量时,首先获取当前线程引用,然后获取线程内部的ThreadLocalMap对象,设置map的key值为threadLocal对象,value为参数中的object。

当线程调用ThreadLocal.get()方法获取变量时,首先获取当前线程引用,以threadLocal对象为key去获取响应的ThreadLocalMap,如果此‘Map’不存在则初始化一个,否则返回其中的变量。

也就是说每个线程内部的 ThreadLocalMap对象中的key保存的threadLocal对象的引用,从ThreadLocalMap的源代码来看,对threadLocal的对象的引用是WeakReference,也就是弱引用。

下面一张图描述这三者的整体关系

对于一个正常的Map来说,我们一般会调用Map.clear方法来清空map,这样map里面的所有对象就会释放。调用map.remove(key)方法,会移除key对应的对象整个entry,这样key和value 就不会任何对象引用,被java虚拟机回收。

而Thread对象里面的ThreadLocalMap里面的key是ThreadLocal的对象的弱引用,如果ThreadLocal对象会回收,那么ThreadLocalMap就无法移除其对应的value,那么value对象就无法被回收,导致内存泄露。但是如果thread运行结束,整个线程对象被回收,那么value所引用的对象也就会被垃圾回收。

什么情况下 ThreadLocal对象会被回收了,典型的就是ThreadLocal对象作为局部对象来使用或者每次使用的时候都new了一个对象。所以一般情况下,ThreadLocal对象都是static的,确保不会被垃圾回收以及任何时候线程都能够访问到这个对象。

 写了下面一段代码进行测试,发现两个方法都没有导致内存溢出,对于没有使用线程池的方法来说,因为每次线程运行完就退出了,Map里面引用的所有对象都会被垃圾回收,所以没有关系,但是为什么线程池的方案也没有导致内存溢出了,主要原因是ThreadLocal.set方法的实现,会做一个将Key== null 的元素清理掉的工作。导致线程之前由于ThreadLocal对象回收之后,ThreadLocalMap中的value 也会被回收,可见设计者也注意到这个地方可能出现内存泄露,为了防止这种情况发生,从而清空ThreadLocalMap中null为空的元素。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadLocalLeakTest {

    public static void main(String[] args) {
        // 如果控制线程池的大小为50,不会导致内存溢出
        testWithThreadPool(50);
        // 也不会导致内存泄露
        testWithThread();
    }

    static class TestTask implements Runnable {

        public void run() {
            ThreadLocal tl = new ThreadLocal();
            // 确保threadLocal为局部对象,在退出run方法之后,没有任何强引用,可以被垃圾回收
            tl.set(allocateMem());
        }
    }

    public static void testWithThreadPool(int poolSize) {
        ExecutorService service = Executors.newFixedThreadPool(poolSize);
        while (true) {
            try {
                Thread.sleep(100);
                service.execute(new TestTask());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void testWithThread() {

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {

        }
        new Thread(new TestTask()).start();

    }

    public static final byte[] allocateMem() {
        // 这里分配一个1M的对象
        byte[] b = new byte[1024 * 1024 * 1];
        return b;
    }

}


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


ITeye推荐



数据库的查询优化

$
0
0
1.合理使用索引  

    索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。索引的使用要恰到好处,其使用原则如下:  

●在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。  

●在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。  

●在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。  

●如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。  

●使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的索引上进行检查。在一些数据库服务器上,索引可能失效或者因为频繁操作而使得读取效率降低,如果一个使用索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时进行修复。另外,当数据库表更新大量数据后,删除并重建索引可以提高查询速度。  

2.避免或简化排序  

应当简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次序产生输出时,优化器就避免了排序的步骤。以下是一些影响因素:  

●索引中不包括一个或几个待排序的列;  

●group by或order by子句中列的次序与索引的次序不一样;  

●排序的列来自不同的表。  

为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,如缩小排序的列的范围等。  

3.消除对大型表行数据的顺序存取  

在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询10亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如,两个表:学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个表要做连接,就要在“学号”这个连接字段上建立索引。  

还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取。下面的查询将强迫对orders表执行顺序操作:  

SELECT * FROM orders WHERE (customer_num=104 AND order_num>;1001) OR order_num=1008  

虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该改为如下语句:  

SELECT * FROM orders WHERE customer_num=104 AND order_num>;1001  

UNION  

SELECT * FROM orders WHERE order_num=1008  

这样就能利用索引路径处理查询。  

4.避免相关子查询  

一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。  

5.避免困难的正规表达式  

MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”  

即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM customer WHERE zipcode >;“98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。  

另外,还要避免非开始的子串。例如语句:SELECT * FROM customer WHERE zipcode[2,3] >;“80”,在where子句中采用了非开始子串,因而这个语句也不会使用索引。  

6.使用临时表加速查询  

把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:  

SELECT cust.name,rcvbles.balance,……other columns  

FROM cust,rcvbles  

WHERE cust.customer_id = rcvlbes.customer_id  

AND rcvblls.balance>;0  

AND cust.postcode>;“98000”  

ORDER BY cust.name  

如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序:  

SELECT cust.name,rcvbles.balance,……other columns  

FROM cust,rcvbles  

WHERE cust.customer_id = rcvlbes.customer_id  

AND rcvblls.balance>;0  

ORDER BY cust.name  

INTO TEMP cust_with_balance  

然后以下面的方式在临时表中查询:  

SELECT * FROM cust_with_balance  

WHERE postcode>;“98000”  

临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。  

注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意不要丢失数据。  

7.用排序来取代非顺序存取  

非顺序磁盘存取是最慢的操作,表现在磁盘存取臂的来回移动。SQL语句隐藏了这一情况,使得我们在写应用程序时很容易写出要求存取大量非顺序页的查询。  

有些时候,用数据库的排序能力来替代非顺序的存取能改进查询。
下面我们举一个制造公司的例子来说明如何进行查询优化。制造公司数据库中包括3个表,模式如下所示:  

1.part表  

零件号     零件描述        其他列  

(part_num) (part_desc)      (other column)  

102,032   Seageat 30G disk     ……  

500,049   Novel 10M network card  ……  

……  

2.vendor表  

厂商号      厂商名      其他列  

(vendor _num) (vendor_name) (other column)  

910,257     Seageat Corp   ……  

523,045     IBM Corp     ……  

……  

3.parven表  

零件号     厂商号     零件数量  

(part_num) (vendor_num) (part_amount)  

102,032    910,257    3,450,000  

234,423    321,001    4,000,000  

……  

下面的查询将在这些表上定期运行,并产生关于所有零件数量的报表:  

SELECT part_desc,vendor_name,part_amount  

FROM part,vendor,parven  

WHERE part.part_num=parven.part_num  

AND parven.vendor_num = vendor.vendor_num  

ORDER BY part.part_num  

如果不建立索引,上述查询代码的开销将十分巨大。为此,我们在零件号和厂商号上建立索引。索引的建立避免了在嵌套中反复扫描。关于表与索引的统计信息如下:  

表     行尺寸   行数量     每页行数量   数据页数量  

(table) (row size) (Row count) (Rows/Pages) (Data Pages)  

part    150     10,000    25       400  

Vendor   150     1,000     25       40  

Parven   13      15,000    300       50  

索引     键尺寸   每页键数量   页面数量  

(Indexes) (Key Size) (Keys/Page)   (Leaf Pages)  

part     4      500       20  

Vendor    4      500       2  

Parven    8      250       60  

看起来是个相对简单的3表连接,但是其查询开销是很大的。通过查看系统表可以看到,在part_num上和vendor_num上有簇索引,因此索引是按照物理顺序存放的。parven表没有特定的存放次序。这些表的大小说明从缓冲页中非顺序存取的成功率很小。此语句的优化查询规划是:首先从part中顺序读取400页,然后再对parven表非顺序存取1万次,每次2页(一个索引页、一个数据页),总计2万个磁盘页,最后对vendor表非顺序存取1.5万次,合3万个磁盘页。可以看出在这个索引好的连接上花费的磁盘存取为5.04万次。  

实际上,我们可以通过使用临时表分3个步骤来提高查询效率:  

1.从parven表中按vendor_num的次序读数据:  

SELECT part_num,vendor_num,price  

FROM parven  

ORDER BY vendor_num  

INTO temp pv_by_vn  

这个语句顺序读parven(50页),写一个临时表(50页),并排序。假定排序的开销为200页,总共是300页。  

2.把临时表和vendor表连接,把结果输出到一个临时表,并按part_num排序:  

SELECT pv_by_vn,* vendor.vendor_num  

FROM pv_by_vn,vendor  

WHERE pv_by_vn.vendor_num=vendor.vendor_num  

ORDER BY pv_by_vn.part_num  

INTO TMP pvvn_by_pn  

DROP TABLE pv_by_vn  

这个查询读取pv_by_vn(50页),它通过索引存取vendor表1.5万次,但由于按vendor_num次序排列,实际上只是通过索引顺序地读vendor表(40+2=42页),输出的表每页约95行,共160页。写并存取这些页引发5*160=800次的读写,索引共读写892页。  

3.把输出和part连接得到最后的结果:  

SELECT pvvn_by_pn.*,part.part_desc  

FROM pvvn_by_pn,part  

WHERE pvvn_by_pn.part_num=part.part_num  

DROP TABLE pvvn_by_pn  

这样,查询顺序地读pvvn_by_pn(160页),通过索引读part表1.5万次,由于建有索引,所以实际上进行1772次磁盘读写,优化比例为30∶1。笔者在Informix Dynamic Sever上做同样的实验,发现在时间耗费上的优化比例为5∶1(如果增加数据量,比例可能会更大)。  


小 结  


20%的代码用去了80%的时间,这是程序设计中的一个著名定律,在数据库应用程序中也同样如此。我们的优化要抓住关键问题,对于数据库应用程序来说,重点在于SQL的执行效率。查询优化的重点环节是使得数据库服务器少从磁盘中读数据以及顺序读页而不是非顺序读页。

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


ITeye推荐



线上JVM调查工具:JCPU和JMEM

$
0
0

以下内容由 [五四陈科学院]提供

之前的jkiller改名为jcpu,然后再加上jmem,齐活了,线上要再遇到问题,内存和CPU之外的也没啥其他办法了。

JMEM

https://github.com/54chen/jmem

用来定位莫名其妙的堆外内存问题。首先还是要先用jmap之类的看清楚是否是JVM堆内问题了再用此神物。

jmem.sh 用来靠gdb找到够大的内存块,直接dump到文件里。然后肉眼看吧。。。反正我没看出来,祝你好运。

pmap2stack.sh 弄出来大块的内存地址后,尝试在各种stack中帮你grep出来可以读懂的东东。

JCPU

https://github.com/54chen/jcpu

这个之前有介绍过,就是cpu占得比较猛的进程,直接打出来里面最费CPU的前五个堆栈。

具体用法都在项目的README上。


想快点找到作者也可以到Twitter上留言: @54chen
或者你懒得带梯子上墙,请到新浪微博: @54chen

张小龙内部邮件:微信团队的七大价值观

$
0
0

作者头像
作者: 黑板报值日生/产品观察家
我是极客公园黑板报认证值日生。搜罗好内容,分享给大家。
[核心提示]腾讯正式将微信独立成为事业群,与此同时张小龙也总结了微信团队的七条价值观。

腾讯昨天宣布对公司组织架构进行调整,“众望所归”地成立了维新事业群,负责微信基础平台、微信开放平台,以及微信支付拓展、O2O 等微信延伸业务的发展,并包括 邮箱、通讯录等产品开发和运营。 张小龙担任微信事业群总裁。

此外,腾讯同时宣布撤销电商控股公司,其中实物电商业务并入京东、O2O 业务并入微信事业群,虚拟业务并入企业发展事业群,电影票业务并入社交网络事业群,客服团队并入技术工程事业群。

随后张小龙发送了内部邮件,指出新成立的微信事业群同时吸纳了 ECC(腾讯电商控股)和财付通的部分团队。而他也首次正是总结了微信团队的七大理念和价值观。现节选摘录如下:

作为一个新的业务团队,我也希望之前微信团队的一些理念能继续保持和发扬。这些理念,其实也是公司一直倡导的。在这里总结几点:

1、做对用户有价值的事情。

我们经常会在各种权衡中做取舍,在任何时候,我们都要想,这个事情是不是从用户价值本身出发的来考虑的。如果我们想的策略和用户价值有违背,哪怕舍弃短期利益,也应该维护用户价值。让用户看到你的努力,而不是同事和上级。

2、保持我们自身的价值观,因为它会体现在我们的产品和服务中。

解决纷争时,它会帮我们做出决定。如果我们认为用户不能被骚扰,我们就不会在产品中做出骚扰用户的行为。如果我们没有一致的价值观,我们的产品和服务就会割裂为利益的集合体。不做个人价值观和产品价值观的双面人。

3、保持小团队,保持敏捷。

希望我们在 BG 成立规模变大后,还能保持小团队心态,避免陷入官僚化和流程化里面。我们曾经禁止写 PPT,认为那是形式化的体现。这有些武断,但目标是效率的最大化。我们还将继续限制招聘的人员数目,只招聘最优秀的人员加入团队。对一个优秀团队来说,人员也是少比多好。

4、学习和快速迭代比过去的经验更重要。

移动互联网变化太快,我们的产品和业务思路,也希望是面向新的环境而产生。

5、系统思维。

记住我们的愿景:连接人,连接企业,连接物体。让它们组成有机的自运转的系统,而不是构建分割的局部的商业模式。我们专注于基于连接能力的平台,并将平台开放给第三方接入,和第三方一起建造基于微信的人和服务的生态系统。系统思维也会帮助我们建造透明公正的商业体系,让系统在规则下运转,避免人为的干预。

6、让用户带来用户,口碑赢得口碑。

用互联网的网状传递效应来推动产品和服务。一个例子是一个小小的飞机大战可以引发一场手机游戏的风暴。我们处在一个人人互联的时代,如果我们能让一个用户说好,这个口碑就会传播出去。将我们的创造力体现在各个细节中。创意不是宏图大略,而在于我们每天工作的点点滴滴,用户都能感知到。

7、思辨胜于执行。

执行力很重要,但更希望我们的日常工作是一个思辨的过程。我们提倡争论,在工作中通过辩理来找到正确的解决方法,而非为了团队利益或者人际关系放弃思辨能力甚至思辨习惯。进步来自思辨。

极客观察均为极客公园原创报道,转载请注明原文链接。

原文地址: http://www.geekpark.net/read/view/204044

关注极客公园,即时获得最新内容: Twitter | 微信:极客公园 | 新浪微博 | 花瓣网 | 人人小站 | Google+ | 点点

移动教育六大剧变,刚需定未来

$
0
0

电脑上的在线教育方兴未艾,移动教育又来了。

教育领域是中国传统的强势市场,用户需求非常强烈。在强大的人口基数和飞速发展的互联网革命下,不断有机构尝试突破传统学校机制,探索新的教育形式。今年以来,各路诸侯先后发力,上市公司学大教育便是其中之一。

移动学习

这两天观摩了GMIC(全球移动互联网大会),在“移动价值峰会”上,学大集团CEO金鑫在演讲中提出,移动互联网时代,传统教育有六个剧变,其中重点谈及:从批量到个性、从固化到碎片、从自我到社交,而产业的真正希望在O2O(网上到网下)模式。

会后索性与金鑫关于产业话题进行了进一步探讨,以下为部分对话实录。

王冠雄:先解释一下你提出的移动互联网时代,传统教育的六个剧变吧?

学大金鑫:这六个剧变是传统教育所不具备的,而在移动设备上特性更强。

第一,从批量到个性。你之前也写过“相比电脑,手机更像人类器官的延伸”嘛,移动设备有更强的私人属性。传统教育是以老师为中心的,学生跟着进度整齐划一地往前走。移动时代会变成以学生为中心,根据每一个人的具体情况来分配教育资源。系统根据学生的数据分析,精准推荐内容,实现真正的个性化学习,而且是随时随地的。

第二,从封闭到开放。传统的教育模式是比较封闭的,在一个课堂里讲授都是规定好的。但是有了移动互联网,这个学习变的更加开放了,真正的做到所有开放的接受知识,甚至是全世界各个地方的学者之间的交流。

第三,从固化到碎片。其实使用电脑的时间也是相对固化的,而移动设备最大的特点就是随时随地,真把大家的时间撕成了碎片。通过移动互联网,可以把每一个碎片时间有效利用。根据课程、知识点、练习,三五分钟就都可以积累自己的学习。而且人都有惰性,传统一节课四五十分钟,中间有很多疲劳点,碎片时间很短,过程不会很累。

第四,从围墙到跨界。移动互联网给了我们机会跨界,学生可以学课堂内外的知识,而且这些知识都是一种非常丰富的手段,有视频,有音频,多媒体,甚至是还会有全新影像的呈现,跨界的技术使得我们可以看到,整个互联网对教育的影响。

第五,从自我到社交。以前每个人的学习主要在一个封闭环境里,都是以个体形态存在的。移动设备本身有极强的地理属性,陌生人社交、兴趣社交非常方便。通过它可以有自己的班级圈、学校圈、同课程圈,也可能分布在全国各地,陌生的学习者一起建立基于学习的圈子社交。因为学习不仅需要自我反馈,更多需要相互激励和比赛。

第六,单中心到多中心。现在因为信息的爆炸,学生获取信息的方便,所以说这种师生关系的角色发生了转换,实现了这种多中心的教育。

王冠雄:提这套理论体系是因为推了一阵移动教育总结而来的吧,现在你们情况如何?

学大金鑫:这六个剧变,我思考了很久,真正的感悟确实是从推APP之后更清晰的。“e学大”是今年3月20日上线的,一个多月就有14万真实用户,主要来自于我们的老师、学员。我们的第一步,是把学大的一万多名老师和正在上课的学员都搬上手机。我们的周活跃度在70—80%,因为学习是一个不间断的过程,这块还是黏性很高的。

王冠雄:为什么学大会全力布局O2O?

学大金鑫:我们主要做小学、中学教育,这个阶段教育最致命的一点就是这个年龄的学生自我学习意愿不强。纯粹做线上可能没有人管。这个特点,让纯线上的教育模式很难渗透重度参与型的K12。我们有在线的e学大平台,又有线下传统的一对一教学,上接互联网,下接地气。而且全程闭环,用户体验完整,学大对整个链条的掌控力也更强。

王冠雄:但未必整个移动教育都主打O2O吧,成人的公开课就不是。

学大金鑫:同意。我们是这么划分的:针对6岁前的学前教育,因为小孩智力发育还没成熟,主要是影响父母,因此方式还是线下为主,比如亲子班什么的。到了K12(6-18岁),就是适用于我刚才讲的O2O模式,走线上线下融合的方式。大学生及职场人群,这种18岁以上的成人教育,纯粹的在线教育会发挥越来越重要的作用。

王冠雄:为什么你们搞移动教育,没有像互联网产品那样爆发性传播?

学大金鑫:教育产品本身不具备强传播的优势,它更多是一种过程,而且每个人的体验都不同,非常个性化。而且教育本身有成本,过程本身比较累,不够轻松。教育就是这样需要有积累的行业。

王冠雄:我觉得运营可以适当游戏化,比如闯关答题什么的。

学大金鑫:是的,这是一个非常重要的趋势。现在游戏化运营教育产品,主要是背单词什么的。传统K12的以游戏化做题的不多,这个阶段学生的学业压力比较大,家长本身也比较排斥作业也搞游戏方式,担心孩子沉溺。我们也在摸索。

王冠雄:宣传上也可以学互联网啊,你看100教育找新东方开战眼球无数。

学大金鑫:互联网和教育行业风格不同。实话说,在中国所有行业中,社会对教育行业的要求是比较高的,传统上讲为人师表嘛。做教育的大部分都是老师出身,教育行业不愿意走口水战的方式。学大的风格是比较专业务实的,最重要的是,我们本来就是垂直行业老大,无需找假想敌。

王冠雄:关于在线教育,学大怎么考虑投资布局?

学大金鑫:我们也一直在关注投资这块。现在市场太热了,而且估值是非常高的。现在,业务成熟,利润上百万的线下教育机构,估值也就千万级人民币,而线上教育用户哪怕只有几万,即便亏损,估值就是千万级美金!对我们来说,还是要对股东负责,适度平衡布局和利润。而且现在市场处于早期阶段,实话说让人眼睛一亮的好产品非常少,如果出现机会我们会抓住的。

王冠雄:移动教育主要靠什么获取用户,你们对移动流量怎么看?

学大金鑫:PC上,整个教育行业目前效果最好的还是百度的搜索引擎推广。现在整个移动流量非常碎片化,我们微博一直有推广,微信上“服务号+订阅号”双管齐下。我个人比较重视朋友圈营销,你复盘的土曼朋友圈营销经典案例也研究过,但教育产品决策过程比较长,也无法作为礼品,只能慢慢去摸索。总之,最核心的还是如何低成本获取用户。

王冠雄:最后要不要评论一下对手和展望一下移动教育前景。

学大金鑫:教育不是零和游戏,我们和友商的客群不同、路子也不同。我的价值观是,做生意不必非得踩别人才能成长。移动教育产业要产生规模型的收入,还是要靠闭环。即通过O2O的方式把互联网和传统资源对接、配置,做个性化教育。需求当然得盯着刚需,K12机会是最大的。我个人感觉,产业真正成熟还需要三年左右。(文/王冠雄)

© 2006-2014 by 望月的博客 | 固定链接 | 我要评论 | 广告投放 | 产品推荐
也许您还喜欢:

旅行中的移动互联网生活

UC掀移动搜索战,请注意节操

国内移动互联网几个可能的发展趋势

google+digg=未来的搜索引擎?

动动手指,商流、物流全解决 让移动互联开创物流新格局
无觅
Viewing all 15843 articles
Browse latest View live


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