做事情不能太急切

上个空降领导我受不了,最主要的一个问题就是做决定太快且改来改去,其实我自己也有这个问题,恐怕是同性相斥,所以我才那么受不了他吧。

虽然出发点也许是好的,举个例子,公司新上线的系统,用起来问题重重,我在用的时候,遇到一些小问题都会找人汇报,认为即使小问题也要尽快修复,还会自作聪明的加一些自己的判断和猜测,然后难免会有一些抱怨。

但实际上,不是每个问题都有解决办法,也不是每个人都是合适的人,这样并不能解决问题,还把自己拖进了问题的深渊,而且本来不是我的深渊。

action plan

少说话,用邮件。写出来的字通常要在脑子里组织一两遍,发出去之前还有改的余地。

对不熟悉的人先不要提观点,甚至要求。找不到频率容易出问题。

提要求之前,5W1H(5W2H1E),是不是在对的时候找了对的人。

摒除个人情绪,不抱怨。

 

2017下半年计划

首先要保障作息时间,最近一个月都是晚11点前睡觉,早6点起床,不熬夜精神状态好了很多。

锻炼身体,现在基本能保证每天运动30分钟,在家的话早上起床去打篮球,下雨或者出差就做做平板支撑和卷腹。

身体好才能执行其他目标啊。

然后是英语,但是如何提高英语水平也是个问题,初步想法是增加阅读量,强制自己读一些英文报纸,然后翻译一些东西。之前看手册太多,词汇量和阅读量都有局限性。把维基百科的帐号捡起来。

动手写点代码,最近三年其实写过不少代码,准备收集一下,写一个库出来,写得规范一些,看看自己在这方面到底能做到什么程度。

阅读,办了张北京市公共图书馆网络联合读者卡,家门口(开车30分钟)的图书馆环境也不错,以后多跑一跑,多看看书。

卖身契即将到期

德国待了一年,签了三年的培训发展协议,还有2周就到期了。

我自己觉得有意思的是,离合同到期还有很长时间的时候,脑袋里总是想着跳个槽,违约成本是多少,算啊算。现在到期了,想换工作的想法却淡了很多。

原因恐怕是习惯了,从工作开始,直到从德国回来后的半年,整个职业发展虽然算不上快,但是也是稳定的上升通道,转折点恐怕就是出国那一年。回国后,习惯了的稳定顺利变成了处处不顺,于是各种急切的想换个能让自己回到顺心的环境。

如果当时真的跳槽了,现在恐怕也不会很顺利,之前顺利的原因恐怕有这么几个:

  1. 在一个公司干得太久,习惯了一种固定的节奏。
  2. 和当时的领导配合时间比较长,风格互相适应。
  3. 级别低,机会多。
  4. 做技术工作,评价系统相对简单。

而感觉处处不顺,除了出国一年导致的断层,就是这四条多少都发生了些变化。现在到有点庆幸当时没有跳槽成功,除非运气极好,否则跳槽完全不能解决这个问题。而我连在同一家公司都没能处理好,换了环境后,处理不好的概率更大一些。

解决其中一个问题不难,四个放一起,我现在也没有能力搞定,而且我也没有认真思考如何解决,过去三年用来抱怨的时间更多一些,像今天下午这样能慢慢想,写下来,再修改的时间应该多分配一些,少一些无作用的抱怨。

 

定位问题

前几天看Billboard排行榜,前十经常出现Justin Bieber,作为不流行的人,脑中的反应就是这小哥天天作,怎么还能在榜单上晃。

仔细想想,虽然排行榜和歌手本身的人气有一定关系,但是还要是歌(作品)本身拿得出手。

回到工作上,也是类似的,如果是销售,那么只要销售额高,靠不靠谱并不重要;工程师能搞定问题,那么沟通能力强不强也不是太重要。

那么问题来了,我现在的定位是什么呢?

2016年雪季

13年入的坑,由于不会开车,在德国的一年几乎没有出去玩,同事很热情的邀我去滑雪,于是入了坑。

老外对于度假的安排和我们的确是不一样,整个行程用了6天,单程开了4个多小时的车,用了一天在往返的路上,中间5天都在滑雪。反过来看国内,可能由于假期非常紧张的缘故,很少有人旅游5天住在同一个房间做同一件事的。

参加了教学班,标准版是5天的学习,由于想留出时间自己玩,于是报了3天的压缩班,学会基本动作后自己玩了两天。

