phoenix待解决的问题

在HBase Phoenix上建立的表,突然发现数据插入和查出来的条数不一致,变量就是“snappy”,需要看下Phoenix的源代码了。

土豆实时数据:
create table if not exists TD.VVCOUNT_VIDEO_MINUTE
(
MINUTE BIGINT not null,
VID INTEGER not null,
PW BIGINT,
MA BIGINT,
PI BIGINT
constraint pk primary key (MINUTE,VID)
)salt_buckets = 30,versions=1,compression='snappy';
测试库,没加snappy
create table if not exists TD.VVCOUNT_VIDEO_MINUTE_TEST
(
MINUTE BIGINT not null,
VID INTEGER not null,
PW BIGINT,
MA BIGINT,
PI BIGINT
constraint pk primary key (MINUTE,VID)
)salt_buckets = 30,versions=1;

如何写专利

什么可以申请专利?
专利既可以保护装置、结构等产品,也可以保护数据处理、程序控制等方法。专利,仅保护“技术方案”。只要我们所要解决的是技术问题,并且我们解决技术问题的办法采用的是技术手段,这样的提案就属于技术方案,就可以申请专利。
寻找技术问题大致有两个角度:一个角度是从自身找,去收集那些影响我们设计指标或者拖累我们研发进度的技术上的困难;另一个角度是从竞争对手那里找,去挖掘竞品在技术层面可被我们吐嘈的地方。
要满足什么基本条件的方案才能申请?
一项技术方案能否获得专利权,并不是看这个方案有多么复杂,也不是看这个方案是否独创,而是去考察这个方案与现有技术的区别是否显而易见。在撰写专利提案时不要过多考虑技术高度的问题。
产品和专利是什么关系?
我们需要对产品进行“技术分解”,将一个产品分解成若干“技术分支”,“技术分解”做的越细致,专利提案点就越容易找到。
挖掘专利的基本方法是什么?
寻找发明点的前提在于寻找技术问题。户的“痛点”就是技术问题所在,工程师治愈“痛点”的设计思路就是发明点。建议开发人员或测试人员,大家在日常工作中要有心地去记录每次技术会议的内容,只要将我们每次版本更新或者产品升级的原因转化成“技术问题”,将程序代码或电路布图的设计思路落在纸面上,每个人都有可能成为年产数件专利的“大发明家”。
技术方案 就是 发明点+使发明点能够工作的技术细节。
挖掘 技术主题 —>技术问题 —>发明点 —>技术方案
为什么要做专利检索?
检索同行专利文献的好处主要有三个,一是站在巨人的肩膀上研发,不会闭门造车;二是便于及时察觉专利风险,以便提前规避;三是基于同行专利进行改进,提升公司专利商业价值。
专利检索网站:
http://epub.sipo.gov.cn/index.action
http://www.patentstar.com.cn/My/SmartQuery.aspx
专利文献该怎么读?
一般情况下每一条检索式命中的结果至少都有几十件,因为专利文献一般会用法律语言写得比较晦涩,搞研发的同学一看到检索到这么多相关或不相关的专利就头大了——这可怎么读啊?其实读专利是有窍门的。我们在拿到一份专利文献时,不要按照页码顺序阅读,而是要跳着读。首先要粗读“摘要”部分,初步确定是否有进一步深入阅读全文的必要,如果大致一读感觉相关度很低,即可以PASS掉;第二要阅读“背景技术”部分,以了解该专利的施用范围和技术问题;第三要结合“附图”阅读“具体实施方式”部分的第一个实施例,至此,研发人员已经可以基本理解该专利的发明构思了。如果有进一步规避同行专利的需求,再回过来读“权利要求”部分,最后这一步是可选项哦。

移动开发的现状

