一篇让Java程序猿随时可以翻看的Oracle总结

技术交流lanqiao 发表了文章 • 0 个评论 • 34 次浏览 • 1 天前 • 来自相关话题

  本文总结了以下Oracle中常用的命令和语句,没有语法都是实例,以便以后工作的时候随时翻看。     有关的语句和操作基本都是按照实战中的顺序来总结的,比如创建用户,建表,序列初始化,插入数据的顺序呢。 ...查看全部
 
本文总结了以下Oracle中常用的命令和语句,没有语法都是实例,以便以后工作的时候随时翻看。
   
有关的语句和操作基本都是按照实战中的顺序来总结的,比如创建用户,建表,序列初始化,插入数据的顺序呢。
   
这篇文章的基表是大家最为熟知的Scott用户下的emp员工表,dept部门表以及salgrade薪水等级表,一切的语句都是围绕它写的。
 
下面来看一下Oracle中常用的操作都有哪些吧!
 
一.用户的有关操作。
 
创建用户
create user scott identified by 123456;
给用户分配权限
grant connect,resource to scott;
grant create view to scott;
grant create synonym to scott;
撤销用户权限
revoke connect,resource from scott;
revoke create view from scott;
revoke create synonym from scott;
删除用户
drop user scott cascade;
修改用户密码
alter user scott identified by 123456;--命令修改
conn scott/123456
password;--命令可视化修改1
connect scott/123456
password;--命令可视化修改2
设置用户是否锁定
alter user scott account lock;
alter user scott account unlock;
  
二.表空间的有关操作。
 
创建表空间
create tablespace mysapce
datafile 'D:a.ora' size 10M--绝对路径和大小
extent management local
uniform size 1M;--每个分区的大小
扩展表空间
alter tablespace mysapce
add datafile 'D:b.ora' size 10M;
为ORACLE对象指定表空间
create user space_text identified by 123456 account unlock default tablespace mysapce;
--创建表、索引也可以指定表空间;一旦指定,表空间无法修改。
删除表空间
drop tablespace mysapce;
  
三.DDL的有关操作。
 
表table
--创建员工表
CREATE TABLE EMP(
EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR VARCHAR(10), --上司
HIREDATE DATE, --入职日期
SAL NUMBER(7,2), --薪水
COMM NUMBER(7,2), --津贴
DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES DEPT
);
  
--创建部门表
CREATE TABLE DEPT(
DEPTNO NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY,
DNAME VARCHAR2(14) ,
LOC VARCHAR2(13) --地址
);
  
--创建工资等级表
CREATE TABLE SALGRADE(
GRADE NUMBER, --等级
LOSAL NUMBER, --等级中最低的薪水
HISAL NUMBER --等级中最高的薪水
);
  
视图view
--为emp表的empno,ename,sal和dept表的dname和salgrade表的grade创建一个视图
create view emp_dept_salgrade
as
select e.empno,e.ename,e.sal,d.dname,s.grade from
emp e inner join dept d using(deptno)
inner join salgrade s on e.sal between s.losal and s.hisal;
select * from emp_dept_salgrade;--通过视图查询
序列sequence
--为员工表的EMPNO创建一个序列
create sequence emp_empno_seq
start with 1001
increment by 1
nomaxvalue
nocycle
cache 10;
select emp_empno_seq.currval from dual;<span style="color: #008000;">查询序列的当前值</span>
select emp_empno_seq.nextval from dual;<span style="color: #008000;">查询序列的下一个值</span>
同义词synonym
--为视图emp_dept_salgrade创建同义词
create synonym eds for emp_dept_salgrade;
select * from eds;<span style="color: #008000;">通过视图的同义词来查询视图中的数据
</span>
触发器trigger
--为员工表的empno创建一个自动插入的触发器
create or replace trigger emp_empno_tri
before insert on emp
for each row
begin
:new.empno:=emp_empno_seq.nextval;<span style="color: #008000;">--语句级(for each row)触发器里面可以:new.列名来给进行操作。</span>
end;
存储过程procedure
--创建一个可以控制行数的乘法表的过程。
create or replace procedure nine_nine(nine_line in number)
as
begin
for i in 1..nine_line loop
for j in 1..i loop
dbms_output.put(i||'*'||j||'='||i*j||' ');
end loop;
dbms_output.put_line('');
end loop;
end;
--调用这个乘法过程
set serveroutput on;
execute nine_nine(9);
存储函数function
--创建一个求1!+2!+..+20!的值的存储函数
create or replace function one_tw
return number
as
value_sum number:=0;
value_loop number:=1;
begin
for i in 1..20 loop
value_loop:=value_loop*i;
value_sum:=value_sum+value_loop;
end loop;
return value_sum;
end;
select one_tw() from dual;<span style="color: #008000;">--调用函数</span>
<span style="color: #008000;">备注:存储函数的调用可以放在表达式的位置,即表达式在哪里成立,它就可以在哪里调用。</span>
事务rollback、commit、savepoint
 
三.常用的结构查询。
 