回国后老婆一直念念不忘,不过更多的是对5天的假期,以及意大利的雪山景色,我也一直在怂恿她在国内继续滑雪,因为她实在不爱运动,难得有个她稍微感点兴趣的事情。

今年得以成行,主要原因是我拿到了驾照,我们生活的半径变大了,我老婆虽然驾龄比我长,但是对于开车并不热衷,甚至有点抵触,另外就是16年冬天终于搬到了非租赁的房子,很多时候买东西的心情不一样了。不怕搬家时折腾了。

北京的雪季大概是12月初到3月初,3个月左右,说服老婆已经春节过后的一月底了,先买了两套入门的装备,平均一套大约要6K,先去家旁边的云居寺滑雪场试了试装备,虽然地小人多,但是毕竟开车只要半小时,比较适合调试。滑了大约4小时,我的固定器买来后没有任何调整,结果松到飞起,随便一使力板就飞了,胳膊砸到了雪杖上,第一天就弯了。老婆的雪杖也没能幸免,在坡底被不会制动的人直接撞弯,幸好没有撞到人。

隔了一天直奔崇礼,从房山过去稍远,由于是夜路,中间几乎所有的休息区都停下来休息了一下,开到多乐美地用了将近4小时,19年会开通到崇礼的直达高速公路,估计时间能减少1个半小时左右,毕竟现在要从张家口绕100公里左右。

最后大概玩了一天半,住了两天,住宿800多,400多油费,200多高速费,季末打折雪票400,早的话要800,估计2天的旅程大约消费是2400-3000。

滑雪本身,我和老婆正式学了三天,基础打得算比较好,但是三年没滑也用了些时间恢复,滑雪的时长基本可以按天算,我们只有8天,还算是非常初学的水平,我老婆犁式一带而过,正在练平行式,我的犁式右转弯一直有问题,跳过这个练平行反而动作更流畅,不过感觉跳过某个技术环节,未来总会有些隐患。

两天主要滑了多乐的米兰道和博洛尼亚道,长1500米,平均坡度13度,算是中级道,但是由于地形问题,个别地方相当歪,相当陡,我和老婆在米兰道上摔得有点心虚,我还冲出边网一次,甚是危险。博洛尼亚比较宽,所以后半段我们基本就在博洛尼亚上滑,道也熟悉了,动作也想起来了,基本没怎么摔。

犁式转弯在转的拐点处,速度会降到非常低,而且整个转弯的过程要靠山下脚单脚支撑,尤其对于我这个体重,膝盖的压力非常大,上次5天滑完膝盖疼得不得了,尝试练平行式,同样需要在拐弯处把速度降下来,但是没有犁式这么慢,我还没有仔细看教学视频,现在的感觉是,随时保持两脚平行,走S型,板的角度随时与S轨迹相切,下坡时微蹲,转弯时微调重心直起身体。

然后就是初学者太多,很多我看来非常重要的东西他们却不在意,比如如何上下板,比如如何从地上站起来,如何上下拖牵,甚至很多人连护具都不全,尤其是国内单板特别多,在中级道上经常遇到两三个单板随时在道中间一停,然后席地而坐开聊,真的是很危险。

 

2016年总结+牢骚

2016是失败的一年。

一切结果皆有原因,与各种近期内的外因比起来,导致15和16两年都荒废的根本原因在于12年出国的决定。12年部门结构调整,当了代主管,说是试用半年OK就给Title,结果到了年底,7个多月了依旧没有消息,甚至连私下的沟通也没有,于是当时不想耗了,想辞职出国留学,当时的Line Manager也了解我的情况,于是费了不少力气帮我找了个折中的办法,派到德国一年。13年6月成行,14年6月回国,不能说这个决定是错的,只是风险太大,也的确没有太多的回报。不过既然是自己的选择,也谈不上后悔,总算还是年轻,还有一些犯错的资本。

1月,R玩了F总一把,F休假前特意开了次会交待事情,让把Q2的招聘尽快招进来,R当时满口答应,F休假后的第一天,R就改了决定,开会说他做主,这些人全部冻结不招了,然后K应该也是年终奖到手,提了辞职,R和K关上门谈了一阵,据说达成了共识,K自己开公司后还和R合作,这事就订了,于是F休了两周假回来,招聘也冻结了,赏识的人也辞职走人了。不知道当时有没有生一点点气呢。