77%以上移动开发者年龄小于30岁,平均领域开发经验小于3年
访问在线教育资源和在工作中学习是开发者最主要的获取技能方式
大多数的移动开发者会选择移动应用领域创业,新兴智能硬件领域的创业趋势发展迅猛
O2O、工具类移动应用和智能家居类的智能硬件开发是当前热点
Java依然是移动应用领域最主要的编程语言,但是HTML5/JavaScript混合语言开发和Swift的使用者增长明显
第三方支付服务作为需求量最大的服务,基本被支付宝和微信支付垄断
有超过一半的Android应用缺乏加固措施
稳定性、易用性和兼容性是移动开发者在选择服务平台时最优先考虑的因素
充分利用第三方网络渠道推广,已经成为各类移动应用以及智能硬件开发者的基本推广模式
移动应用版本升级及跨平台兼容性问题依然是困扰大多数开发者的问题
2015年智能硬件的发行渠道则出现了由自身官网向多渠道转变趋势
分析结果清楚地表明使用第三方云平台、云服务加速应用开发已经成为趋势,在移动应用领域使用云服务的企业数量比较2014年增加了12%
知道现状,指导未来

为什么“hbase.zookeeper.quorum”必须配奇数个

zookeeper有这样一个特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的。也就是说如果有2个zookeeper,那么只要有1个死了zookeeper就不能用了,因为1没有过半,所以2个zookeeper的死亡容忍度为0;同理,要是有3个zookeeper,一个死了,还剩下2个正常的,过半了,所以3个zookeeper的容忍度为1;同理你多列举几个:2->0;3->1;4->1;5->2;6->2会发现一个规律,2n和2n-1的容忍度是一样的,都是n-1,所以为了更加高效,何必增加那一个不必要的zookeeper呢。

HBase Phoenix UDFs的实现

HBase里的Phoenix的UDFs的实现,HBase的版本是0.98,Phoenix的也需要选择对应的版本。
参考文章:
http://phoenix.apache.org/udf.html
http://phoenix-hbase.blogspot.com/2013/04/how-to-add-your-own-built-in-function.html(翻墙才能打开,而且这篇文章很旧,2013年的)
官网说Phoenix 4.4.0版本才实现了让用户拥有使用自定义函数的功能。话说以前的3.0版本我们都是把自定义函数写到系统函数里的,这个需要编译Phoenix的源码,对后期版本的升级很不友好。因此4.4.0版本可以说有他的积极意义的O(∩_∩)O哈哈~
直接上代码吧,UrlParseFunction.java类

package phoenix.function;
import java.sql.SQLException;
import java.util.List;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.function.ScalarFunction;
import org.apache.phoenix.parse.FunctionParseNode.Argument;
import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.types.PInteger;
import org.apache.phoenix.schema.types.PVarchar;
import phoenix.util.DiscoverUrlUtil;
import phoenix.util.DomainInfo;
@BuiltInFunction(name=UrlParseFunction.NAME,  args={
		@Argument(allowedTypes={PVarchar.class}),
		@Argument(allowedTypes={PInteger.class})} )
public class UrlParseFunction extends ScalarFunction {
    public static final String NAME = "URLPARSE";
    private static final int TYPE1 = 1;
    private static final int TYPE2 = 2;
    private static final int TYPE3 = 3;
    public UrlParseFunction() {
    }
    public UrlParseFunction(List children) throws SQLException {
        super(children);
    }
    @Override
    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
    	Expression strExpression = getStrExpression();
        if (!strExpression.evaluate(tuple, ptr)) {
            return false;
        }
        String sourceStr = (String)PVarchar.INSTANCE.toObject(ptr, strExpression.getSortOrder());
        if (sourceStr == null) {
            return true;
        }
        Expression typeExpression = getTypeExpression();
        if (!typeExpression.evaluate(tuple, ptr)) {
            return false;
        }
        int panelType = (Integer)PInteger.INSTANCE.toObject(ptr, typeExpression.getSortOrder());
        if (panelType == TYPE1) {
            String topDomain = DomainInfo.getDomainGroup(sourceStr);
            ptr.set(PVarchar.INSTANCE.toBytes(topDomain != null ? topDomain : "other"));
        } else if (panelType == TYPE2) {
        	String sClassificationName = DiscoverUrlUtil.getSClassificationName(sourceStr);
        	ptr.set(PVarchar.INSTANCE.toBytes(sClassificationName));
        } else if (panelType == TYPE3) {
        	String urlName = DiscoverUrlUtil.getUrlName(sourceStr);
        	ptr.set(PVarchar.INSTANCE.toBytes(urlName));
        } else {
        	throw new IllegalStateException("parse type should be in (1,2,3).");
        }
        return true;
    }
    @Override
    public PDataType getDataType() {
        return getStrExpression().getDataType();
    }
    @Override
    public boolean isNullable() {
        return getStrExpression().isNullable();
    }
    @Override
    public String getName() {
        return NAME;
    }
    private Expression getStrExpression() {
        return children.get(0);
    }
    private Expression getTypeExpression() {
        return children.get(1);
    }
}