查询用户和用户的信息
select username,user_id,password,default_tablespace from dba_users;
select * from dba_users;
查询用户所拥有的角色
select * from user_role_privs;--系统用户
select * from session_roles;--普通用户
查询用户的权限
select * from user_sys_privs;普通用户和系统用户都可以
查看表中列的字符长度和字节长度
select length(ename),lengthb(ename) from emp;
查询表的相关信息
SELECT table_name, tablespace_name, temporary
FROM user_tables;
查询表中列的相关信息
SELECT table_name,column_name, data_type, data_length, data_precision, data_scale
FROM user_tab_columns;
对表进行重命名
rename student to mystudent;
给表添加备注
comment on table student is '我的练习';
给表中列添加备注
comment on column student.sno is '学生号';
查看表和视图的备注信息
select * from user_tab_comments where table_name='STUDENT';
查看表和视图中列的备注信息
select * from user_col_comments where table_name='STUDENT';
查看表的结构
describe student;
截断表
truncate table student;
使用连接运算符
select empno||ename as employees from emp;
select concat(empno,ename) as employees from emp;
查看表的约束信息
select * from user_constraints where table_name='EMP';
查看列的约束信息
select * from user_cons_columns where column_name='SNO';
查看序列的信息
select * from user_sequences where sequence_name='EMP_EMPNO_SEQ';
查看索引的信息
select * from user_indexes;
  
查看视图的信息
select * from user_views;
查看同义词
select * from user_synonyms;
查看触发器
select * from user_triggers;
查看存储过程
select * from user_procedures;
四.DML的有关操作。
插入数据insert
--dept--
INSERT INTO DEPT
select 10,'ACCOUNTING','NEW YORK' from dual
union
select 20,'RESEARCH','DALLAS' from dual
union
select 30,'SALES','CHICAGO' from dual
union
select 40,'OPERATIONS','BOSTON' from dual;
commit; <span style="color: #008000;">--使用Oracle中的多行插入方法,关键字union,select自己想要的数据,与dual伪表组建一个完整的结构。
</span>
  
--emp--
INSERT INTO EMP(ename,job,mgr,hiredate,sal,comm,deptno)
select 'SMITH','CLERK',1009,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20 from dual
union
select 'ALLEN','SALESMAN',1006,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30 from dual
union
select 'WARD','SALESMAN',1006,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30 from dual
union
select 'JONES','MANAGER',1009,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20 from dual
union
select 'MARTIN','SALESMAN',1006,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30 from dual
union
select 'BLAKE','MANAGER',1009,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30 from dual
union
select 'CLARK','MANAGER',1009,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10 from dual
union
select 'SCOTT','ANALYST',1004,to_date('13-10-87','dd-mm-rr')-85,3000,NULL,20 from dual
union
select 'KING','PRESIDENT',1007,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10 from dual
union
select 'TURNER','SALESMAN',1006,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30 from dual
union
select 'ADAMS','CLERK',1009,to_date('13-10-87', 'dd-mm-rr')-51,1100,NULL,20 from dual
union
select 'JAMES','CLERK',1009,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30 from dual
union
select 'FORD','ANALYST',1004,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20 from dual
union
select 'MILLER','CLERK',1004,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10 from dual;
commit; <span style="color: #008000;">--这里使用了触发器emp_empno_tri来自动插入emp表的empno员工编号</span>
--salgrade--
INSERT INTO SALGRADE VALUES (1,700,1200);
INSERT INTO SALGRADE VALUES (2,1200,1400);
INSERT INTO SALGRADE VALUES (3,1400,2000);
INSERT INTO SALGRADE VALUES (4,2000,3000);
INSERT INTO SALGRADE VALUES (5,3000,9999);
commit;
  
更新数据update
update emp set sal=3000 where empno=1004;
删除数据delete
delete from emp where empno=1004;<span style="color: #008000;">--from可以省略</span>
查询数据select
    
查询数据是DML语句中最关键的部分,也是最难的部分,在这里有许多围绕scott用户的实例,都是稍微复杂一点的查询,简单的就没必要写了。
    
1.最常用。
select * from emp;
select * from dept;
select * from salgrade;
    
2.内部连接。
      
2-1.查询每个员工所在的部门,使用where连接.
select e.empno,e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
      
2-2.inner join on连接.
select e.empno,e.ename,d.dname from emp e inner join dept d on e.deptno=d.deptno;
      
2-3.inner join using连接.
select e.empno,e.ename,d.dname from emp e inner join dept d using(deptno);
    
3.外部连接。
      
3-1.左外连接:例如:查询出部门的员工的情况(显示所有部门).
select e.ename,d.dname from emp e left join dept d using(deptno);
      
3-2.右外连接用(+).
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno(+);
      
3-3.右外连接:例如:查询出所有的员工的部门情况(显示了所有员工).
select e.ename,d.dname from emp e right join dept d using(deptno);
      
3-4.右外连接用(+).
select e.ename,d.dname from emp e,dept d where e.deptno(+)=d.deptno;
    
4.自连接。  
      
4-1.查询出员工及他的上级。
select a.ename as 员工,b.ename as 上级 from emp a ,emp b where a.mgr=b.empno;
select a.ename as 上级,b.ename as 上级 from emp a inner join emp b on a.mgr=b.empno;
    
5.子查询。
      
5-1.查询工资高于平均工资的员工信息.
select * from emp where sal>(select avg(sal) from emp);
      
