【今天,你总结了吗?】

  

  毕业后工作也快有两个月,试用期期间也没有太大的压力,工作日正常上班,平时住在公司,晚上加点班,整理整理学习到的知识。上班的感觉还不错,毕竟也有能力养活自己,比在学校的时候状态要好些,更容易约束自己。这里是不是也潜伏着很多Dotaer呢,毕业了,对DOTA的热情慢慢的淡下来了。咱还是安心的工作吧。

 学校

  在学校的时候主要跟着导师学习嵌入式方面的一些知识,参与割草机项目的开发,每学期领着导师发的微薄的“工资”,两年半的时间很快,现在想想还是比较肤浅的,范围不是很广泛,使用C语言完成一些简单的功能,也不会考虑深层次方面的东西,例如:代码的优化上,内存的分配,代码的健壮性等。

 公司

  进入进公司后,我被分配到了传感器网络部门,面对新的环境,咱也不虚,虽然技术不是很扎实,但是感觉前景还是有的。既来之,则安之嘛。我的直接上司在这公司已经有6年了,有着丰富的技术经验,我的目标就是要慢慢的榨干他,当然是榨干他的知识。来了2个月,感觉他人还不错,在分配了任务之后,会经常过来问问情况,我也不好意思老是问,怕一下子一大堆简单的问题吓到他,经常看到一些老员工很反感这样的新员工,咱还是在他不在的时候问baidu吧,实在不能解决的,我就记在本子上,有关于技术方面的,有关于需求方面的。用谦虚的口吻跟老员工交流还是挺受用的。

  由于这个部门是用C++开发的,主要负责数据的通道和数据的处理转发,很多要用到面向对象的思想,类的继承等等,虽然在大学的时候学习过,但不曾有实质性的项目锻炼,那时候的时间都奉献给我的同学了。有失必有得嘛,至少还有几个玩的比较好的朋友。(在这里忽然想到句话:当你失去一些重要东西的时候,其实上天在告诉你,你已经得到了很多了。)在刚着手的时候,经常犯一些低级错误,其实,咱在毕业前好一段时间没认真的写过代码了。我觉得还是有必要记录下易错的知识点,免得以后再同一个地方在跌倒,也避免其他人走弯路。

 背景

  先扯点从项目中得来的感受吧。这个部门不是在我来才成立的,然而它的目标也很明确,就是解决数据的通道和处理,主要是网络的通信,所以在软件架构上已经有一套体系,个人感觉写的不错,很多地方都体现了C++面向对象的特点,因此最近我也恶补了一些相关知识,好在我以前学习的不多,要不然我现在还有这感悟吗?(先找个以前不好好学习的借口)。通过类的继承,能够很好的适应不同的平台,这里指Windows和Linux上的,因为想让程序在linux上运行还不是特别的方便,可以现在Windows上测试通过,再弄到Linux上测试。相关的底层函数也已经封装了七七八八,对于我这个新码农而言,只要学会如何使用它们就行了,多看看他们以前写的代码,呵呵。

 知识点

  1)面向对象特点有三:其一封装,其二继承,其三多态。

  ①  封装防止了程序相互依赖性而带来的变动影响。最直观的是,一个类要控制另一个类里的数据成员时,不能直接对其操作,要通过相应的接口完成。当设计的好时,可以保证在面向对象模型下不会存在全局数据。

  ②  继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类的行之有效的方法,它简化了对象、类的创建工作量,增加了代码的可重性。 例如在Windows和Linux中,它们对外的接口可以是一样的,只是在实现上会有所差异,相同的部分我们可以抽象出来,作为基类(父类)。而将类的细化作为子类。

  ③  多态是指两个或多个属于不同类的对象,对于同一个消息(方法调用)作出不同响应的方式。多态则是为了实现接口重用,增强了软件的灵活性和重用性。

  最近也看了博客园里很多大神的文章,也能学到一些知识,根据自己的情况,又在当当上买了三本书。

  《设计模式:可复用面向对象软件的基础》这本书好像评论还不错。毕竟写代码不是难事,关键在于能不能设计出一个好的模式,嗯,我现在就缺这个。

  《大话设计模式》,在网上搜索到一部分内容,写的很生动,容易理解,搭配着第一本看看吧。

  《大象——Thinking in UML》注重软件的分析、设计与建模过程,软件江湖盛传的“UML第一书”,开发人员梦寐以求的“九阳真经”,真正助您打通软件开发“任督二脉”。希望看了它,我的“任督二脉”也能通一下。

  好了,下面再简单的谈谈项目中常发生的错误吧。

  2)第一个就是指针,类的指针,以前接触不多,这次就吃了大亏,先是不申请内存就使用,其实这点我也注意,但是往往理解的不彻底,例如:

A *a, *b;
a=new A();
b=a;

  当你看到这个知识点时,很好理解,指针是用来指向对像的。a指向类的一个对象,而b没有用new关键字,而是直接指向a这个对象。

  其实,new跟指针没有关系。new是在堆上分配内存,作用域由开发人员确定。不new是在栈上分配内存,作用域由变量作用域确定。

  ps:指针访问前,必须指向一段有效的内存,不管是堆的还是栈的。比如你上面的代码就是指向栈的内存。

再一个需要注意的是指针的作用域,例如:

char *GetMemory( void )
{ 
 char p[] = "hello world"; 
 return p; 
}

void Test( void )
{ 
 char *str = NULL; 
 str = GetMemory(); 
 printf( str ); 
}

  其中一个错误是p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期

在项目中,刚开始我没有很好的理解生存期的意思,我就贴出一段代码来简单说明一下吧。 

/********************************************************
功能:返回没发送的任务中优先级最小的
********************************************************/
CTaskInfo* CTaskMgr::GetLowPRI()
{
    BOOL        bFind=FALSE;
    CTaskInfo*    pTaskInfo;
    for(DWORD i=0;i<MAX_TASK_COUNT && i<m_TaskCount;i++)
    {
        if(!m_TaskList[i]->HasSendFrame)
        {
            if(bFind)
            {
                if(m_TaskList[i]->PRI<pTaskInfo->PRI)
                {
                    pTaskInfo=m_TaskList[i];
                }                
            }
            else
            {
                pTaskInfo=m_TaskList[i];                 bFind=TRUE;
            }
        }
    }
    if(bFind)
    {
        return pTaskInfo;
    }
    return NULL;
}

  粗略一看,嗯?以上2个不是一回事吗?怎么第一个不行,第二个就行了呢?原来区别在于m_TaskList[i]是一个CTaskInfo*类型的模块变量,当return时,pTaskInfo指向的是一个堆,在没有用delete释放内存时是一直存在的,所以它是可以返回的。而上面的那个例子就不一样了,p是一个局部变量,在栈中,当函数执行完后,p就被回收掉了,所以返回是无效的。以前不认真思考的话还真是一知半解。

  3)由于我做的项目中涉及到了网络多通道问题,所以要灵活使用消息队列,它是解决数据共享的,相当于一个缓存,由另一个线程再处理数据。再一个需要注意的是,对于多线程,有时候要注意使用锁机制。这里就不详细说了。

 写在最后

  这次就先总结到这里吧,有的知识点不及时整理的话又要遗失在记忆的角落里拉。平时还要勤快点呢。知识是一点一点积累的,慢慢来。每天进步一点点。

 

 

你可能感兴趣的:(【今天,你总结了吗?】)