其中,DomainInfo.java和DiscoverUrlUtil.java是两个工具类,获取url对应的中文名称。
下面的两段代码是要求必须要重写的:

@Override
    public PDataType getDataType() {
        return getStrExpression().getDataType();
    }
@Override
    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
    	Expression strExpression = getStrExpression();
        if (!strExpression.evaluate(tuple, ptr)) {
            return false;
        }
        ......
        return true;
    }

pom.xml代码:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.youku</groupId>
    <artifactId>phoenix</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
		<dependency>
		  <groupId>sqlline</groupId>
		  <artifactId>sqlline</artifactId>
		  <version>1.1.9</version>
		</dependency>
        <dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>4.4.0-HBase-0.98</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.hbase</groupId>
                    <artifactId>hbase-server</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.hadoop</groupId>
                    <artifactId>hadoop-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>


以上代码需要打包成jar包,上传到HBase集群的HDFS上,并在进入Phoenix的shell以后,输入下边的代码,将函数注册到Phoenix里。

CREATE FUNCTION URLPARSE(varchar,integer) returns varchar as 'phoenix.function.UrlParseFunction' using jar 'hdfs://0.0.0.0:8010/hbase/udf/phoenix-1.0-SNAPSHOT.jar';

完整的代码结构:

hadoop jar包移除和上传命令:

hadoop fs -rm /hbase/udf/phoenix-1.0-SNAPSHOT.jar
hadoop fs -put /root/test/phoenix-1.0-SNAPSHOT.jar /hbase/udf/

PS:hbase-site.xml也需要做修改,需要将修改后的文件上传到Phoenix的客户端里,只需要修改客户端即可。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<configuration>
<property>
  <name>phoenix.functions.allowUserDefinedFunctions</name>
  <value>true</value>
</property>
<property>
  <name>fs.hdfs.impl</name>
  <value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
</property>
<property>
  <name>hbase.dynamic.jars.dir</name>
  <value>${hbase.rootdir}/lib</value>
  <description>
    The directory from which the custom udf jars can be loaded
    dynamically by the phoenix client/region server without the need to restart. However,
    an already loaded udf class would not be un-loaded. See
    HBASE-1936 for more details.
  </description>
</property>
<property>
           <name>hbase.master</name>
           <value>0.0.0.0:6000</value>
</property>
<property>
           <name>hbase.master.maxclockskew</name>
           <value>180000</value>
</property>
<property>
    <name>hbase.rootdir</name>
    <value>hdfs://0.0.0.0:8010/hbase</value>
</property>
<property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
</property>
<property>
    <name>hbase.tmp.dir</name>
    <value>/opt/hbase/tmp</value>
</property>
<property>
    <name>hbase.zookeeper.quorum</name>
    <value>localhost</value>
</property>
 <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/opt/storage/zookeeper</value>
    <description>Property from ZooKeeper's config zoo.cfg.
    The directory where the snapshot is stored.
    </description>
  </property>
  <property>
           <name>dfs.replication</name>
           <value>1</value>
   </property>
</configuration>

最后的效果:

0: jdbc:phoenix:localhost:2181&gt; select urlparse(cat4,3) from yk.video_channel_source where videoid = 100059807;
+------------------------------------------+
|            URLPARSE(CAT4, 3)             |
+------------------------------------------+
| www.baidu.com                            |
+------------------------------------------+
1 row selected (0.081 seconds)
0: jdbc:phoenix:localhost:2181&gt; select urlparse(cat4,2) from yk.video_channel_source where videoid = 100059807;
+------------------------------------------+
|            URLPARSE(CAT4, 2)             |
+------------------------------------------+
| 其他                                       |
+------------------------------------------+
1 row selected (0.104 seconds)
0: jdbc:phoenix:localhost:2181&gt; select urlparse(cat4,1) from yk.video_channel_source where videoid = 100059807;
+------------------------------------------+
|            URLPARSE(CAT4, 1)             |
+------------------------------------------+
| *.baidu.com                              |
+------------------------------------------+
1 row selected (0.086 seconds)

HBase读写流程

client写入=》存入MemStore,一直到MemStore存满=》Flush成一个StoreFile,直到增长到一定的阈值=>触发Compact合并操作=》多个StroeFile合并成一个StoreFile,同时进行版本合并和数据删除=》当StoreFile Compact后,逐步形成越来越大的StoreFile=》单个StoreFile大小超过一定阈值后,触发Split操作,把当前的Region Split成2个Region,父亲Region会下线,新Split出的2个孩子Region会被Master分配到相应的HRegionServer上,使得原先1个Region的压力得以分流到两个Region上。由此过程可知,HBase只是增加数据,所有的更新和删除操作,都是在Compact阶段做的,所以,用户写操作只需要进入到内存即可立即返回,从而保证I/O高性能。
HSore:是hbase的存储核心,由两部分组成,一部分是MemStore,一部分是StoreFile。
HLog:在分布式环境中,无法避免系统出错或者宕机,一但HRegionServer意外退出,MemStore中的内存数据就会丢失,引入HLog就是防止这种情况。
HLog的工作机制:每个HRegionServer中都会有一个HLog对象,HLog是一个实现Wite AheadLog类,每次用户操作写入Memstore的同时,也会写一份数据到HLog文件,HLog文件会自动滚动出新,并删除旧文件(已经持久化到StoreFile中的数据)。当HRegionServer意外终止后,HMaster会通过ZooKeeper感知,HMaster首先处理遗留下来的HLog文件,将不同的region的log数据拆分,分别放到相应的region目录下,然后再将失效的region(带有刚刚拆分的log)重新分配,领取到这些region的HRegionServer在load Region的过程中,会发现有历史HLog需要处理,因此会ReplayHLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。
Region:region就是StoreFile,StoreFile里由HFile构成,HFile里由hbase的data块构成,一个data块里面又有很多的key value对,每个key value里存了我们需要的数据。
http://my.oschina.net/u/1464779/blog/265137
HBase读流程:
client->zookeeper->.ROOT->.META-> 用户数据表zookeeper记录了.ROOT的路径信息(root只有一个region),.ROOT里记录了.META的region信息, (.META可能有多个region),.META里面记录了region的信息。

HBase Shell无法删除

在secureCRT中,点击【选项】【回话选项】【终端】【仿真】,右边的终端选择linux,在hbase shell中如输入出错,按住Ctrl+删除键 即可删除!

训练对数字的敏感

开经营会议的时候,我常常发现很多中高层管理人员,对数字相当的不敏感。有时候,整个一场会开完,有些管理人员对各部门所报告的数据,既无问询,也不质疑,只是盯着幻灯片,任其往下翻。而报告的人,常常将一些数字念到个位数,乃至小数点后面两位数,也让我觉得不可思议。我觉得这样的会议,这样的数字,这样的管理人员,都没有价值。不能透过数字,看出数字背后的问题的管理人员,不是好管理人员。要么赶快训练对数字的敏感度,要么,干脆另谋生路。
这让我想自己与数字打交道的故事。
读书时,我的数学成绩并不好。参加工作后,我所从事的工作,却是个天天跟各种数据打交道的工作。至今还记得,第一次做统计数据的工作,一堆数字,我加过去,而后加过来,怎么都对不起来。第二天就要交那份报告,那天晚上,我却被困在一堆数字里,晕头转向,欲哭无泪。在快要绝望的时候,一位新来的工程师来找资料,成了我最后的救命稻草。在我的万般央求之下,他帮我把那堆统计数据给弄了出来。
从此,那些数据就变成了我的噩梦。有段时间,我做梦的主要内容,就是不停计算数字。但我却常常因为一些数字的准确性,而被上司骂得狗血喷头。我不服气,但又无奈。有些事情,我也常常搞不懂,那些数字都是我统计的,一个个都是我输进电脑,做成图表的。为何我发现不了其中的错,而上司翻翻,扫一眼,就能发现错误呢?
后来,我从统计,被调入生产线,之后,又被调去任品质部主管。最糟糕的事情,就发生在那一年。工作忙,常常起早贪黑。每次开会,检讨工作,除了带着一堆资料之外,当然还要记住很多重要的数据。但我是对数据不敏感。其结果是,我越想拼命记住那些数字,我的记忆力却变得越差。一度到了我跟别人讲话,讲了上半句,竟然会忘记下半句想讲什么。
有一天,我们在那里进行月度检讨。老板问财务部经理一些经营数字,比如销售业绩,成本状况,等等,我听财务部经理在那里翻着月统计报表,答:“8360912元”,“337231元”,“4053222元”。老板忽然问起三个月前的材料成本数据,财务经理傻眼了,手上没有报告,答不出来。我恰好记得那些数据,便顺口答:“234万。占了整个产值的28%。”散会后,我很奇怪,对数据一向迟钝如我的人,何以记得三个月前的成本数据?仔细想,原来那时候我要分析品质成本,就看了整个成本数据。但我记忆力本身就差,又对数字不敏感,所以只是记了大数。
记大数?我忽然开了窍。我过去之所以记不住那么多数据的原因,想来大概也如财务经理一样,数字弄得太精准。数字精准,就必须得花大力气去记。但事实是,没有人有那样的精力和能力,记得那些精确到个位的数字。我仔细分析了一下,发现,在企业里,做为管理人员,分析和判断时,只需要到万位数就可以,万以下的数字,可以忽略不计。另外一些数字,则只需要记住百分比即可。有了大数,有了百分比,有些数字记不住,其实不打紧,一推算,就出来了。
之后,我再接再厉,继续分析总结,发现,其实,很多数字是有规律的。比如成品率,废品率,材料成本,管理费用,他们都在某个百分比上下波动。记住了上年度,或者本年度第一季度的大数(到万即可)和百分比,以其为参考基准线,后面几个月,上下的波动,其实很容易记住。如果报表中,忽然出现某个跳动太明显的数字,自然便是异常的。快速判断这个异常是计算错误,还是真的异常,只需要看与其相关联的数字即可,如果与其相关联的数字也随之波动,则是真的异常,如果与之相关联的数据没有太大变化,立刻就可以判断出来,这个数字的计算是有问题的。
大数当然只是用于方向和趋势的判断。仅仅记住大数是不够的,还要记住每个项目的关键指标。关键指标,是很多数字赖以存在的基础和基点。比如,计划部门,必须记住物料采购周期,产品生产周期、按时交货率、每个工序标准加工时间等等,以此为参考基点,任何与之相关的数字拿来一比,他可以立即判断进度是否异常。若考核业绩的话,一定要记得部门平均业绩,个人平均业绩,最高、最低业绩等。如果是市场部,除了记住一个月的销售指标外,自然要分解到每天,每个片区的销售业绩指标,到哪天,只要看当天业绩和累积大数,自然对销售状况了然于胸了。
除了根据大数和关键指标去衡量和判断之外,还要随着异常的波动,适当调整自己的注意力。每天,那些项目虽然重要,但是在图表上显示正常的数据,可以一扫而过,不必为之花时间。你要集中注意力,重点盯异常点。一般异常的,就是一个,或者几个点而已,所以,你会很容易关注的过来,自然也就很容易记得住,盯得住。其实,只要理解了数字背后的意义,记住相关数字,是比较容易的事。
当明白了这些的时候,我就开始调整我的工作方法,记数字的方式,有意识训练自己。后来,我尝试让自己记住更大范围、更宏观的数字,比如世界范围内的行业数字,在日本、美国、韩国、台湾等国家地区的数字,中国的行业数据,某个地区的行业数据。我尽大可能放宽我的视野,搜寻与我所从事领域相关联的数字,拿来判断一下,琢磨一下它的好坏,根据它的走势,寻找一下它的判断基准点。渐渐的,我也变成了一个对数字敏感的人。
特别是我离开原来的公司,到了新公司之后,能快速记住主要的关键指标和数字。我在一两天之内,就能从各部门提供的数据和报告中找出问题;我能看一眼财务的数据,就指出那些重要指标与世界发达国家水平及中国发达地区水平、行业平均水平的差异,乃至重要物料计算是否准确。我甚至能比排计划的人,更能快速计算出物料需求量,生产中可能受阻的位置和可能受阻的时间等等。他们常常惊叹我对数字的敏感程度,以为我的记忆力超人。其实非也。到现在,我还会常常忘掉很多常用的电话号码,每次都要从手机中查,甚至不记得现在租住房子的门牌号码。之所以能记住与那么多与工作有关的数字,无非是我对工作用心,找到了一点点记住数字的技巧和规律。总结起来,其实也相当简单,就几句话:“记大数,略小数,有事没事,琢磨琢磨关键指标,盯紧异常数。
转自:
http://site.douban.com/129505/widget/notes/5254608/note/195879174/