5-2.使用ANY查询任意满足工资低于最低档工资的员工信息.
select * from emp where sal<any(select losal from salgrade);
      
5-3.查询所有员工所属部门.
select dname from (select distinct dname from dept);
      
5-4.查询满足大于每个部门的最低工资的员工信息.
select * from emp where sal>all(select min(sal) from emp group by deptno);
 
5-5.查询出每个部门中,高出本部门平均工资的员工的雇员号和姓名.
select empno as 雇员号,ename as 姓名 from emp outer where sal>
(select avg(sal) from emp inner where inner.deptno=outer.deptno );
      
5-6.查询不在部门10的员工信息:注意子查询中的1,由于只关心子查询是否返回TRUE值,使用1可以提高查询的效率.
        
5-6.1.EXISTS子查询效率高于IN子查询.
select * from emp a where not exists (select 1 from emp b where a.deptno=10);
        
5-6.2.in的效率低,但比较好理解.
select * from emp where deptno not in 10;
      
5-7.查询emp表中可以管理别的员工的员工.
select ename from emp a where exists(select ename from emp b where a.empno=b.mgr);
      
5-8.删除中部门重复行.
delete emp where rowid not in (select min(rowid) from emp group by deptno);
      
5-9.查找emp表第6-10条记录.
select * from(select rownum m,ename,sal,deptno from emp where rownum<=10)
where m>5;

怎样在复杂代码中找 bug?

技术交流lanqiao 发表了文章 • 0 个评论 • 17 次浏览 • 1 天前 • 来自相关话题

  我曾经做了两年大型软件的维护工作,那个项目有10多年了,大约3000万行以上的代码,参与过开发的有数千人,代码checkout出来有大约5个GB,而且bug特别多,open的有上千,即使最高优先级的showstopper也有上百。分享下我的d ...查看全部
 
我曾经做了两年大型软件的维护工作,那个项目有10多年了,大约3000万行以上的代码,参与过开发的有数千人,代码checkout出来有大约5个GB,而且bug特别多,open的有上千,即使最高优先级的showstopper也有上百。分享下我的debug的经验
 
1.优先解决那些可重现的,可重现的bug特别好找,反复调试测试就好了,先把好解决的干掉,这样最节约时间。
 
2.对于某些bug没有头绪或者现象古怪不知道从哪里下手,找有经验的同事问一下思路,因为在那种开发多年的大型系统里,经常会反复出现同样原因的bug,原因都类似,改了一处,过一阵子另外一处又冒出来,而且无法根治。
 
比如:我那个系统里有个特别危险的API,接口参数比较难用,一旦有人用错了某些情况下就会出诡异的现象,解决很简单,找到调用这个API的地方把调用方式写对就好了。为什么不根治呢?因为要保持兼容性不能改接口了。Windows系统里就好多这种烂API。问下老员工吧,说不定他们都遇到过好多次了。
 
3.放大现象,有些bug现象不太明显,那么就想办法增大它的破坏性,把现象放大。这只是个思路,具体怎么放大只能根据具体的代码来定。比如:美剧《豪斯医生》里有一集,怀疑病人心肺有问题,就让病人去跑步机上跑步,加重心肺负担,从而放大症状。
 
4.二分法定位,把程序逻辑一点点注释掉,看看还会不会出问题,类似二分查找的方法,逐步缩小问题范围。
 
5.模拟现场,有时候我会问自己,如果我要实现bug描述的现象我要怎么写代码才行?比如:我遇到一个死锁问题,但是检查代码发现所有的锁都是配对的,没有忘记解锁的地方,而且锁很简单就是一个普通的临界段, 保护几行赋值语句而已。这样的代码怎么写才能让他死锁呢?我想如果让我故意制造这样一个现象,只有在上锁的时候强制杀掉线程了。既然这样就可以去看看有谁强杀线程了没有。
 
6.制作工具,针对某些bug编写一些调试辅助工具。比如,我那个系统没有完善的崩溃报告,虽然也有dump,但是分析出来的callstack经常不准。于是我为解决崩溃问题编写了个工具,会自动扫描代码,在每个函数入口和出口插入log,以此来定位崩溃点。
 
7.掩盖问题,虽然这样做有点不厚道,但是有时不得不这么做。有些bug找不到真正的root cause,但是又要在规定时间内解决,那么我们就可以治疗症状而不去找病因。比如用try catch掩盖一些奇怪的崩溃。不到万不得已不要这么干,未来可能会付出更大代价。

大学的真实面貌其实是这样的,哈哈哈哈哈~扎心了!

吐槽lanqiao 发表了文章 • 0 个评论 • 48 次浏览 • 1 天前 • 来自相关话题

  ...查看全部

cd0f352agy1fx2yvrt3wlj20c80dhq35.jpg


cd0f352agy1fx2yvrtc5pj20c80ax3yr.jpg


cd0f352agy1fx2yvrtf2oj20c80cat8x.jpg


cd0f352agy1fx2yvrtg8oj20c80b8t8v.jpg


cd0f352agy1fx2yvrty1yj20c80bwwer.jpg


cd0f352agy1fx2yvru2elj20c80ds3yv.jpg


cd0f352agy1fx2yvrux7oj20c80djjrm.jpg


cd0f352agy1fx2yvrve2mj20c80cgweu.jpg