3月,春节过后,“分单”的事情R终于推进不下去了,BOSS直接给了否定,而且由于营业额差距非常大,导致了R被BOSS强烈的Challenge,于是R很快速的(当然他一直很快速)做了改变,终于放弃了分单的决策,开始把全部精力投入的销售服务上。这也导致了我对他彻底的失望,原来他并不是意识到了困难而是要改变,而是根本没意识到困难的程序,而意识到后,直接就放弃了。于是从3月份开始,我基本不再给他提任何的建议了。

5月,经过3个月的磨合,我已经把重心从工作转移到了生活,跑跑步锻炼身体,老婆还收养了一只流浪狗,R也意识到了我的(非暴力)不合作,开始越过我指挥,其实我所谓的两个下属都是资格比我老一辈的工程师,我一直都是管而不限,R其实并不知道如何和这两个人打交道。

8月,人心已经彻底散了,算上我,R一共还剩8个直接下属,其中的4个曾经考虑过换部门,而不是换工作,我由于比较失望,也不愿意去争取他的位子,所以已经抱定换不了部门就换工作的想法,期间前领导曾经和我聊过一次,确实是好意,但是我当时已经失去理智了,毕竟我只是和一个人无法合作,却给了BOSS我自以为是,不愿意好好工作的印象。

10月,财年结束,虽然R下半年把所有的精力放在了Revenue上,但是前半年欠账太多,还是没有完成任务,于是结果是两边不得好,其实Revenue指标是个41%的权重,如果你没搞定,你就不及格。但是R是当做60%权重来干的,只要我搞定,其他的40%我都不要了,于是Revenue没完成,老板不满意,其他工作也没干好,技术部门不搞支持,销售的意见还是很大的。
10月底年会,BOSS终于答应给我换个职位,去销售部门当售前支持,我当然很开心,但是太突然,从征询我意见到发公告也就10天不到,连R都没知会,于是R到处和人说我是被挖走了,反正我的目的也达到了,爱怎么说怎么说吧。

11月,有两个比较重要的研讨会,技术方面的,虽然我的关系已经转到了销售,但是毕竟算半个组织者,还是得参加,于是花了不少精力,然后我得到了一个反馈,F总和其他人私下说,我一换部门就不管这面的事情了。我当真很失望,虽然不是直接领导,但是也认识我近十年了,居然连这点信任还没有,而且就在他说这话的时候,我还参加了两周的研讨会,中间老外的衣食住行基本我都帮忙安排,还在做技术支持。约了好久,终于找到他有时间通了个电话,把事情解释了一下,有用没用不知道,虽然我怀疑是有人在煽风点火,但是没有证据也只能当没发生吧。

12月,算是正式到了新岗位,领导又是空降来的,之前是做特种设备的,明显比R要聪明很多,但是也有一些虚浮,不知道是不是空降领导的通病,总是拿之前自己用的成功的一个套路四处套,感觉驾驭起下属来非常的吃力。当然不是指我这种技术nerd。

17年,感觉自己会变成销售-_-b,记得刚毕业时特别的抵触做销售,10年过去,现在还真没这么抵触了,看着来吧。

目标更新

上次更新目标是7月31日。

回顾一下:

车开得还好,这个已经算是正常了,不是计划事项了。

徒弟进步比较快,换了部门这个也不是计划了。

跑步彻底荒废了,得找个锻炼的方法。

这两天和人讨论的时候发现情绪会失控,仔细阅读罗伯特议事规则是有必要的,还得再买本书看看如何进行讨论。

德语也荒废了。

由于换了部门,计划如下:

  1. 锻炼身体,本钱。
  2. 读书,罗伯特议事规则
  3. 德语绝对是要学的。
  4. 多用Outlook的任务,有效管理任务,要在项目管理上下点功夫。

我的SharpDX学习笔记

从开始折腾到觉得自己可以小结一下了,一共三周。

开始是找库,OPENGL还是DirectX其实并不重要,甚至还考虑过Unity,不过最终发现像我这种非主流的需求,还是老老实实的从头学(搞)比较实际。

最终选了DirectX还是因为微软的文档。

SharpDX封装的很好,学习的过程中找到的有效资料基本都是C++的,用SharpDX实现既能对应上,又让我觉得方便了很多(和C++例子比)。

代码我是在一个项目上直接改的,我的目的不是教别人,所以堆在一起,未来看的时候能回忆一下当初的理解过程。

如果其他人看到了,抱歉,这文章是我自己纪录思路的,可能不太适合当作参考。

总的来说,DirectX入门需要一些数学知识储备,向量、矩阵的定义和运算,坐标变换的原理,齐次坐标变换,仿射矩阵,向量单位化(L2Norm),有一些立体的抽象思维能力,坐标系,光源,摄像机,而且绕不开的还有C++的知识,至少要能猜懂。

学习的顺序:

一、找本靠谱的参考书,例如Introduction to 3D Game Programming with Direct3D 11.0

二、测试开发环境,创建一个Device,我在网上找到几个靠谱的Tutorial代码却全在我Win7+VS2015 Community的环境下编译不能。所以测试环境很重要啊。

三、理解PipeLine,细节理解得越清楚越好,否则后面绝对会乱,尤其是C++。

四、针对PipeLine的每一部分,去用代码熟悉一下,总的来说,Directx每一步都有如下套路:描述一下这部分的属性,分配内存(当然分配前要定义结构和空间大小),绑定。C++原始API都是把创建的结果地址当作参数传入,返回结果是出错代码,对习惯了等号右赋左值的C#程序员很不习惯,所以SharpDX封装的好!而且还尽力省略了一些很不常用的参数。

五、别着急,这种底层的API由于灵活,所以每个人的玩法都不一样,没理解的情况下要把两个例子混一块玩会死得很惨,

SharpDX的Camera实现

<Introduction to 3D Game Programming with Direct3D 11.0>第15章Camera类的C#(SharpDX)实现。

using System;
using SharpDX;

namespace SharpDX_Study_001
{
    class Camera
    {
        public Camera()
        {
            mPosition = Vector3.Zero;
            mRight = Vector3.UnitX;
            mUp = Vector3.UnitY;
            mLook = Vector3.UnitZ;
            SetLens(0.2f * SharpDX.MathUtil.Pi, 1.0f, 1.0f, 1000.0f);
        }
        public Vector4 PositionXM
        {
            get
            {
                return new Vector4(mPosition, 0);
            }
        }
        public Vector3 Position
        {
            get
            {
                return mPosition;
            }
            set
            {
                mPosition = value;
            }
        }
        public Vector4 RightXM
        {
            get
            {
                return new Vector4(mRight, 0);
            }
        }
        public Vector4 UpXM
        {
            get
            {
                return new Vector4(mUp, 0);
            }
        }
        public Vector4 LookXM
        {
            get
            {
                return new Vector4(mLook, 0);
            }
        }
        public Vector3 Right
        {
            get
            {
                return mRight;
            }
        }
        public Vector3 Look
        {
            get
            {
                return mLook;
            }
        }
        public Vector3 Up
        {
            get
            {
                return mUp;
            }
        }
        public float NearZ
        {
            get
            {
                return mNearZ;
            }
        }
        public float FarZ
        {
            get
            {
                return mFarZ;
            }
        }
        public float Aspect
        {
            get
            {
                return mAspect;
            }
        }
        public float FovY
        {
            get
            {
                return mFovY;
            }
        }
        public float FovX
        {
            get
            {
                float halfWidth = 0.5f * NearWindowWidth;
                return 2.0f * Convert.ToSingle(Math.Atan(halfWidth / mNearZ));
            }
        }
        public float NearWindowWidth
        {
            get
            {
                return mAspect * mNearWindowHeight;
            }
        }
        public float NearWindowHeight
        {
            get
            {
                return mNearWindowHeight;
            }
        }
        public float FarWindowWidth
        {
            get
            {
                return mAspect * mFarWindowHeight;
            }
        }
        public float FarWindowHeight
        {
            get
            {
                return mFarWindowHeight;
            }
        }

        /// <summary>
        /// Set frustum.
        /// </summary>
        /// <param name="fovY"></param>
        /// <param name="aspect"></param>
        /// <param name="zn"></param>
        /// <param name="zf"></param>
        public void SetLens(float fovY, float aspect, float zn, float zf)
        {
            // cache properties
            mFovY = fovY;
            mAspect = aspect;
            mNearZ = zn;
            mFarZ = zf;

            mNearWindowHeight = 2.0f * mNearZ * Convert.ToSingle(Math.Tan(0.5f * mFovY));
            mFarWindowHeight = 2.0f * mFarZ * Convert.ToSingle(Math.Tan(0.5f * mFovY));

            mProj = Matrix.PerspectiveFovLH(mFovY, mAspect, mNearZ, mFarZ);
        }