IT人,不要一辈子靠技术生存

我现在是自己做,但我此前有多年在从事软件开发工作,当回过头来想一想自己,觉得特别想对那些初学JAVA/DOT。NET技术的朋友说点心里话,希望你们能从我们的体会中,多少受点启发(也许我说的不好,你不赞同但看在我真心的份上别扔砖头啊).
一。 在中国你千万不要因为学习技术就可以换来稳定的生活和高的薪水待遇,你千万更不要认为哪些从事 市场开发,跑腿的人,没有前途。
不知道你是不是知道,咱们中国有相当大的一部分软件公司,他们的软件开发团队都小的可怜,甚至只有1-3个人,连一个项目小组都算不上,而这样的团队却要承担一个软件公司所有的软件开发任务,在软件上线和开发的关键阶段需要团队的成员没日没夜的加班,还需要为测试出的BUG和不能按时提交的软件模块功能而心怀忐忑,有的时候如果你不幸加入现场开发的团队你则需要背井离乡告别你的女友,进行封闭开发,你平时除了编码之外就是吃饭和睡觉(有钱的公司甚至请个保姆为你做饭,以让你节省出更多的时间来投入到工作中,让你一直在那种累了就休息,不累就立即工作的状态)
更可怕的是,会让你接触的人际关系非常单一,除了有限的技术人员之外你几乎见不到做其他行业工作和职位的人,你的朋友圈子小且单一,甚至破坏你原有的爱情(想象一下,你在外地做现场开发2个月以上,却从没跟女友见过一面的话,你的女友是不是会对你呲牙裂嘴)。
也许你拿到了所谓的白领的工资,但你却从此失去享受生活的自由,如果你想做技术人员尤其是开发人员,我想你很快就会理解,你多么想在一个地方长期待一段时间,认识一些朋友,多一些生活时间的愿望。
比之于我们的生活和人际关系及工作,那些从事售前和市场开发的朋友,却有比我们多的多的工作之外的时间,甚至他们工作的时间有的时候是和生活的时间是可以兼顾的,他们可以通过市场开发,认识各个行业的人士,可以认识各种各样的朋友,他们比我们坦率说更有发财和发展的机会,只要他们跟我们一样勤奋。(有一种勤奋的普通人,如果给他换个地方,他马上会成为一个勤奋且出众的人。)
二。在学习技术的时候千万不要认为如果做到技术最强,就可以成为100%受尊重的人。
有一次一个人在面试项目经理的时候说了这么一段话:我只用最听话的人,按照我的要求做只要是听话就要,如果不听话不管他技术再好也不要。随后这个人得到了试用机会,如果没意外的话,他一定会是下一个项目经理的继任者。
朋友们你知道吗?不管你技术有多强,你也不可能自由的腾出时间象别人那样研究一下LINUX源码,甚至写一个LINUX样的杰作来表现你的才能。你需要做的就是按照要求写代码,写代码的含义就是都规定好,你按照规定写,你很快就会发现你昨天写的代码,跟今天写的代码有很多类似,等你写过一段时间的代码,你将领略:复制,拷贝,粘贴那样的技术对你来说是何等重要。(如果你没有做过1年以上的真正意义上的开发不要反驳我)。
如果你幸运的能够听到市场人员的谈话,或是领导们的谈话,你会隐约觉得他们都在把技术人员当作编码的机器来看,你的价值并没有你想象的那么重要。而在你所在的团队内部,你可能正在为一个技术问题的讨论再跟同事搞内耗,因为他不服你,你也不服他,你们都认为自己的对,其实你们两个都对,而争论的目的就是为了在关键场合证明一下自己比对方技术好,比对方强。(在一个项目开发中,没有人愿意长期听别人的,总想换个位置领导别人。)
三。你更不要认为,如果我技术够好,我就自己创业,自己有创业的资本,因为自己是搞技术的。
如果你那样认为,真的是大错特错了,你可以做个调查在非技术人群中,没有几个人知道C#与JAVA的,更谈不上来欣赏你的技术是好还是不好。一句话,技术仅仅是一个工具,善于运用这个工具为别人干活的人,却往往不太擅长用这个工具来为自己创业,因为这是两个概念,训练的技能也是完全不同的。
创业最开始的时候,你的人际关系,你处理人际关系的能力,你对社会潜规则的认识,还有你明白不明白别人的心,你会不会说让人喜欢的话,还有你对自己所提供的服务的策划和推销等等,也许有一万,一百万个值得我们重视的问题,但你会发现技术却很少有可能包含在这一万或一百万之内,如果你创业到了一个快成功的阶段,你会这样告诉自己:我干吗要亲自做技术,我聘一个人不就行了,这时候你才真正会理解技术的作用,和你以前做技术人员的作用。
[小结]
基于上面的讨论,我奉劝那些学习技术的朋友,千万不要拿科举考试样的心态去学习技术,对技术的学习几近的痴迷,想掌握所有所有的技术,以让自己成为技术领域的权威和专家,以在必要的时候或是心里不畅快的时候到网上对着菜鸟说自己是前辈。
技术仅仅是一个工具,是你在人生一个阶段生存的工具,你可以一辈子喜欢他,但最好不要一辈子靠它生存。
掌握技术的唯一目的就是拿它找工作(如果你不想把技术当作你第二生命的话),就是干活。所以你在学习的时候千万不要去做那些所谓的技术习题或是研究那些帽泡算法,最大数算法了,什么叫干活?
就是做一个东西让别人用,别人用了,可以提高他们的工作效率,想象吧,你做1万道技术习题有什么用?只会让人觉得酸腐,还是在学习的时候,多培养些自己务实的态度吧,比如研究一下当地市场目前有哪些软件公司用人,自己离他们的要求到底有多远,自己具体应该怎么做才可以达到他们的要求。等你分析完这些,你就会发现,找工作成功,技术的贡献率其实并没有你原来想象的那么高。
不管你是学习技术为了找工作还是创业,你都要对技术本身有个清醒的认识,在中国不会出现BILL GATES,因为,中国目前还不是十分的尊重技术人才,还仅仅的停留在把软件技术人才当作人才机器来用的尴尬境地。(如果你不理解,一种可能是你目前仅仅从事过技术工作,你的朋友圈子里技术类的朋友占了大多数,一种可能是你还没有工作,但喜欢读比尔。盖茨的传记)。

程序员

程序员

五一放轻松

五一放轻松,该干点啥就干点啥呗!