cd0f352agy1fx2yvrw88ij20c80cidgb.jpg

 

“欧巴,帮我调试个bug好么?”看看12星座程序猿的反应

技术交流lanqiao 发表了文章 • 0 个评论 • 43 次浏览 • 2 天前 • 来自相关话题

帮我调试个bug好吗?” [size=16]“……” 求过了那么多程序猿,结果却没有几个愿意帮你的忙,你怀着满腔怨气抱怨这群程序猿不近人情,其实是因为你并没有摸透他们的性格![/size] 白羊座 ...查看全部
帮我调试个bug好吗?”
[size=16]“……”
求过了那么多程序猿,结果却没有几个愿意帮你的忙,你怀着满腔怨气抱怨这群程序猿不近人情,其实是因为你并没有摸透他们的性格![/size]


白羊座
帮我调试个bug好么?
你是谁?
我是amy,上回聚会有见过
行!没问题!! 

 
性欲强,颜值控的白羊座
无论是程序猿还是其他行业
他们都是十足的颜控
虽然为人爽快又正直
但这一切的前提都是看脸好么
如果你没有 88 58 88的三围
或是没有八块腹肌外加人鱼线
那你还是省省吧 别找他们了
他们对颜值7分以下的人
不会伸出援手的

金牛座
欧巴,帮我调试个bug好么
报价报价报价!!!
还要钱???
你以为我是喝西北风长大的么?????? 

别跟金牛座谈感情,多伤钱啊!
想要调个bug什么的,还是别指望金牛座了
他直接拿100页的报价单甩死你
别人家报价单是按项目收费
金牛座的报价单是按像素收费
大金牛实实在在的将:时间就是金钱
贯彻到生活的每一个地方
讲真,最好连金牛问都不要问
万一人家咨询也收费呢

双子座
欧巴,帮我调试个bug好么
额,我想想最近好像有点忙
或许晚上有时间
但是,好像又要吃聚餐
你在让我好好想一想
我下个月再给你答复
。。。。。。。 

喜怒无常的双子座
你要是想找他们帮你免费调试一个bug
可能要提前半个月跟他们说
伶牙俐齿热心肠的双子座
绝对不会一开始就拒绝你
毕竟他们是真的热心肠
但是 ,你需要将他们纠结的时间也考虑进去
都说双子座内心住着两个小人
从他答应给帮你的那一刻开始
一个小人就对他说
“今天别做了,出去聚餐多好玩啊…”
另一个说
“是啊是啊…”

巨蟹座
欧巴,帮我调试个bug好么
啊,好吧
谢谢欧巴~
欧巴,两个月过去了,做好了么??
前段时间太忙,忘了
。。。。。。 

天性温良的巨蟹座
在你开口之后绝逼不好意思直接拒绝你
毕竟他们总是以老好人的形象示人
亲切有礼貌 感情丰富又富有同情人
但你别以为这就真的万无一失了
每一个巨蟹都是一只小腹黑
纠结的不要不要的
答应你之后,他的内心开始演宫斗剧
“天啊,我好忙啊,一点也不想做”
“但是答应了人家,是不是应该守信用呢”
“万一没做,她会不会给别人说我坏话”
“到时候会不会所有人都觉得我很不近人情”
“天啊……不敢想象!”
“……”
但一般宫斗剧的结果是
他们忘记要帮你做东西了…
所以,还是找下一个吧

狮子座
欧巴,帮我调试个bug好么
不好
不着急的,你有时间做就好
有时间我也不想做
。。。。。。 

帮我调个bug好不好”
“不好”
你敢找我大狮子调bug!!?
敢找我大狮子调bug!!?
找我大狮子调bug!!?
我大狮子免费调bug!!?
大狮子免费调bug!!?
狮子免费调bug!!?
你真是
TOO YOUNG TOO SIMPLE!!!
我大狮子的尊贵玉手
岂是用来给你做不花钱调bug的?

 
处女座
欧巴,帮我调试个bug好么
要调成什么样
随便弄弄就行相信你啦
你自己都不知道自己想调成啥??就让我随便弄弄,把你这人怎么这么不严谨,为什么会有bug,,如果你一开始,
。。。。。。 

千万别被网上黑处女座的段子给吓到
搞定处女座其实并没有那么难
处女座讲究的是:存!在!感!

天秤座
欧巴,帮我调试个bug好么
什么的?
游戏的
调好了,有版本1,版本2,版本3,你自己选
谢谢 

颜控面子薄的天秤座
一般都会答应你的要求 

毕竟他们抹不开面子
觉得也算是认识 帮一下就帮一下呗
并且天秤座是不喜欢拖稿的人
他们手上永远都是事情越少越好
能快点搞完 绝不拖到明天
而且活好手快 你上午给他说 他下午就给你了
是不是如此完美!
but 他们最怕最怕做选择
一个东西可能做个三四版本不同样式的
因为他们一旦开始做了
就分不清那些好那些不好了
感觉看着都不错
让他们选还不如直接杀死他们算了
所以,找他们做一个
有可能会收获好几个版本

天蝎座
欧巴,帮我调试个bug好么
什么东西?
游戏的
好的,记得请我吃饭
谢谢 