        //       // Define camera space via LookAt parameters.
        public void LookAt(Vector4 pos, Vector4 target, Vector4 worldUp)
        {
            Vector3 L = new Vector3(pos.X, pos.Y, pos.Z);
            Vector3 T = new Vector3(target.X, target.Y, target.Z);
            Vector3 U = new Vector3(worldUp.X, worldUp.Y, worldUp.Z);
            LookAt(L, T, U);
        }
        public void LookAt(Vector3 pos, Vector3 target, Vector3 up)
        {
            mPosition = pos;
            mLook = Vector3.Normalize(target - pos);
            mRight = Vector3.Normalize(Vector3.Cross(up, mLook));
            mUp = Vector3.Cross(mLook, mRight);
        }
        public Matrix View
        {
            get
            {
                return mView;
            }
        }
        public Matrix Proj
        {
            get
            {
                return mProj;
            }
        }
        public Matrix ViewProj
        {
            get
            {
                return View * Proj;
            }
        }
        // Strafe/Walk the camera a distance d.
        public void Strafe(float d)
        {
            // mPosition += d*mRight
            Vector4 s = new Vector4(d);

            var nPos = (s * RightXM + PositionXM);
            mPosition = new Vector3(nPos.X, nPos.Y, nPos.Z);
        }
        public void Walk(float d)
        {
            // mPosition += d*mLook
            Vector4 s = new Vector4(d);
            var nPos = (s * LookXM + PositionXM);
            mPosition = new Vector3(nPos.X, nPos.Y, nPos.Z);
        }

        // Rotate the camera.
        public void Pitch(float angle)
        {
            // Rotate up and look vector about the right vector.

            Matrix R = Matrix.RotationAxis(mRight, angle);
            mUp = Vector3.TransformNormal(mUp, R);
            mLook = Vector3.TransformNormal(mLook, R);
        }
        public void RotateY(float angle)
        {
            // Rotate the basis vectors about the world y-axis.

            Matrix R = Matrix.RotationY(angle);
            mRight = Vector3.TransformNormal(mRight, R);
            mUp = Vector3.TransformNormal(mUp, R);
            mLook = Vector3.TransformNormal(mLook, R);
        }

        // After modifying camera position/orientation, call to rebuild the view matrix.
        public void UpdateViewMatrix()
        {
            var R = mRight;
            var U = mUp;
            var L = mLook;
            var P = mPosition;

            // Keep camera's axes orthogonal to each other and of unit length.
            L = Vector3.Normalize(L);
            U = Vector3.Normalize(Vector3.Cross(mLook, mRight));

            // U, L already ortho-normal, so no need to normalize cross product.
            R = Vector3.Cross(U, L);

            // Fill in the view matrix entries.
            float x = -Vector3.Dot(P, R);
            float y = -Vector3.Dot(P, U);
            float z = -Vector3.Dot(P, L);

            mRight = R;
            mUp = U;
            mLook = L;

            mView.Column1 = new Vector4(mRight, x);
            mView.Column2 = new Vector4(mUp, y);
            mView.Column3 = new Vector4(mLook, z);
            mView.Column4 = Vector4.UnitW;
        }


        private Vector3 mPosition;

        private Vector3 mRight;

        private Vector3 mUp;

        private Vector3 mLook;


        // Cache frustum properties.
        float mNearZ;
        float mFarZ;
        float mAspect;
        float mFovY;
        float mNearWindowHeight;
        float mFarWindowHeight;

        Matrix mView;
        Matrix mProj;

    }
}

 

管理者不需要懂业务?

我觉得问题分成两个比较好,招聘一个管理者是否需要他有相关的背景或者业务知识;一个称职的管理者是否需要精通业务。

第一个问题是否定的,虽然相关的行业,相同的职能,是肯定极大的加分项,但是没有相关的背景也不应该是否定项。毕竟作为管理者,更多的还是考虑到软技能和个人能力,而不是背景。当然想找救火队员的不算。

第二个问题,我觉得是肯定的,作为管理者,必须要做决策,也要为决策的失误承担责任,如果不能了解具体的业务,只是凭经验去判断,风险是极大的。但是也出现了很多基本不懂业务,也极成功的例子,我觉得问题在于,即使本人不懂,也需要一个非常懂业务的参谋,然后得到他的信任,然后相信他的建议,作出合适的决策。