jar包冲突解决

原文 – 微博

“基础架构部的jar包冲突解决”,这是我们各种中间件sdk最头痛的事情,最怕升级之后sdk的依赖包影响了业务本身的依赖包,或者另一个sdk的。

业界解决方案包括osgi, java modules,springboot式的超级pom文件,各种自产的classloader方案比如蚂蚁金服的SOFAArk,我们也自研了一个但没上线。

最近爱用的方案是maven-shade plugin,将sdk与容易冲突的依赖包如httpclient打包在一起,修改hc的package名比如改成cfgcenter.org.apache,这样就不和谁冲突了,然后坑粗吭哧修改所有import的地方。

天啊,以前我们是自己拉httpclient的源码下来手工修改的,工作量巨大,现在一句plugin配置搞定了,后面都是基于asm的可靠干活。

(但还是人工留意下有没有基于类名反射的情况)

和菜头翻译 如何不靠运气致富

  1. Seek wealth, not money or status. Wealth is having assets that earn while you sleep. Money is how we transfer time and wealth. Status is your place in the social hierarchy.

去寻求财富,而非金钱或地位。财富就是你拥有资产,而资产在你睡觉的时候都还在为你赚钱;金钱是我们转换时间和财富的工具;身份是你在社会等级体系里所处的位置。

  1. Understand that ethical wealth creation is possible. If you secretly despise wealth, it will elude you.

要明白一件事:一个人完全可以不靠坑蒙拐骗站着赚取财富。如果你在暗中鄙视财富,那么财富也会躲着你。

  1. Ignore people playing status games. They gain status by attacking people playing wealth creation games.

别去理会那些热衷于玩身份游戏的人,他们通过攻击那些创造财富的人以获得自己的身份。

4.You’re not going to get rich renting out your time. You must own equity — a piece of a business — to gain your financial freedom.

你不会通过出租自己的时间而变得富有。你必须拥有产权,也就是生意的一部分,以此才能赢得个人财务自由。

5.You will get rich by giving society what it wants but do

es not yet know how to get. At scale.

提供社会大众想要但是他们还不知道如何获取的东西,你就会因此而致富。但有一点:你必须规模化地供应社会。

6.Pick an industry where you can play long term games with long term people.

选择一个你可以长期从事的产业,寻找一批可以一起长期共事的人。

7.The Internet has massively broadened the possible space of careers. Most people haven’t figured this out yet.

互联网极大拓展了一个人职业生涯的可能性。绝大多数人对此毫无认知。

8.Play iterated games. All the returns in life, whether in wealth, relationships, or knowledge, come from compound interest.

玩就玩复利游戏。无论是财富,人际关系或者是知识,所有你人生里获得的回报,都来自复利。

9.Pick business partners with high intelligence, energy, and, above all, integrity.

在选择商业合作伙伴的时候,选择那些高智商、精力旺盛的家伙,但在这一切之上,他应该是个正直诚实的人。

10.Don’t partner with cynics and pessimists. Their beliefs are self-fulfilling.

不要和愤世嫉俗者和悲观主义者合作,因为他们会任由坏事发生,以此证明他们的负面看法是正确的。

11.Learn to sell. Learn to build. If you can do both, you will be unstoppable.

学会如何销售,学会如何创建。如果你同时能做到这两件事,你的成功将无可阻挡。

12.Arm yourself with specific knowledge, accountability, and leverage.

用独到知识,责任感和杠杆武装自己。

13.Specific knowledge is knowledge that you cannot be trained for. If society can train you, it can train someone else, and replace you.

独到知识是那种不可以通过培训而获得的知识。这是因为,如果这种知识可以经由培训而得,那么其他人同样也可以,并且以此取代你。

14.Specific knowledge is found by pursuing your genuine curiosity and passion rather than whatever is hot right now.

在真正的好奇心和热情驱使你前进的路上,你更有可能获得独到知识,而不是在追逐潮流热点的闻风起舞脚步里。

15.Building specific knowledge will feel like play to you but will look like work to others.

创建独到知识的过程对于你就像是在玩,而对于别人则像是工作。

16.When specific knowledge is taught, it’s through apprenticeships, not schools.

不能通过学校教育教会一个人独到知识,它只能通过学徒制口传身教。

17.Specific knowledge is often highly technical or creative. It cannot be outsourced or automated.

独到知识通常极富技术性和创造性,因此它不能被外包或自动实现。

18.Embrace accountability, and take business risks under your own name. Society will reward you with responsibility, equity, and leverage.

拥抱责任感,押上自己的声誉以承担商业风险。社会也会以责任,产权和杠杆作为回报。

19.The most accountable people have singular, public, and risky brands: Oprah, Trump, Kanye, Elon.

最具责任感的人都具有独一无二的、世人皆知的、敢于冒险的个性特征,如奥普拉、川普、坎耶、埃隆。

20.“Give me a lever long enough, and a place to stand, and I will move the earth.” — Archimedes

只要给我一根足够长的杠杆,一处可以立足的地方,我就能撬起地球。——阿基米德

21.Fortunes require leverage. Business leverage comes from capital, people, and products with no marginal cost of replication (code and media).

财富增长需要使用杠杆。商业杠杆有三个来源:1、资本;2、人力;3、复制起来边际成本为零的产品(如:代码和媒体)。

22.Capital means money. To raise money, apply your specific knowledge, with accountability, and show resulting good judgment.

资本的意思就是钱。想要融资,那就运用你的独到知识,配合你责任感,展示出你良好的判断力。

23.Labor means people working for you. It’s the oldest and most fought-over form of leverage. Labor leverage will impress your parents, but don’t waste your life chasing it.

人力指的就是为你干活的人,它是最古老也是争夺最激烈的杠杆。人力杠杆会让你父母因为你手下有许多人为你工作而感到骄傲,但你不要浪费生命去追求这一点。

24.Capital and labor are permissioned leverage. Everyone is chasing capital, but someone has to give it to you. Everyone is trying to lead, but someone has to follow you.

资本和劳动力是需要征得许可才能使用的杠杆。每个人都在追逐资本,但总得有个什么人给你才行;每个人都想要领导其它人,但总得有什么人愿意跟着你才行。

25.Code and media are permissionless leverage. They’re the leverage behind the newly rich. You can create software and media that works for you while you sleep.

代码和媒体是无需要许可即可使用的杠杆。它们是新贵人群背后的杠杆,你可以通过自己创建的软件和媒体,在睡觉时仍然为你干活。

26.An army of robots is freely available — it’s just packed in data centers for heat and space efficiency. Use it.

一支机器人军团已经集结待命,只是为了节约空间和热效能,它们被打包放进数据中心。去用吧。

27.If you can’t code, write books and blogs, record videos and podcasts.

如果你不会编程,那你还可以写书和博客,或者做视频或者音频节目。

28.Leverage is a force multiplier for your judgement.

杠杆能够成倍地放大你的判断力(所产生的效能)。

29.Judgement requires experience, but can be built faster by learning foundational skills.

判断力需要经验,但它可以通过学习基本技能的方法更快速地建立起来。

30.There is no skill called “business.” Avoid business magazines and business classes.

并不存在一种叫做“商业”的能力。尽量避开商业杂志和商业课程。

31.Study microeconomics, game theory, psychology, persuasion, ethics, mathematics, and computers.

去学习微观经济学、博弈论、心理学、说服术、伦理学、数学和计算机科学。

32.Reading is faster than listening. Doing is faster than watching.

读比听快,做比看快。

33.You should be too busy to “do coffee,” while still keeping an uncluttered calendar.

你应该忙得没有社交的时间才对,与此同时你应该始终保证日程安排井井有条。

34.Set and enforce an aspirational personal hourly rate. If fixing a problem will save less than your hourly rate, ignore it. If outsourcing a task will cost less than your hourly rate, outsource it.

你应该为自己设定一个有抱负的个人时薪数,并且坚持执行。如果解决一个问题所能节省下来的成本低于你的个人时薪,那就忽略这个问题好了;如果一项任务的外包成本低于你的个人时薪,就把它外包出去。

35.Work as hard as you can. Even though who you work with and what you work on are more important than how hard you work.

尽管你跟谁一起工作、做什么工作,要远比你的努力程度更加重要。但还是要倾尽全力去工作。

36.Become the best in the world at what you do. Keep redefining what you do until this is true.

你所做的事情,要努力做到世界最好。不断重新定义你在做什么,直到真的做到世界最好。

37.There are no get rich quick schemes. That’s just someone else getting rich off you.

这个世界上并没有快速赚钱致富的方法,如果你想要找寻这种方法,那它只会让别人从你身上赚钱致富。

38.Apply specific knowledge, with leverage, and eventually you will get what you deserve.

运用你的独到知识,配合上杠杆,最终你会得到你应该得到的东西。

39.When you’re finally wealthy, you’ll realize that it wasn’t what you were seeking in the first place. But that’s for another day.

终有一天当你变得富有,你会发现那一切并不是你最开始想要的东西。但是那就是另外一回事了。

注释:

1、财富就是你睡着觉,你的资产也在为你继续赚钱。这是一个越来越被广泛接受的定义。Naval Ravikant是硅谷狂热的数字货币支持者,所以,他的话另有所指。从前后文来看,他所谓的资产并不等于是传统意义上的房产、股票、收藏,而是偏向于他反复提及的:软件和媒体。

2、出租时间概念,许多人理解为打工,认为打工就是出租自己的时间以换取金钱。其实并非如此,Naval所指的出租时间概念,指的是一个人的财富增长,是否直接关系到他的时间。一个小卖部的老板,他并不为谁打工,但是他的财富增长需要他长时间守在店里,因此,他依然是出租时间换钱。但一个淘宝点卡店老板则不同,他的点卡销售是全自动的,不需要24小时守着,而且也不需要只做这一样生意。这就是Naval所谓互联网拓宽了个人职业生涯的一个例子。

3、equity我翻译为产权,不是一个很好的翻法。但是Naval前文提到assets,很明显,作为投资人他非常清楚地知道这两个字眼之间的区别。equity无论是翻译为股票、权益或者是资产,原文说“ You must own equity — a piece of a business — to gain your financial freedom.”,这是和出租时间概念做对应的。出租时间的人,在商业链条里作为生产资料出现,不拥有任何产权,也就无法通过商业行为获利,所以,我这里勉强翻译为产权。

4、specific knowledge我翻译为独到知识,没有翻译为特定知识、专业知识或者是特殊知识。原因是在我的理解中,specific knowledge不是书本知识,也不是学校教授的知识,更不可能在网上免费获取。一方面,它只能提供自己实践来获取;另一方面,它只能通过前人口耳相传。这种知识是做成一件事情的关键,属于知识体系中不共的那一部分。所以,我翻译为独到知识。

5、“Give me a lever long enough, and a place to stand, and I will move the earth.” — Archimedes 这话不像是阿基米德说的。更像是一次抬杠的结果:

“给我一个支点,我就能撬起地球!”

“那么,您站在哪儿呢?”

“好吧,给我一个支点,再给我一个站立的地方,我就能撬起地球。”

“那么,您用空气就能撬起地球了?”

“好吧,给我一根足够长的杠杆,一处可以立足的地方,我就可以翘起地球!”

“那么,阿基米德先生,支点又不需要了吗?”

“滚!”

6、accountability我本想翻译为“靠谱程度”,想想还是算了。

7、号称是“四十条语录”,但是我就找见了39条。

8、结合上下文看,Leverage一词始终翻译为“杠杆”其实也不大对头。Naval一再强调代码、博客、播客、视频节目,我觉得Leverage在他那里,有些时候应该相当于是个人影响力的代名词,或者可以简单理解为放大器。

价值投资

原文链接

1,炒股,

有时候需要像作家一样,

有灵感。

今天中午,

就是灵感突然降临,

将目前的股市生态,

说得明明白白了。

有点小得意,

于是把这个“灵感”再重复一遍,

加深大家的印象。

你真明白股市生态的真相了,

炒股就会变得很简单了。

2,目前,股市,

在发生深刻而清晰的变化。

(1)80%的股票,

慢慢变得无人问津。

(2)10%的股票,

机构们在玩“价值投资”。

(3)剩下的10%,

被全市场的资金,

当成“筹码”,

用来炒作,

玩互掏口袋的游戏。

这就是俗称的,

赌博游戏。

3,你看明白这样的市场格局,

炒股就变得简单了:

(1)80%持有“死股”不动的,

就是来这个市场亏钱玩耍的。

而且他们亏的钱,

像一个黑洞,

没有人赢。

全部消失在风中。

亏给空气了。

(2)学“价值投资”的人,

越来越多了。

包括专业机构。

包括一些半懂不懂的“专家”。

其实,

做价值投资,

你都不需要小学3年级以上的文化。

运哥教你的,

就是幼儿园小盆友都能掌握的方法。

最简单的价值投资方法:

在每天成交金额前100名里,

找上升趋势的票,

找指数下跌和个股下跌的共振点,

买入,

然后持有不动。

这就是“价值投资”了!

赚了钱,

你在任何位置卖出,

都是价值投资。

亏钱的不是价值投资。

这个价值投资投资法的原理是:

市场的聪明资金,

都会买好股票。

那么,

好股票,

必然会成交活跃。

那么,

你买成交金额排前100名的股票,

不是最正宗的价值投资了吗?

那些家伙,

把价值投资,

给你说得神神秘秘的东西,

其实就是这么简单!

4,以上3条,

就是目前股市的全部秘密。

你摸透了这个秘密,

炒股赚钱,

是不是就变成很简单的事情了?

通过以上分析,

你知道炒股,

为什么那么容易亏钱了吧?

你要做的,

就是找准你的定位。

赚你可以把握的钱。

这,

才是你要考虑的第一重要的事情。

MyBatis SQL 注入案例

安全的用法

<select id="getPerson" parameterType="int" resultType="org.application.vo.Person">
SELECT * FROM PERSON WHERE ID = #{id}
</select>

使用 #{} 传参数 会使用PreparedStatement 执行sql 例如:

/* Comparable JDBC code */
String selectPerson = "SELECT * FROM PERSON WHERE ID = ?"; 
PreparedStatement ps = conn.prepareStatement(selectPerson); 
ps.setInt(1, id);

其他一些正确案例

<insert id="insertPerson" parameterType="org.application.vo.Person">
insert into Person (id, name, email, phone)
values (#{id}, #{name}, #{email}, #{phone})
</insert>
 
<update id="updatePerson" parameterType="org.application.vo.Person">
update Person set name = #{name}, email = #{email}, phone = #{phone}
where id = #{id}
</update>
 
<delete id="deletePerson" parameterType="int">
delete from Person where id = #{id}
</delete>

易受攻击的用法

<select id="getPerson" parameterType="string" resultType="org.application.vo.Person">
SELECT * FROM PERSON WHERE NAME = #{name} AND PHONE LIKE '${phone}'; 
</select>
如果入参是: "1%' OR '1'='1"
SELECT * FROM PERSON WHERE NAME = ? and PHONE LIKE '1%' OR '1' = '1'
如果入参是:"A%'; DELETE FROM PERSON; --"
SELECT * FROM PERSON WHERE NAME = ? and PHONE LIKE 'A%'; DELETE FROM PERSON; --'

其他一些错误案例

<insert id="insertPerson" parameterType="org.application.vo.Person">
insert into Person (id, name, email, phone)
values (#{id}, #{name}, #{email}, ${phone})
</insert>
 
<update id="updatePerson" parameterType="org.application.vo.Person">
update Person set phone = ${phone}
where id = #{id}
</update>
  
<delete id="deletePerson" parameterType="int">
delete from Person where id = ${id}
</delete>

尚硅谷大数据全套教程

2020最新路线:cv5213600

【推荐观看】
Linux(韩顺平主讲,大数据专用):BV1ZW411k7Qh
Shell:BV1hW41167NW
Hadoop:BV1cW411r7c5
Zookeeper:BV1PW411r7iP
Hive(升级版):BV1W4411B7cN
Flume(升级版):BV184411B7kU
Kafka(升级版):BV1a4411B7V9
HBase(升级版):BV1Y4411B7jy
HA:BV1zb411P7KY
Sqoop:BV1jb411A7tc
Azkaban:BV1t4411B7Rh
Oozie:BV1jb411A7Ar
Scala:BV15t411H776
Scala数据结构和算法:BV1zb411h78b

【项目实战】
电信客服:BV17t411W7wZ
机器学习与推荐系统:BV1R4411N78S
电商推荐系统:BV1X4411Y7ZN
电商数仓:BV1L4411K7hW
Flink:BV1gJ411Q72x
阿里云数仓(离线):BV1AJ411Q7ox
阿里云数仓(实时):BV1dJ411k7BE

☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆

《OOD启思录》:61条面向对象设计的经验原则

摘自《OOD启思录》 Arthur J.Riel【著】; 鲍志云【译】

“你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚。但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起。” —– Arthur J.Riel

(1) 所有数据都应该隐藏在所在的类的内部。

(2) 类的使用者必须依赖类的共有接口,但类不能依赖它的使用者。

(3) 尽量减少类的协议中的消息。

(4) 实现所有类都理解的最基本公有接口[例如,拷贝操作(深拷贝和浅拷贝)、相等性判断、正确输出内容、从ASCII描述解析等等]。

(5) 不要把实现细节(例如放置共用代码的私有函数)放到类的公有接口中。 如果类的两个方法有一段公共代码,那么就可以创建一个防止这些公共代码的私有函数。

(6) 不要以用户无法使用或不感兴趣的东西扰乱类的公有接口。

(7) 类之间应该零耦合,或者只有导出耦合关系。也即,一个类要么同另一个类毫无关系,要么只使用另一个类的公有接口中的操作。

(8) 类应该只表示一个关键抽象。包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包影响,则将对包中的所有类产生影响,而对其他的包不造成任何影响 .

(9) 把相关的数据和行为集中放置。设计者应当留意那些通过get之类操作从别的对象中获取数据的对象。这种类型的行为暗示着这条经验原则被违反了。

(10) 把不相关的信息放在另一个类中(也即:互不沟通的行为)。朝着稳定的方向进行依赖.

(11) 确保你为之建模的抽象概念是类,而不只是对象扮演的角色。

(12) 在水平方向上尽可能统一地分布系统功能,也即:按照设计,顶层类应当统一地共享工作。

(13) 在你的系统中不要创建全能类/对象。对名字包含Driver、Manager、System、Susystem的类要特别多加小心。规划一个接口而不是实现一个接口。

(14) 对公共接口中定义了大量访问方法的类多加小心。大量访问方法意味着相关数据和行为没有集中存放。

(15) 对包含太多互不沟通的行为的类多加小心。这个问题的另一表现是在你的应用程序中的类的公有接口中创建了很多的get和set函数。

(16) 在由同用户界面交互的面向对象模型构成的应用程序中,模型不应该依赖于界面,界面则应当依赖于模型。

(17) 尽可能地按照现实世界建模(我们常常为了遵守系统功能分布原则、避免全能类原则以及集中放置相关数据和行为的原则而违背这条原则) 。

(18) 从你的设计中去除不需要的类。一般来说,我们会把这个类降级成一个属性。

(19) 去除系统外的类。系统外的类的特点是,抽象地看它们只往系统领域发送消息但并不接受系统领域内其他类发出的消息。

(20) 不要把操作变成类。质疑任何名字是动词或者派生自动词的类,特别是只有一个有意义行为的类。考虑一下那个有意义的行为是否应当迁移到已经存在或者尚未发现的某个类中。

(21) 我们在创建应用程序的分析模型时常常引入代理类。在设计阶段,我们常会发现很多代理没有用的,应当去除。

(22) 尽量减少类的协作者的数量。一个类用到的其他类的数目应当尽量少。

(23) 尽量减少类和协作者之间传递的消息的数量。

(24) 尽量减少类和协作者之间的协作量,也即:减少类和协作者之间传递的不同消息的数量。

(25) 尽量减少类的扇出,也即:减少类定义的消息数和发送的消息数的乘积。

(26) 如果类包含另一个类的对象,那么包含类应当给被包含的对象发送消息。也即:包含关系总是意味着使用关系。

(27) 类中定义的大多数方法都应当在大多数时间里使用大多数数据成员。

(28) 类包含的对象数目不应当超过开发者短期记忆的容量。这个数目常常是6。当类包含多于6个数据成员时,可以把逻辑相关的数据成员划分为一组,然后用一个新的包含类去包含这一组成员。

(29) 让系统功能在窄而深的继承体系中垂直分布。

(30) 在实现语义约束时,最好根据类定义来实现。这常常会导致类泛滥成灾,在这种情况下,约束应当在类的行为中实现,通常是在构造函数中实现,但不是必须如此。

(31) 在类的构造函数中实现语义约束时,把约束测试放在构造函数领域所允许的尽量深的包含层次中。

(32) 约束所依赖的语义信息如果经常改变,那么最好放在一个集中式的第3方对象中。

(33) 约束所依赖的语义信息如果很少改变,那么最好分布在约束所涉及的各个类中。

(34) 类必须知道它包含什么,但是不能知道谁包含它。

(35) 共享字面范围(也就是被同一个类所包含)的对象相互之间不应当有使用关系。

(36) 继承只应被用来为特化层次结构建模。

(37) 派生类必须知道基类,基类不应该知道关于它们的派生类的任何信息。

(38) 基类中的所有数据都应当是私有的,不要使用保护数据。类的设计者永远都不应该把类的使用者不需要的东西放在公有接口中。

(39) 在理论上,继承层次体系应当深一点,越深越好。

(40) 在实践中,继承层次体系的深度不应当超出一个普通人的短期记忆能力。一个广为接受的深度值是6。

(41) 所有的抽象类都应当是基类。

(42) 所有的基类都应当是抽象类。

(43) 把数据、行为和/或接口的共性尽可能地放到继承层次体系的高端。

(44) 如果两个或更多个类共享公共数据(但没有公共行为),那么应当把公共数据放在一个类中,每个共享这个数据的类都包含这个类。

(45) 如果两个或更多个类有共同的数据和行为(就是方法),那么这些类的每一个都应当从一个表示了这些数据和方法的公共基类继承。

(46) 如果两个或更多个类共享公共接口(指的是消息,而不是方法),那么只有他们需要被多态地使用时,他们才应当从一个公共基类继承。

(47) 对对象类型的显示的分情况分析一般是错误的。在大多数这样的情况下,设计者应当使用多态。

(48) 对属性值的显示的分情况分析常常是错误的。类应当解耦合成一个继承层次结构,每个属性值都被变换成一个派生类。

(49) 不要通过继承关系来为类的动态语义建模。试图用静态语义关系来为动态语义建模会导致在运行时切换类型。

(50) 不要把类的对象变成派生类。对任何只有一个实例的派生类都要多加小心。

(51) 如果你觉得需要在运行时刻创建新的类,那么退后一步以认清你要创建的是对象。现在,把这些对象概括成一个类。

(52) 在派生类中用空方法(也就是什么也不做的方法)来覆写基类中的方法应当是非法的。

(53) 不要把可选包含同对继承的需要相混淆。把可选包含建模成继承会带来泛滥成灾的类。

(54) 在创建继承层次时,试着创建可复用的框架,而不是可复用的组件。

(55) 如果你在设计中使用了多重继承,先假设你犯了错误。如果没犯错误,你需要设法证明。

(56) 只要在面向对象设计中用到了继承,问自己两个问题:(1)派生类是否是它继承的那个东西的一个特殊类型?(2)基类是不是派生类的一部分?

(57) 如果你在一个面向对象设计中发现了多重继承关系,确保没有哪个基类实际上是另一个基类的派生类。

(58) 在面向对象设计中如果你需要在包含关系和关联关系间作出选择,请选择包含关系。

(59) 不要把全局数据或全局函数用于类的对象的薄记工作。应当使用类变量或类方法。

(60) 面向对象设计者不应当让物理设计准则来破坏他们的逻辑设计。但是,在对逻辑设计作出决策的过程中我们经常用到物理设计准则。

(61) 不要绕开公共接口去修改对象的状态。

说说职场中的交流和沟通 [转发]

原文链接

关于职场的交流和沟通,记得我之前好像写过一些。来 Coinbase 已经有快两年了,有了不少的成长,尤其是在职场交流上。说起来,每个公司都有核心文化(core values),Coinbase 的四大核心文化之一,便是清楚有效的交流(clear communication)。所以能感觉到,这里的人,尤其是管理者,对交流和沟通的标杆是相当高的。文化和氛围这东西可意会但很难言传,所以我只能尽我最大努力简单说说自己的体会和经验吧。

交流大致分四种,一种是各种书面的文档、email,自己写好或者发出去,别人大部分时候是异步的阅读,然后有些情况会有评论(comment)或者回复;第二种是一对一的对话,这可能是面对面的交谈,也可能是 slack 这样的工具上的对话;第三种是组会,或者是 slack 群里面多人的讨论;最后一种是演讲(presentation),就是你一个人给大家讲。

先说一些适用于所有情况的基本准则。

首先就是从交流对象的角度去考虑话要怎么说。职场的交流沟通和朋友相处间的交流,最大的区别:交流是你工作的一部分。换句话来说,在职场你说话写字不是为了抒发情感,不是为了发泄感情,而是为了办好事情,让对方了解你想让他了解到的问题和情况,或者是你对一个问题的看法或想法。这里面可能和平时说话不大一样的地方,就是首先你要把对方作为中心,而不是你自己。你要说的,不是你想说的,或者你觉得正确的语序和方式;而是怎么说,会让对方会感兴趣,一下子就明白,并且印象深刻。

我遇到过组里的人,跟外组的人解释一个东西,从头到尾一二三,每条都对。但是外组的人听完了,虽然点头,但是其实这三条里,真正需要那个组的人注意或者帮忙的,就完全被弱化了,甚至不知道对方是不是真的会完全领会基于这三点,他该注意什么,该做什么。所以这种情况,后面加一句:这里你们可能尤其需要注意的,是xxx。这样就能极大强化对话的效果。

另外,说话不在多,不在快,而在准确切到重点上。事实上,尤其是口头的交流,你说多了、快了、除非对方已经知道大部分的内容,大部分你说的,都成了无可奈何的耳旁风。先把最重要的点说了,具体那些细节,等着别人来问再给更多,而不是一股脑儿都倒给对方,大部分时候效果会好很多。

如果是回答问题,确定你真的明白了对方想问的是什么再回答。开会的时候遇到一个人问了问题A,结果另一个人回答了问题B。如果你还不好插话,是不是特别着急?

还有的时候对方因为对一些具体细节不熟悉,问的问题甚至可能不是他真正困惑想问的问题。这种情况在上级问一个下级所属事务相关的问题,但是对那部分事务又不那么熟悉的时候尤为经常发生,这时候如果问题听起来似乎太简单或者太奇怪,你就要试着去推测对方是不是应该想了解另一个问题只是问的方式不对。推测完了先确认你推测的对不对:“您的问题答案是xxx,但我想您是不是想了解xxx的意思?” 这样的去确认,如果对方说不是,你那个答案就够了,那就算了。如果说是,这样,你才有机会回答了实际的问题。

演讲还是组会,说话的时候不要只盯着自己的电脑或者大屏幕,看看大家的表情和眼神,看看是不是已经云游方外了,还是有困惑的表情。如果你不能把大家的注意力带到你身上,那你说再多也只是背景噪音。

其次就是养成一个习惯,帮别人划重点。这个在书面交流中尤其重要。什么意思呢?如果是文档,你的 summary 或者 overview 就要确保假如别人没时间看完,他仍然能准确知道整个文档主要的中心思想。如果是 email,我发长的 email 一定都有两个要素:一个就是最前面的 TL;DR (too long, don’t read),一个就是 email 里一定会有 10% 左右的文字是黑体

因为职位需要,现在经常发周报,以及一些给高层或者整个大组的信件。我们都知道,长的信件除非是那种重要到他们不看会后悔的,大部分人可能看个标题很快就标注已读并存档。谁也没有时间和耐心去在你的信件里找有没有什么值得注意的。这个时候,前面的 TL;DR 确保是你用一句话描述了的大家绝对不能错过的内容的概述。如果需要更多讲解,加一句:see details below。这就帮助大家快速决定是不是有必要去读你的全文。

然后 email 主体再学会用黑体点出最重要的内容,这样别人如果只有30秒跳读你的信件,就会读所有的黑体部分。只要你重点没划错,你就帮你自己让别人没有错过你想传达的信息。

以前遇到别人说:我 email 里都写了啊,你自己没注意看。我会觉得,他说的很有道理。但是现在的我就不一定认同。如果你真的能把 email 写到帮别人划重点,并且划对,其实别人漏掉重要信息的可能性会极小。

最后说一说哪些是满分之外的那100分。

如果你刚和另一个人讨论一个问题有了一些方案、思路、想法、尤其是决定时,第一时间尽可能把讨论内容汇总群发 email 给或者 shared slack 给所有可能相关的人。这一点对于经常需要做决定的人尤其重要。否则你可能会遇到后面有另一个不同的决定,或者有些事情和你的决定好像有矛盾,然后你再去说:我和谁谁谁早谈过了,决定要怎么怎么。你没告诉到所有该告诉的人,谁知道你决定了什么啊。

但是要注意的是,群发的目的是让大家得到一致的信息(on the same page), 内容发出去前只要条件允许,请务必先让参与和你讨论的人过目确认,避免不必要的误解。而不是让和你讨论的人从群发消息上意识到你俩的理解有出入,然后炸了。好的处理,你先给参与讨论的人看了,说我这样发出去有问题吗,对方确认没有问题,这件事就很圆满。没有这一步,到时候那人说:我什么时候说xxx了,根本不是那个意思,那你就去吵吧。吵赢吵输,你都丢掉了一部分人的信任。

任何时候不要给你老板一个惊喜。在没有十足把握下,重要的或者敏感的东西发出去之前,先让老板看一下。他忙或者信任你说不用看了,那是另一回事。但是这样问一下,可以避免很多让你后悔的情况。甚至,哪些东西该由你说,哪些东西你就该等着你的老板先去说,尤其不要出格。

有两个以上人问你同一个问题,就不要反复口头回答或者私聊里回答。尤其是回答起来还比较费劲的问题,把答案记录下来放在一个共享的文档或者网页上,作为标准答案,不断去完善这个标准答案。下次再有人问、再有100个人问,给他发个答案链接就行。就不用去抱怨为什么大家总问你这个问题了。

同样,如果有多个人对你的某个设计、说法、方案有误解,就可能不是别人的理解问题,而是确实容易引起误会,这个时候,静下心来去看看怎么可以做到或者写到更好,而不要轻易觉得是自己找不到知己,或者别人智商不够。

先写这么多吧,职场的交流和沟通绝对是门大学问。初级的人能把事情说对明白(但别人能不能懂要看其理解力高低),中级的人能把大部分人都说懂,高级的人是通过交流和沟通把一整个团队、甚至别的团队结结实实拉到一起,达到自己想要的目的,把问题解决。当然,我也还一直在学习,共勉之。

最短路径算法

import java.util.PriorityQueue;

public class Dijkstra {

	/**
	 * 1.假设带权有向图G的顶点集合为V,起始点为V0。
	 * 2.初始S={V0},T=V-S={其余顶点},其中集合S表示已经计算出最短距离的顶点,T是还没计算的剩余顶点。
	 * 3.初始化V0到其余各点的距离,D(V0,Vi)代表V0到Vi的最短距离,按如下规则。
	 * 3.若V0可以直接到达某个顶点Vi,则将边的权值赋给(V0,Vi),否则D(V0,Vi)=∞。
	 * 5.从T中选取一个与S中顶点有关联(直接相连)且权值最小的顶点W(这里用到了贪心法思想),加入到S中。
	 * 6.以W作为中间点,若V0到T中某个顶点Vi距离变短,则修改D(V0,Vi)的值。 
	 * 7.重复5)和6)直到T为空。
	 * 
	 * @param src
	 * @param dst
	 * @param graph
	 * @param n
	 * @return
	 */
	public static int dijkstra(int src, int dst, int[][] graph, int n) {
		// 排序队列
		PriorityQueue<Node> pNodes = new PriorityQueue<>();
		int[] visitLog = new int[n + 1];
		// 记录访问过的点
		pNodes.add(new Node(src, 0));
		while (!pNodes.isEmpty()) {
			Node tNode = pNodes.poll();
			// 由于已经排序了 直接返回的就是最短路径
			if (tNode.node == dst) {
				return tNode.cost;
			}
			if (visitLog[tNode.node] == 1) {
				continue;
			}
			visitLog[tNode.node] = 1;
			for (int i = 0; i < n; i++) {
				// 可联通且没有遍历过
				if (graph[tNode.node][i] < 1000 && visitLog[i] != 1) {
					pNodes.add(new Node(i, tNode.cost + graph[tNode.node][i]));
				}
			}
		}
		return -1;
	}

	public static void main(String[] args) {
		int graph[][] = { { 0, 2, 3, 6, 1000, 1000 }, { 2, 0, 1000, 1000, 4, 6 }, { 3, 1000, 0, 2, 1000, 1000 },
				{ 6, 1000, 2, 0, 1, 3 }, { 1000, 4, 1000, 1, 0, 1000 }, { 1000, 6, 1000, 3, 1000, 0 } };// 地图

		System.out.println(Dijkstra.dijkstra(0, 3, graph, 6));
		System.out.println(Floyd.floyd(0, 3, graph, 6));
	}
}

/**
 * 
 * @author shichaopeng
 *
 *
 *
 *         邻接矩阵graph储存路径,同时最终状态代表点点的最短路径。如果没有直接相连的两点那么默认为一个很大的值(不要溢出)!而自己的长度为0.
 *         从第1个到第n个点依次加入图中。每个点加入进行试探是否有路径长度被更改。
 *         而上述试探具体方法为遍历图中每一个点(i,j双重循环),判断每一个点对距离是否因为加入的点而发生最小距离变化。如果发生改变,那么两点(i,j)距离就更改。
 *         重复上述直到最后插点试探完成。
 * 
 *         状态转移方程为: dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])
 *         其中dp[x][y]的意思可以理解为x到y的最短路径。所以dp[i][k]的意思可以理解为i到k的最短路径dp[k][j]的意思可以理解为k到j的最短路径.
 */
class Floyd {

	/**
	 * 
	 * @param src
	 * @param dst
	 * @param graph
	 * @param n
	 * @return
	 */
	public static int floyd(int src, int dst, int[][] graph, int n) {
		int[][] r = new int[n][n];
		for (int i = 0; i < r.length; i++) {
			for (int j = 0; j < r.length; j++) {
				r[i][j] = graph[i][j];
			}
		}
		for (int k = 0; k < n; k++) { // 任意2点插入点 让后动态规划
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					r[i][j] = Math.min(r[i][j], graph[i][k] + graph[k][j]);
				}
			}
		}
		return r[src][dst];
	}

}

class Node implements Comparable<Node> {

	public int node;
	public int cost;

	public Node(int node, int cost) {
		super();
		this.node = node;
		this.cost = cost;
	}

	@Override
	public int compareTo(Node o) {
		return cost - o.cost;
	}

}