腹黑高冷天蝎座
平时都一份高冷到结冰的样子
所以敢求他们帮忙做设计的
一般都已经是很熟的朋友了
这个时候他们是不会拒绝的
但他们也不会直接给你做
毕竟这样就太对不起他们高冷的形象了
高冷高智商的他们
一般都会选择将事情转移到下家…
来来来,那个学弟你不是想要练习吗
这个bug你拿去练手吧
关键是毫不知情的下家
还会因为高冷天蝎突然搭理自己了
变得受宠若惊…


射手座
欧巴,帮我调试个bug好么
没有问题
太感谢啦
不用谢,我这就去调
用我说一下怎么调试么?
【自动回复】您好,我现在有事,不方便联系 

射手座什么的绝对是逗比小王子
热情又思维跳跃
通常他们比较实心眼
帮忙就帮忙咯 没有那么多需要思前想后的
但是你要谨慎他们的自由发挥
毕竟在他们实在的心眼之外
是一个脑洞巨大的身体
你给他一个猫
他没准帮你养成一只狗
但是你并不能怪他们
天性使然,况且还只是帮个忙呀

摩羯座
欧巴,帮我调试个bug好么
对不起,我最近时间安排满了没有时间做了
不着急的~~
我算了一下时间成本,这样的活还不如找个人去做算了
那找谁呢?会贵么?
找金牛吧,只要有钱他都会接 

摩羯向来给人处变不惊的感觉
永远都是有耐心且可靠的
说话也是有一说一有二说二
有三绝不会给你说个四
他说没时间了,就肯定是没时间了
你也不用去揣测他说的是真的还是假的
毕竟他们是很少说谎的群体
而且他会站在你的立场去帮忙分析
比如你看,你要做个便宜logo的话
就去找金牛吧
只要有钱,金牛都会做的
哈哈哈哈哈哈哈,


双鱼座
欧巴,帮我调试个bug好么
你猜我要不要帮你
.。。。。。。。 

柔情又羞涩的双鱼座
总是羞于表达自己的情绪
他们心思细密 又内秀
内心的那些小九九总是不想让别人知道
结果别人通常会被这种看似无厘头的羞涩给吓倒
面对双鱼座 死缠烂打类的沟通方式
绝对是搞定他们的不二法宝

水瓶座
欧巴,能帮我调个bug吗?
可以呀,什么的
游戏的
什么游戏,这个游戏是谁开发的?为什么会存在bug???要不然创新一下,这样才能出其不意,
。。。。。。 

脑洞大开的水瓶座劝你们还是不要招惹了
真的,水瓶座发挥起来
你们一般星座都控制不住好吗
你给他一杯水
他可以给你讲到尼斯湖水怪
你叫他调个bug
万一他给你做个app出来
你还觉得自己hold住吗
你跟水瓶座一起脑洞大开畅谈未来的时间
给别人都可以调10个bug了
真爱生命 别惹水瓶

……
 

程序员如何打造自己的顶端优势

技术交流lanqiao 发表了文章 • 0 个评论 • 32 次浏览 • 2 天前 • 来自相关话题

这篇文章的核心观点是:软件开发者只有打造顶端优势,才能获得更好的发展。   这样的感触,来自: 有位工作十来年的朋友,一直做开发,J2EE、C#、JavaScript、PHP、C++、Android、Python,很多语言、 ...查看全部
这篇文章的核心观点是:软件开发者只有打造顶端优势,才能获得更好的发展
 
这样的感触,来自:
  1. 有位工作十来年的朋友,一直做开发,J2EE、C#、JavaScript、PHP、C++、Android、Python,很多语言、框架和平台都用过,最近他找工作,找来找去,发现每个技术方向上的修炼都很难对得起他的工作年龄,直接导致他找不到比原来工作待遇更好的,非常沮丧。
  2. 最近有很多人在找工作,都抱怨说略懂几个方向可找起工作来很难。

那么什么是顶端优势?什么是程序员的顶端优势呢?
 
 顶端优势
 
植物在生长发育过程中,顶芽和侧芽之间有着密切的关系。顶芽旺盛生长时,会抑制侧芽生长。如果由于某种原因顶芽停止生长,一些侧芽就会迅速生长。这种顶芽优先生长,抑制侧芽发育的现象叫做顶端优势。
 
顶端优势强的植物,几乎不生分枝,如向日葵的许多品种。番茄等植物顶端优势弱,能长出许多分枝。灌木顶端优势极弱,几乎没有主茎与分枝的区别。多数植物属中间类型,如稻、麦、泡桐等。
 
我家在农村,小时候经常见我爸爸修理泡桐树,在树苗还很小时就把杂七杂八的斜枝掰断或者削掉,这样树苗就可以往高里长,往直里长。
 
去除侧枝侧芽,力保顶枝顶芽优先生长,这就是在利用顶端优势。经过这样处理的树苗最终可能长成这样:
 
而放任侧枝侧芽肆意生长,树苗则可能长成这样:
 
砍掉树干的斜枝让树长得高大,是利用顶端优势的一种方式。还有一种方式是剪掉顶芽,让侧芽生长。究竟运用哪种方式,和背后的目的有关。 
 
程序员的顶端优势
 
