人生思绪
未读我在两家创业公司工作过。A公司,由3人发展到20人;B公司,由20人发展到60人。这两家公司都不算成功,因此,要讲收获,更多的是经验与教训。就如同教材一样,反面教材更加有教育意义。我针对创业公司面临的重要问题,谈谈我的想法。
灵活性相对于大公司,小公司的灵活性是核心竞争优势。小公司的灵活性,是指小公司船小好调头,能够快速地响应用户。我在B公司时,公司刚好处于创业扩张期(20→60人)。公司也就是在这个时候失去它的核心竞争优势的。
初到B公司,公司的情况是:已经做出了产品,有一些铁杆用户,有投资者表示愿意入股,希望在两三年能够上市。上市,则要求公司在人数上,管理上发生一些改变。我们公司实施了如下举措:
一、将技术部细分为各个小组。如Android组、iOS组、Web组、通讯组、架构组等。为了让公司的整体技术实力提升,公司花重金为每个组都招来工作经验丰富的人带队。在之前,两三个人通过简单的沟通就可以完成包含 Android, iOS, Web 前端以及后台服务的整个软件。现在,要完成这样的软件,需要各个组的组长相互讨论,得到一个相互妥协的结果。
得到妥协的结果存在三个问题:(一)花费的时间 ...
前两天在这个版块的精华区里翻到了Robbin关于EJB的调用原理的分析,受益非浅,但感觉用纯文字来表达效果似乎不够直观,而且对RMI的阐述也略嫌少了些。这里我根据自己的一点体会,在Robbin帖子的基础上再来说说这个话题,供大家参考。
首先,我想先说说RMI的工作原理,因为EJB毕竟是基于RMI的嘛。废话就不多讲了,RMI的本质就是实现在不同JVM之间的调用,工作原理图如下:
它的实现方法就是在两个JVM中各开一个Stub和Skeleton,二者通过socket通信来实现参数和返回值的传递。
有关RMI的例子代码网上可以找到不少,但绝大部分都是通过extend the interface java.rmi.Remote实现,已经封装的很完善了,不免使人有雾里看花的感觉。下面的例子是我在《Enterprise JavaBeans》里看到的,虽然很粗糙,但很直观,利于很快了解它的工作原理。
1. 定义一个Person的接口,其中有两个business method, getAge() 和getName()
public interface Person { ...
软件设计
未读前言:太久没有做过技术分享了,这里把曾经老的新浪论坛里面使用过的架构技术做了改进和整理,最后总结了这么一篇,欢迎拍砖。
1.为什么分层?
计算机领域的体系结构普遍采用了分层的方式。
从整体结构来看:
从最底层的硬件往高层依次有操作系统->驱动程序->运行库->系统程序->应用程序等等。
从网络分层模型OSI来讲,由上至下为:
应用层->表示层-> 会话层->传输层->网络层->数据链路层->物理层
当然实际应用的TCP/IP协议的分层就没OSI标准这么复杂。
从C语言文件编写到生成可执行文件的过程来看:
预处理(展开后的C语言代码)->编译成汇编语言(特定CPU体系结构的汇编语言源文件)->汇编器生成目标文件(CPU可执行的二进制指令机器码)->链接器连接目标文件生成可执行文件(操作系统可以加载执行的二进制文件)
这不算是软件的分层结构,但是可以理解为一种通过分层来简化复杂问题的思想。那么PHP语言可以认为是建立在C语言之上的层 ...
java源码分析
未读 在Java集合类中最常用的除了ArrayList外,就是HashMap了。本文尽自己所能,尽量详细的解释HashMap的源码。一山还有一山高,有不足之处请之处,定感谢指定并及时修正。
在看HashMap源码之前先复习一下数据结构。
Java最基本的数据结构有数组和链表。数组的特点是空间连续(大小固定)、寻址迅速,但是插入和删除时需要移动元素,所以查询快,增加删除慢。链表恰好相反,可动态增加或减少空间以适应新增和删除元素,但查找时只能顺着一个个节点查找,所以增加删除快,查找慢。有没有一种结构综合了数组和链表的优点呢?当然有,那就是哈希表(虽说是综合优点,但实际上查找肯定没有数组快,插入删除没有链表快,一种折中的方式吧)。一般采用拉链法实现哈希表。哈希表?拉链法?可能一下想不起来,不过放张图就了然了。
(图片google来的,好多都用了文章用了这张图了,不知道出处了就没申明作者了)
学计算机的肯定学过这玩意儿,也不需要解释,都懂的。
铺垫了这么多,又是数组又是链表,还有哈希表,拉链法,该入正题了,我们什么时候用到了这些内容,具体它是怎么实现的?
其实我们一直在用(别告诉我你没 ...
时常,在各大论坛看到不少的朋友在张贴简历,希望得到他人的指点。为此,根据笔者一点经验,谈谈看法。
在IT行业里面,相对竞争压力较大。好的简历是成功的前提,可是很多经验较少的朋友,尤其是毕业生,对写好简历有点“犯难”。
写简历是一门学问,其中有不少的策略,要注意一下原则和方法。
原则一:态度决定成败
一个好的员工,一定是做事情一丝不苟的,何况是写简历找工作这样的大事。个人比较偏好那种做事情扎实的人来合作,所以一些低级错误不要犯。首先是错别字,一个简历信息就那么多,通篇很多错别字,说明你做事情粗心大意,想想一个粗心的员工能够得到团队的信任吗?并且很有可能接受你的简历的是人力资源,而不是技术官,他们可能直接把简历丢掉了。然后是语义问题,笔者就接受过男的照片,性别为女。一句很长的话,没有断句,很令人费解。
文章布局排版,这个可以充分的体现求职人的态度。
总之,你的简历给别人第一影响是“不难受”,能够做到“舒服”是更好。没有必要过度装饰,矫揉造作。
原则二:信息突出重点
首先,求职人需要明确的是,好工作的行情-“肉少狼多”。所谓“重金”之下,必出勇夫。多少人投 ...
生命中唯一不变的事实就是世事时刻在变。这在软件开发的每一个阶段都不可避免。我们所要面对的挑战是:要以最小的延迟和最大的灵活性来适应变化。
令人欣慰的是有人已经解决了你的设计问题,而且他们的方法已经形成了最佳实践了;这些公认为最佳实践的方法就是“设计模式”。今天我们要研究两个最流行的设计模式,学习怎样使用好的设计让你得代码更干净,让扩展性更好。
适配器模式(Adapter Design Pattern)
我们假设你有一个旧系统,现在你需要让它适应新的三方库,但是这个库用的是完全不同的API。旧系统适用的接口是完全不同于新库的。当然,你若够勇敢的话,可以改掉旧的代码以适用新的接口。但是对于所有旧系统来说,千万不要这么做。
适配器模式救了你的命!你可以简单的写一个适配器(新的封装类)
好的设计不仅是可以重复使用,还要具有可扩展性。
适配器使用了接口,并且转换成客户端可以解析的接口,使不兼容的类联系在一起。
实战适配器设计模式
好了,闲话少说,我们来实战演习。我们旧系统使用的是下面的LegacyVideoController接口来控制视频系统。
12345678910publicint ...
多线程-并发
未读1、在构造函数中启动线程我在很多代码中都看到这样的问题,在构造函数中启动一个线程,类似这样:
12345678public class A{ public A(){ this.x=1; this.y=2; this.thread=new MyThread(); this.thread.start(); } }
这个会引起什么问题呢?如果有个类B继承了类A,依据java类初始化的顺序,A的构造函数一定会在B的构造函数调用前被调用,那么thread线程也将在B被完全初始化之前启动,当thread运行时使用到了类A中的某些变量,那么就可能使用的不是你预期中的值,因为在B的构造函数中你可能赋给这些变量新的值。也就是说此时将有两个线程在使用这些变量,而这些变量却没有同步。解决这个问题有两个办法:将A设置为final,不可继承;或者提供单独的start方法用来启动线程,而不是放在构造函数中。
2、不完全的同步都知道对一个变量同步的有效方式是用synchronized保护起来 ...
多线程-并发
未读
在不只一个线程访问一个互斥的变量时,所有线程都必须使用同步,否则就可能会发生一些非常糟糕的事情。Java 语言中主要的同步手段就是 synchronized 关键字(也称为 内在锁 ),它强制实行互斥,确保执行 synchronized 块的线程的动作,能够被后来执行受相同锁保护的 synchronized 块的其他线程看到。在使用得当的时候,内在锁可以让程序做到线程安全,但是在使用锁定保护短的代码路径,而且线程频繁地争用锁的时候,锁定可能成为相当繁重的操作。
在 “流行的原子” 一文中,我们研究了 原子变量 ,原子变量提供了原子性的读-写-修改操作,可以在不使用锁的情况下安全地更新共享变量。原子变量的内存语义与 volatile 变量类似,但是因为它们也可以被原子性地修改,所以可以把它们用作不使用锁的并发算法的基础。
非阻塞的计数器清单 1 中的 Counter 是线程安全的,但是使用锁的需求带来的性能成本困扰了一些开发人员。但是锁是必需的,因为虽然增加看起来是单一操作,但实际是三个独立操作的简化:检索值,给值加 1,再写回值。(在 getValue 方法上也需要同步,以保证调用 ...
每种语言都很强大,不管你是像我一样的初学者还是有过N年项目经验的大神,总会有你不知道的东西。就其语言本身而言,比如Java,也许你用Java开发 了好几年,对其可以说是烂熟于心,但你能保证Java所有的用法你都知道吗?今天没事就来整理下Java中有哪些隐藏的特性呢?知道的可以举手哦~~~
一、双括号初始化语法( DoubleBraceInitialization)(这里指的是大括号{}) 主要指的是集合类(List,Map,Set等),我们创建一个常量集合或传递一个常量集合作为参数,往往都会这么做(以Set为例):
123456Set<String> validCodes = new HashSet<String>(); validCodes.add("XZ13s"); validCodes.add("AB21/X"); validCodes.add("YYLEX"); validCodes.add("AR2D"); removeProductsWithCodeIn(validCod ...