现在我们可以回到最开始,解释一下那位工作十来年的朋友找工作时遇到的问题,他的问题,反映了如下有两点:
  1. 个人的技能树没有顶端优势。就是说,这也略懂,那也略懂,哪儿也不精。
  2. 在顶端优势不突出的情况下,寻找技术类岗位

 
这样的问题,我在分答、知乎以及IT职业咨询群里回答过很多:
  • 比如到底要学多少门语言
  • 比如自己一直使用Java做OA,两年多了,可现在AR、VR、AI等各种新技术层出不穷,要不要换个语言去追新技术,如用Python去学TensorFlow
  • 比如做开发三年了,语言层面该会的都会了,该用的都用了,有些迷茫,不知道接下来怎么提高
 如果结合顶端优势原理,这些问题,就很容易回答了: 

对于想沿着技术路线发展的开发者,要尽早聚焦在某个技术方向上,打造出个人技能树的顶端优势,这样对将来的发展更为有利。

 以我个人为例,我用过C、C++、Java、Lua、JavaScript、Python、Scala、OC等各种语言,但C++是我最熟悉的,明显比其它语言有优势。而在C++里面,我又用过ffmpeg、Qt、VLC、DirectX、OpenGL、CEF、WebRTC等框架,但Qt是我最熟悉的,写过《Qt Quick核心编程》和《Qt on Android核心编程》。这就是我个人技能树的两个顶端优势。 当你的能力树存在明显的顶端优势时,你就更容易被标签化,更容易被“使用”。 有人可能会说,君子不器,我们不必搞得自己只能干某件事。对,《论语》说得没错,但那是成为君子之后的事儿。在成为君子之前,先打造顶端优势,先被标签化,这样才有更好的机会去发展。当你具备了顶端优势之后,再以顶端为基础,树冠搞得大些,让自己成一专多能的T型人才。类似这样: 塑造你在群体中的顶端优势 问题:如何让一个女人变得更美?答:让她和一个比较丑的同伴一起出现。 这就是比较优势带来的顶端优势。对开发者也一样,从自身角度看,修剪个人的能力树可以打造技能上的顶端优势。但是很多时候,你要和别人放在一起比较时,也能显示出优势。这就是群体中的顶端优势。当你能够通过某方面的能力让自己凸显出来,你就会更重要。 那么,对开发者来讲,要塑造自己在群体中的顶端优势,最重要的一点就是选择环境。举个例子,有很多大公司的开发者,干了几年后得不到晋升,但是跑到初创公司或者小公司,就很容易成为核心或者技术管理者。 这就是“宁做鸡头不做凤尾”,是利用比较优势塑造顶端优势的典型案例。 那相应的,还可以通过地域的差异来凸显你的优势。比如你在北京做开发,泯然众人,但回到西安,可能就能显出不一样来。如果你再回到三线、四线城市,可能优势会更突出。 另外一种凸显优势的,就是到一个匮乏你所拥有的技能的环境,比如前两年移动端开发火热时,你转战到传统软件公司或者传统行业的软件公司,帮他们的产品向移动端迁移。那你就具备顶端优势了。  小结 归纳一下,这篇文章讲了三点:[list=1]
  • 顶端优势可以从个人和群体两个维度来看。对于个人来讲,越早打造出你在知识、技能层面的顶端优势,你就越容易被识别,越容易得到更好的发展机会。
  • 具备了顶端优势之后,再横向拓展,将你的技能构建成T型,这样就有更强、更全面的竞争力。
  • 将你个人技能层面的顶端优势,放在合适的环境中,通过比较,就可以塑造你在群体中的顶端优势,让你得到更好的资源。

  • 优秀程序员写代码的七个优秀习惯

    技术交流lanqiao 发表了文章 • 0 个评论 • 66 次浏览 • 2 天前 • 来自相关话题

    伟大的程序员都有三个优点:懒惰、急躁和傲慢。为什么这么说呢?懒惰会促使他们去写一些省事儿的程序来辅助他们或别人更好的工作,这样他们就无需再去回答一些不想回答的问题。没耐心会激励他们去写一些程序,不等你提出就主动满足你的需求。傲慢会促使他们写出可靠无误的代码,因 ...查看全部
    伟大的程序员都有三个优点:懒惰、急躁和傲慢。为什么这么说呢?懒惰会促使他们去写一些省事儿的程序来辅助他们或别人更好的工作,这样他们就无需再去回答一些不想回答的问题。没耐心会激励他们去写一些程序,不等你提出就主动满足你的需求。傲慢会促使他们写出可靠无误的代码,因为他们不想受到批评和指责。但是,伟大的程序员也并不总是高效的,那些每天都能将自己的工作完成的很好的开发者,比那些偶尔编码到令人眩晕的高度的程序员要更高效。为了提高你的就业能力,你不需要成为一个伟大的开发者,而是一个高效的开发者。下面的7个习惯,能逐渐让你成为高效的开发者。
     
    每天至少写4个小时代码
    猛的一看,这条建议没有意义,因为很多程序员在他们的电脑桌前几乎每天要写至少8个小时的代码,很多甚至是10个小时。他们实际上只有很少的时间花在了实际开发工作中。很多项目中,开发者把他们的时间大部分都消磨在了开会、娱乐、吃饭等等的这些事情上面,所以,纯粹写代码的时间是没有4个小时的,但令人惊讶的是,在办公环境中这点是很难实现的。为什么呢?一个很重要的因素就是:要保证开发者在那4个小时内不能被打扰。因为一旦你全身心投入进去,你的大脑就处在高速运行中,一旦中间被打断了,可能会需要你花一个小时的时间才能找回原来的感觉和思路。怪不得那么多程序员都不喜欢在编程中受到打扰呢。
     
    配合开发团队
    作为团队中的其中一员,学会和你的同事相处是成为一个高效开发者的重要组成部分。这要比你有经验丰富的编码技能更重要。无论他多么有才华,就问一个关键的问题,和他们一起工作有开心吗?如果答案是否定的,可能会影响整个团队的士气。但这不仅仅是自大的家伙单方面造成的问题。如果开发人员太好或者因为某些原因不适应团队环境也可能会出现一些问题。
     
    利用业余时间编码
    如果你写代码仅仅是为了钱,那么你很难在新的领域学到新技能以及经验。为了娱乐而去编码是很重要的。大神级的开发者,他们业余都有自己研究的项目领域。这些开发者不会为他们的小项目使用他们在工作中需要的技能,相反,他们会利用一些业余项目来增加自己的技能,同时让自己跟上新技术发展的步伐,这才是真正让他们兴奋的。
     
    学会写潦草的代码
    很少有项目会需要开发者去创建一个华丽的代码作品:它们所需要的通常是一个可以在上面建立具体功能的通用平台。最有效的方式就是快速写一些可运行的作品,然后从中受益。不管你的代码是邋遢也好,重复也好,命名很烂也好,代码只是一种解决方案的表现形式,之后你可以去重构它,让它看起来很好。
     
    不要在相同的工作上停留过长时间
    一个保证不失去自己编程优势的有效方式就是去重新找一个工作,然后让自己融入到开发团队中。因为一旦你掌握了工作所需的所有技能,你就进入了一个死胡同,你的技能很难再提升,你也很难成为一个更好的程序员。你需要不断挑战自己,如果你在一个地方工作了好几年,那么你可能已经学到了当时想学的东西,所以不要再待在那了——继续前行,去寻找新的挑战。
     
    永远不要停止学习
    当今社会,软件技术更新的非常快,这意味着现在很多重要的编码技能可能很快就会过时。所以,如果你打算在软件开发领域有一个长期的发展,及时了解新的编程语言和技术趋势是非常非常重要的。事实很简单但也很残酷,你现有的知识是不足以你去消费一辈子的,你必须做好不断去重新学习的准备,因为你现在所拥有的知识未来是不能满足你的需求的。清楚并专注于你感兴趣的领域,而不是试图成为各行各业的高手是很重要的。对你想深入学习的领域,要保持如饥似渴的态度和持续的激情。不要试图去啥都学,因为这是不可能的,要保持专注,不断学习。也许你每一份开发工作都会有一半之前没有做过的事情,所以你要有的重要的技能就是知道如何去学习,去寻找信息,如果你有了这项技能,那么,不管你需要什么,你都可以通过自学拥有了。
     
    因为热爱去编程
    选择自己热爱的领域是至关重要的,这样才能确保自己能够全身心投入项目中去。产生动力,最重要的因素是你关心代码能够做什么,也许可以用某种方式让一个app运行,也许它会让一台机器以你希望的方式去工作。无论如何,你要真正去享受自己正在做的事,并尝试获得良好效果,如果可能的话,你能从中找到快乐,那么恭喜你,你一定会写出伟大的代码,成为一个伟大的程序员。

    据说只有程序员才会的10个智力问题

    技术交流lanqiao 发表了文章 • 0 个评论 • 34 次浏览 • 2 天前 • 来自相关话题

    程序员,已经成为互联网时代高薪、高智商以及苦逼的代名词。其实,优秀的程序员会越来越轻松。计算机世界和现实世界很像,解决问题的办法是开放的,而很多时候限制自己的是想象力。现在,程序员证明自己智商的时候到了,一大波智力题正在靠近。 ...查看全部
    程序员,已经成为互联网时代高薪、高智商以及苦逼的代名词。其实,优秀的程序员会越来越轻松。计算机世界和现实世界很像,解决问题的办法是开放的,而很多时候限制自己的是想象力。现在,程序员证明自己智商的时候到了,一大波智力题正在靠近。

    微信截图_20181115132826.png

     

    640.jpg

     

    谈谈Java程序员进阶的那些知识和方向

    技术交流lanqiao 发表了文章 • 0 个评论 • 18 次浏览 • 2 天前 • 来自相关话题

    记得前段时间看过一篇文章谈到一种程序员叫野生程序员,战斗力极强,可以搞定一切问题,但是通常看问题抓不到本质,或者说是google/baidu/stackoverflow/github的搬运工,其实个人觉得也没什么不好的,闻道有先后,术业有专攻,确实有工作岗位就 ...查看全部
    记得前段时间看过一篇文章谈到一种程序员叫野生程序员,战斗力极强,可以搞定一切问题,但是通常看问题抓不到本质,或者说是google/baidu/stackoverflow/github的搬运工,其实个人觉得也没什么不好的,闻道有先后,术业有专攻,确实有工作岗位就需要这样的职位。但是计算机行业的发展有其方向,工程师的职业发展也有其方向,随着经验的积累,可能这样的人回头再看看自己写的代码也会觉得不太好。那么如果有一天这样的人想换工作,或者应聘体质比较完整的公司,可能还是需要潜心修炼的,下面笔者从两个方面谈谈Java程序员进阶的那些知识和方向,笔者不打算从基础的东西讲起,比如Java语言基础,多线程,IO,如果有责方面的需求请参考领域内的那些神著,但是切记,最好看原版,远离粗制滥造的翻译版。
    1.Paradigm
    除了Java语言基础,通常在每种语言中还有很多paradigm,这些paradigm往往是衡量老鸟和新手的地方,比如函数命名,异常处理,泛型等等,下面用异常处理的两种类型来说明,笔者见过很多的Java程序员写过很多年的代码仍然分不清楚其中的区别。
    Checked 和 unchecked exceptions
    Unchecked exceptions 
    一般用于表示程序中的Bug, 比如函数调用中的非法参数异常,Java 创始人对Unchecked exceptions的解释是Unchecked exceptions是通常不可以恢复的运行时异常,换句话说,Unchecked exceptions 其实就是RuntimeException,常用的Unchecked exceptions有IllegalArgumentException, NullPointerException, 和 IllegalStateException,Unchecked exceptions通常不需要添加到函数签名列表,并且在调用方不需要强制使用try..catch。

    Checked exceptions 
    通常用于表示函数执行过程中的一些pre condition 没有得到满足,这些条件通常超出了函数的控制范围,比如无效输入,数据库连接问题,网络异常,文件丢失等问题,Checked exceptions的父类是Exception,Checked exceptions需要添加到函数签名列表,并且在调用方需要强制使用try..catch来捕获Checked exceptions。

    2.效率和速度
    记得有一次一个朋友的老板和客户谈了一个项目,客户想先看看效果然后做决定某些功能是不是他想要的,于是老板问下面的一个工程师需要多久做出一个demo,这个人想了一天,说最快也要一个月,老板觉得太慢,于是问另外一个工程师,他给出的结论是demo只需要3天,结果3天的确实做完了,而且没有加班。那么为什么差这么多呢,脚本语言,脚本语言可以大幅的提升工作效率,特别是原型设计阶段,下面以Groovy操作XML为例加以说明。假设有很多这样的XML数据需要处理,试想一下如果使用Java会是一番什么样的景象呢。
    [code][size=14]<books>
     <book name="Effective C++">
       <author>Scott Meyers</author>
     </book>
     <book name="More Effective C++">
       <author>Scott Meyers</author>
     </book>
     <book name="C++ Primer">
       <author>Stanley B. Lippman</author>
     </book>
     <book name="Core Java">
       <author>Cay S. Horstmann</author>
     </book>
     <book name="Effective Java">
       <author>Joshua Bloch</author>
     </book></books>[/size]
    [/code]
    下面演示一下如何通过Groovy Script驾驭上面那段XML, 输出配对的书名和作者,并且过滤出所有Scott Meyers的著作,可以看出,除了打印输出,几乎所有的需求只要一行代码就可以解决。
    [code][size=14]println"--solidmango design start--"  languages = new XmlParser().parse(‘TestXML.xml')

    println "Books and authors"languages.each {
     println "<<${it.@name}>> authored by ${it.author[0].text()}"}

    def languagesByAuthor = { authorName ->
       languages.findAll { it.author[0].text() == authorName }.collect {
         it.@name }.join(', ')
    }

    println"-------------------------"  println "Languages by Scott Meyers:" + languagesByAuthor('Scott Meyers')

    println"--solidmango design end--"[/size]
    [/code]
    输出:
    [code][size=14]--solidmango design start--Books and authors<<Effective C++>> authored by Scott Meyers<<More Effective C++>> authored by Scott Meyers<<C++ Primer>> authored by Stanley B. Lippman<<Core Java>> authored by Cay S. Horstmann<<Effective Java>> authored by Joshua Bloch-------------------------Languages by Scott Meyers:Effective C++, More Effective C++--solidmango design end--[/size]
    [/code]
     

    【吐你没商量】那些年让你很受伤的面试~~

    吐槽lanqiao 发表了文章 • 0 个评论 • 14 次浏览 • 2 天前 • 来自相关话题

    一直吐槽没啥面试 刚突然发现简历上手机号少了一个数 内心无数个biiiiiii   你在面试中遇到过哪些不开心的事,说出来让大家开心开 ...查看全部
    一直没啥面试
    刚突然发现简历上手机号少了一个数
    内心无数个biiiiiii

    timg.gif

     
    你在面试中遇到过哪些不开心的事,说出来让大家开心开心吧!~
     

    计算机专业男生的求和,和我的。。。

    吐槽lanqiao 发表了文章 • 0 个评论 • 23 次浏览 • 2 天前 • 来自相关话题

    来自计算机专业男生的求和   and  我的求和: ...查看全部
    来自计算机专业男生的求和
     
    007jtb7Sgy1fwzmnmvvkpj30c80bddjv.jpg


    007jtb7Sgy1fwzmnltjqnj30c80hc767.jpg


    and  我的求和: