精华内容
下载资源
问答
  • 论敏捷开发的优缺点

    万次阅读 2017-06-20 14:39:52
    近期试用了一下华为最新推出项目管理工具-华为软件开发云,接触了敏捷开发,产生一些想法。以下是使用体验,仅供同行们参考。 一、敏捷开发技术几个特点和优势: 1.个体和交互胜过过程和工具 2....

    踏入软件开发行列时间不算短了,也使用过很多项目管理软件和方法,但是在使用过程中多多少少都会遇到一些问题吧,同行们或多或少也会有相应的体验。近期试用了一下华为最新推出的项目管理工具-华为软件开发云,接触了敏捷开发,产生一些想法。以下是使用体验,仅供同行们参考。

    一、敏捷开发技术的几个特点和优势:

    1.个体和交互胜过过程和工具

    2.可以工作的软件胜过面面俱到的文档

    3.客户合作胜过合同谈判

    4.响应变化胜过遵循计划

    二、敏捷开发技术的12个原则:

    1.我们最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意。

    2.即使到了开发的后期,也欢迎改变需求。

    3.经常性地交付可以工作的软件,交付的间隔可以从几周到几个月,交付的时间间隔越短越好。

    4.在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。

    5.围绕被激励起来的个人来构建项目。

    6.在团队内部,最具有效果并且富有效率的传递信息的方法,就是面对面的交谈。

    7.工作的软件是首要的进度度量标准。

    8.敏捷过程提倡可持续的开发速度。

    9.不断地关注优秀的技能和好的设计会增强敏捷能力。

    10.简单使未完成的工作最大化。

    11.最好的构架、需求和设计出自于自组织的团队。

    12.每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。

    三、敏捷开发技术的适用范围

    1.项目团队的人数不能太多

    2.项目经常发生变更

    3.高风险的项目实施

    4.开发人员可以参与决策

    根据以上三点,大体可以总结出:

    优势:

    敏捷确实是项目进入实质开发迭代阶段,用户很快可以看到一个基线架构版的产品。敏捷注重市场快速反应能力,也即具体应对能力,客户前期满意度高。

    劣势:

    但敏捷注重人员的沟通,忽略文档的重要性,若项目人员流动大太,又给维护带来不少难度,特别项目存在新手比较多时,老员工比较累。

    需要项目中存在经验较强的人,要不大项目中容易遇到瓶颈问题。

    结合华为软件开发云,他们提供了两种项目创建方法:Scrum和Scrum精简,可以结合自己的不同习惯,选择合适自己团队的方法,这点还是不错的。


    同时,华为软件开发云,在文档和百科管理上,也增加了自己的特色,有效避免传统敏捷开发的劣势。大家不妨试用一下,后续有什么建议和想法,欢迎一起探讨。

    展开全文
  • 近期试用了一下华为最新推出项目管理工具-华为软件开发云,接触了敏捷开发,产生一些想法。以下是使用体验,仅供同行们参考。一、敏捷开发技术几个特点和优势:1.个体和交互胜过过程和工具2.可以工作软件...

    踏入软件开发行列时间不算短了,也使用过很多项目管理软件和方法,但是在使用过程中多多少少都会遇到一些问题吧,同行们或多或少也会有相应的体验。近期试用了一下华为最新推出的项目管理工具-华为软件开发云,接触了敏捷开发,产生一些想法。以下是使用体验,仅供同行们参考。

    一、敏捷开发技术的几个特点和优势:

    1.个体和交互胜过过程和工具

    2.可以工作的软件胜过面面俱到的文档

    3.客户合作胜过合同谈判

    4.响应变化胜过遵循计划

    二、敏捷开发技术的12个原则:

    1.我们最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意。

    2.即使到了开发的后期,也欢迎改变需求。

    3.经常性地交付可以工作的软件,交付的间隔可以从几周到几个月,交付的时间间隔越短越好。

    4.在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。

    5.围绕被激励起来的个人来构建项目。

    6.在团队内部,最具有效果并且富有效率的传递信息的方法,就是面对面的交谈。

    7.工作的软件是首要的进度度量标准。

    8.敏捷过程提倡可持续的开发速度。

    9.不断地关注优秀的技能和好的设计会增强敏捷能力。

    10.简单使未完成的工作最大化。

    11.最好的构架、需求和设计出自于自组织的团队。

    12.每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。

    三、敏捷开发技术的适用范围

    1.项目团队的人数不能太多

    2.项目经常发生变更

    3.高风险的项目实施

    4.开发人员可以参与决策

    根据以上三点,大体可以总结出:

    优势:

    敏捷确实是项目进入实质开发迭代阶段,用户很快可以看到一个基线架构版的产品。敏捷注重市场快速反应能力,也即具体应对能力,客户前期满意度高。

    劣势:

    但敏捷注重人员的沟通,忽略文档的重要性,若项目人员流动大太,又给维护带来不少难度,特别项目存在新手比较多时,老员工比较累。

    需要项目中存在经验较强的人,要不大项目中容易遇到瓶颈问题。

    结合华为软件开发云,他们提供了两种项目创建方法:Scrum和Scrum精简,可以结合自己的不同习惯,选择合适自己团队的方法,这点还是不错的。

    同时,华为软件开发云,在文档和百科管理上,也增加了自己的特色,有效避免传统敏捷开发的劣势。大家不妨试用一下,后续有什么建议和想法,欢迎一起探讨。

    展开全文
  • 华为liteos内存管理源码以及架构分析 ...liteos内存分配策略的优缺点 liteos内存分配代码在平时工作中帮助解决bug华为liteos内存管理源码以及架构分析本文主要从源码层面讲解华为针对物联网的一个小型操作系统liteos的

    华为liteos内存管理源码以及架构分析

    本文主要从源码层面讲解华为针对物联网的一个小型操作系统liteos的内存管理方式:

    • liteos内存管理概要
    • liteos内存管理结构图
    • liteos内存管理源码los_memory.c源码分析
    • liteos内存分配策略的优缺点
    • liteos内存分配代码,在平时工作中帮助解决bug

    liteos内存管理概要

    一般对于操作系统来说,主要有几个必要核心的基础模块,内存管理,任务调度,任务之间的通信和互斥。这几个是一个操作系统最核心的模块其次比较重要的就是文件系统,网络协议栈等一些比较重要的模块,再下来就是操作系统根据各种类型的设备定义的一些驱动的框架,比如字符设备,块设备,等各种类型的设备的管理框架,再具体下来就是具体的设备驱动程序这些是和具体的设备相关的。内存管理应该属于操作系统最基础的模块了,因为其他的模块基本都会使用该模块的接口去分配和释放内存。liteos也不例外,所以本文主要讲解liteos的内存管理。

    牵扯到的主要数据结构

    主要数据结构如下,后面再从代码层面依次详细讲解:

    typedef struct
    {
        VOID *pPoolAddr;/*内存池起始地址*/
        UINT32 uwPoolSize;     /**<内存池大小*/
    } LOS_MEM_POOL_INFO;

    LOS_MEM_POOL_INFO该结构体是内存池的起始地址和内存池的大小,位于内存池的开头,后面会有结构图。

    typedef struct tagLOS_MEM_DYN_NODE
    {
        LOS_DL_LIST stFreeNodeInfo; /**<没有使用的内存节点链表*/
        struct tagLOS_MEM_DYN_NODE *pstPreNode; /*前一个内存节点*/
        UINT32 uwSizeAndFlag; /*当前节点的管理内存的大小,最高位表示内存是否已经被分配*/
    }LOS_MEM_DYN_NODE;

    LOS_MEM_DYN_NODE该结构体内存管理的基本单元,每分配一次内存就是在找大小合适的节点,没有使用的内存也是通过这样的node一个个组织起来的。

    typedef struct LOS_DL_LIST
    {
        struct LOS_DL_LIST *pstPrev; /*指向链表的前一个节点*/
        struct LOS_DL_LIST *pstNext; /*指向链表的后一个节点*/
    } LOS_DL_LIST;

    LOS_DL_LIST这个是一个双向链表,用来阻止没有使用的内存。

    typedef struct
    {
        LOS_DL_LIST stListHead[OS_MULTI_DLNK_NUM];//链表数组
    } LOS_MULTIPLE_DLNK_HEAD;

    注意: LOS_MULTIPLE_DLNK_HEAD该结构体是内存管理模块一个比较重要的结构体,该数组中的每一个元素都是一个链表,主要用来管理没有使用的内存,并且按照2的幂次方大小范围管理,每次分配的内存的是否都是找到该数组中合适的链表,然后找到链表中合适的元素。

    liteos内存管理结构图

    这里写图片描述

    上次中的第一行是整个内存池结构,第二行和第三行分别对应第一行蓝色线放大对应的具体结构,笔直的红色线代表sFreeNodeInfo是数组中某一个链表的一个node,用来管理没有使用的内存,具体是那个元素我们在后面的代码中具体分析。

    红色笔话的线以及标记的uwSizeAndFlag表示箭头对应的长度,注意这个flag中最高位表示该节点是否使用,liteos就是使用这样的节点表示一个内存块。然后再list数组中管理没有使用的内存。

    liteos内存管理源码los_memory.c源码分析

    内存池的初始化

    UINT32 LOS_MemInit(VOID *pPool, UINT32  uwSize)
    {
        LOS_MEM_DYN_NODE *pstNewNode = (LOS_MEM_DYN_NODE *)NULL;
        LOS_MEM_DYN_NODE *pstEndNode = (LOS_MEM_DYN_NODE *)NULL;
        LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)NULL;
        UINTPTR uvIntSave;
        LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL;
    
        if ((pPool == NULL) || (uwSize < (OS_MEM_MIN_POOL_SIZE)))
        {
            return OS_ERROR;
        }
    
    
        pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool;
        pstPoolInfo->pPoolAddr = pPool;//pool的起始地址就是内存数组的起始地址
        pstPoolInfo->uwPoolSize = uwSize;//pool的大小就是内存数组的大小
        LOS_DLnkInitMultiHead(OS_MEM_HEAD_ADDR(pPool));//内存地址除去poolinfo开始DLINK_HEAD地址,也就是list数组的起始地址
        pstNewNode = OS_MEM_FIRST_NODE(pPool);//除去poolinfo 和DLINK_HEAD的list数组开始第一个node
        //大小除去第info和list数组和第一个node剩下的大小
        pstNewNode->uwSizeAndFlag = ((uwSize - ((UINT32)pstNewNode - (UINT32)pPool)) - OS_MEM_NODE_HEAD_SIZE);
        pstNewNode->pstPreNode = (LOS_MEM_DYN_NODE *)NULL;
        pstListHead = OS_MEM_HEAD(pPool, pstNewNode->uwSizeAndFlag);//找出list中的第log(size)-4个节点,这里是数学中的对数
        if (NULL == pstListHead)
        {
            printf("%s %d\n", __FUNCTION__, __LINE__);
            return OS_ERROR;
        }
    
        LOS_ListTailInsert(pstListHead,&(pstNewNode->stFreeNodeInfo));
        pstEndNode = (LOS_MEM_DYN_NODE *)OS_MEM_END_NODE(pPool, uwSize);//最后一个node
        (VOID)memset(pstEndNode, 0 ,sizeof(*pstEndNode));
        pstEndNode->pstPreNode = pstNewNode;
        pstEndNode->uwSizeAndFlag = OS_MEM_NODE_HEAD_SIZE;
        OS_MEM_NODE_SET_USED_FLAG(pstEndNode->uwSizeAndFlag);//标记为已经使用,这个可以防止越界,后面会用到。
        osMemSetMagicNumAndTaskid(pstEndNode);
    
        return LOS_OK;
    }

    该函数的参数可以看成是一个数组的其实地址和数组的大小,事实上liteos中这两个参数确实是一个数组,该数组就是被管理的内存池。其实上面的那个图的第一行就是表示这个数组,元素的关系就是图上的关系。主要做了一下几个重要操作
    1,分配和初始化pstPoolInfo
    2,数组开头跳过pstPoolInfo的大小分配和初始化链表数组,
    3,跳过pstPoolInfo和链表数组开始的是第一个内存管理节点pstNewNode
    4,在链表数组中找到合适的位置将pstNewNode插入链表。
    5,数组的末尾也是一个内存管理节点pstEndNode,所以可以分配的初始
    化好之后,可以分配的内存就位于pstNewNode和pstEndNode之间。
    上面五个步骤第三步是很关键的,下面详细详解。
    第三步首先调用OS_MEM_HEAD这个宏定义函数,在list数组中找到合适的链表,然后将pstNewNode插入链表。

    宏定义依次为:

    #define OS_MEM_HEAD(pPool, uwSize) OS_DLnkHead(OS_MEM_HEAD_ADDR(pPool), uwSize)
    
    //在内存池数组开头跳过LOS_MEM_POOL_INFO得到list数组结构体的地址
    #define OS_MEM_HEAD_ADDR(pPool) ((VOID *)((UINT32)(pPool) + sizeof(LOS_MEM_POOL_INFO)))
    
    #define OS_DLnkHead                         LOS_DLnkMultiHead
    
    
    LOS_DL_LIST *LOS_DLnkMultiHead(VOID *pHeadAddr, UINT32 uwSize)
    {
        LOS_MULTIPLE_DLNK_HEAD *head = (LOS_MULTIPLE_DLNK_HEAD *)pHeadAddr;
        UINT32 idx =  LOS_Log2(uwSize);//这里就不再贴代码里,这里只要求uSize的二进制表示法最高为1的为在第几位,如LOS_Log2(1024)=10,LOS_Log2(2047)=10
        if(idx > OS_MAX_MULTI_DLNK_LOG2)
        {
            return (LOS_DL_LIST *)NULL;
        }
    
        if(idx <= OS_MIN_MULTI_DLNK_LOG2)
        {
            idx = OS_MIN_MULTI_DLNK_LOG2;
        }
        //链表数组的第几个元素
        return head->stListHead + (idx - OS_MIN_MULTI_DLNK_LOG2);
    }

    上面这个函数中的LOS_Log2()是一个数学中的以2为底的对数函数,只不过下取整如:
    LOS_Log2(1024)结果为10,LOS_Log2(2047)也为10,但是LOS_Log2(2048)就是11,所以该函数也就是求解uwSize的二进制表示方式中1的最高位。
    所以也不难理解LOS_DLnkMultiHead函数就是在list数组中根据uwSize的大小找到一个合适的list,所以该list数组是按照2的指数倍一次组织内存的。所有没有使用的内存都使用该list数组来组织。
    求出合适的位置也就是找到了list之后,将pstNewNode插入list中,也就是
    LOS_ListTailInsert(pstListHead,&(pstNewNode->stFreeNodeInfo));这句代码。
    这样内存池的初始化基本就完成了。后面就可以分配内存使用了。其实就是在内存数组中找到合适的内存节点,

    内存分配

    VOID *LOS_MemAlloc (VOID *pPool, UINT32  uwSize)
    {
        VOID *pPtr = NULL;
        do
        {
            if ((pPool == NULL) || (uwSize == 0))
            {
                break;
            }
            //判断如果uwSize的最最高位为1直接跳出返回
            if (OS_MEM_NODE_GET_USED_FLAG(uwSize))
            {
                break;
            }
            //实际在内存池分配内存
            pPtr = osMemAllocWithCheck(pPool, uwSize);
        } while (0);
    
        return pPtr;
    }
    
    static inline VOID *osMemAllocWithCheck(VOID *pPool, UINT32  uwSize)
    {
        LOS_MEM_DYN_NODE *pstAllocNode = (LOS_MEM_DYN_NODE *)NULL;
        UINT32 uwAllocSize;
        //因为liteos是使用node节点管理内存的所以这一需要添加node结构体长度,然后四字节对齐。
        uwAllocSize = OS_MEM_ALIGN(uwSize + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE);
         //我们在上面说过没有使用的内存都在list数组中按照内存的大小以2的指数级插入链表管理的。
        pstAllocNode = osMemFindSuitableFreeBlock(pPool, uwAllocSize);
        if (pstAllocNode == NULL)
        {
            printf("[%s] No suitable free block, require free node size: 0x%x\n", __FUNCTION__, uwAllocSize);
            return NULL;
        }
        //如果找到的节点分配之后还可以分出一个节点,那么就将该节点分出来
        if ((uwAllocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= pstAllocNode->uwSizeAndFlag)
        {
            osMemSpitNode(pPool, pstAllocNode, uwAllocSize);
        }
        //从链表中删除该节点
        LOS_ListDelete(&(pstAllocNode->stFreeNodeInfo));
        osMemSetMagicNumAndTaskid(pstAllocNode);
        OS_MEM_NODE_SET_USED_FLAG(pstAllocNode->uwSizeAndFlag);
        OS_MEM_ADD_USED(OS_MEM_NODE_GET_SIZE(pstAllocNode->uwSizeAndFlag));
        //返回给用户的是用户可以使用的内存,所以这里需要跳过node
        return (pstAllocNode + 1);
    }

    上面关键的一个

    注意: osMemFindSuitableFreeBlock该函数是遍历我们的list数组找到根据大小找到合适的节点,正如前面所说,所有没有使用的内存都在该数组链表里面保存着。
    找到之后如果找到的节点还足够分出一个节点那么就将该节点分出来将剩下的分出来的节点挂入list数组

    分节点函数

    static inline VOID osMemSpitNode(VOID *pPool,
                                LOS_MEM_DYN_NODE *pstAllocNode, UINT32 uwAllocSize)
    {
        LOS_MEM_DYN_NODE *pstNewFreeNode = (LOS_MEM_DYN_NODE *)NULL;
        LOS_MEM_DYN_NODE *pstNextNode = (LOS_MEM_DYN_NODE *)NULL;
        LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL;
        //分出新的节点
        pstNewFreeNode = (LOS_MEM_DYN_NODE *)((UINT8 *)pstAllocNode + uwAllocSize);
        pstNewFreeNode->pstPreNode = pstAllocNode;
        pstNewFreeNode->uwSizeAndFlag = pstAllocNode->uwSizeAndFlag - uwAllocSize;
        pstAllocNode->uwSizeAndFlag = uwAllocSize;
        //新节点的下一个节点
        pstNextNode = OS_MEM_NEXT_NODE(pstNewFreeNode);
        pstNextNode->pstPreNode = pstNewFreeNode;
        /*判断新节点的下一个节点是否使用,如果没有使用那么将新节点和下一个节点合并,这也就是为什么在初始化的时候最后一个节点要标记为已经使用,还有就是我们可能多次的分配释放,所以下一个节点有可能是没有使用的,所以这里要添加判断*/
        if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag))
        {
            LOS_ListDelete(&(pstNextNode->stFreeNodeInfo));
            osMemMergeNode(pstNextNode);
        }
        //根据大小在list数组中找到合适的list
        pstListHead = OS_MEM_HEAD(pPool, pstNewFreeNode->uwSizeAndFlag);
        if (NULL == pstListHead)
        {
            printf("%s %d\n", __FUNCTION__, __LINE__);
            return;
        }
        //将分出来的节点加入list
        LOS_ListAdd(pstListHead,&(pstNewFreeNode->stFreeNodeInfo));
    }
    

    以上就是内存的分配,当分配内存是首先从list数组中找到合适的node节点,如果该node节点管理的内存大于需要分配的内存,并且可以再分出一个节点,那么就将找到的节点分割,一部分是返回给分配的用户,一部分是没有使用的,然后看看这个没有使用的节点的下一个节点是否使用,如果没有那么将该节点和下一个节点合并,然后插入list数组,如果易已经使用,那么直接插入list数组。

    最后就是跳过分配的节点结构体返回用户可以使用的内存起始地址

    内存释放

    UINT32 LOS_MemFree(VOID *pPool, VOID *pMem)
    {
        UINT32 uwRet = LOS_NOK;
        UINT32 uwGapSize = 0;
        do
        {
            LOS_MEM_DYN_NODE *pstNode = (LOS_MEM_DYN_NODE *)NULL;
            if ((pPool == NULL) || (pMem == NULL))
            {
                break;
            }
            //字节对齐处理,由于有字节对齐分配,我们没有这里就不分析了
            uwGapSize = *((UINT32 *)((UINT32)pMem - 4));
            if (OS_MEM_NODE_GET_ALIGNED_FLAG(uwGapSize))
            {
                uwGapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(uwGapSize);
                pMem = (VOID *)((UINT32)pMem - uwGapSize);
            }
            //由于返回给用户的是用户可以使用的,还记得刚才说的跳过node吗,所以这里需要调整,找到node
            pstNode = (LOS_MEM_DYN_NODE *)((UINT32)pMem - OS_MEM_NODE_HEAD_SIZE);
            //检查node使用使用
            uwRet = osMemCheckUsedNode(pPool, pstNode);
            if (uwRet == LOS_OK)
            {
                osMemFreeNode(pstNode, pPool);
            }
        } while(0);
        return uwRet;
    }
    
    
    //释放函数
    
    static inline VOID osMemFreeNode(LOS_MEM_DYN_NODE *pstNode, VOID *pPool)
    {
        LOS_MEM_DYN_NODE *pstNextNode = (LOS_MEM_DYN_NODE *)NULL;
        LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL;
    
        OS_MEM_REDUCE_USED(OS_MEM_NODE_GET_SIZE(pstNode->uwSizeAndFlag));
        pstNode->uwSizeAndFlag = OS_MEM_NODE_GET_SIZE(pstNode->uwSizeAndFlag);
        //如果node的前一个节点不为空,且前一个节点没有使用,那么
        if ((pstNode->pstPreNode != NULL) &&
            (!OS_MEM_NODE_GET_USED_FLAG(pstNode->pstPreNode->uwSizeAndFlag)))
        {
            LOS_MEM_DYN_NODE *pstPreNode = pstNode->pstPreNode;
            //和前一个节点合并
            osMemMergeNode(pstNode);
            pstNextNode = OS_MEM_NEXT_NODE(pstPreNode);
            //后一个节点也没有使用,那么也和后一个节点合并,
            /*也就是说如果需要释放的节点位于两个都内有使用的节点之间那么前后都合并,防止内存碎片*/
            if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag))
            {
                LOS_ListDelete(&(pstNextNode->stFreeNodeInfo));
                osMemMergeNode(pstNextNode);
            }
    
            LOS_ListDelete(&(pstPreNode->stFreeNodeInfo));
            pstListHead = OS_MEM_HEAD(pPool, pstPreNode->uwSizeAndFlag);
            if (NULL == pstListHead)
            {
                printf("%s %d\n", __FUNCTION__, __LINE__);
                return;
            }
    
            LOS_ListAdd(pstListHead,&(pstPreNode->stFreeNodeInfo));
        }
        else
        {
            pstNextNode = OS_MEM_NEXT_NODE(pstNode);
            //如果下一个节点没有使用,和下一个节点合并
            if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag))
            {
                LOS_ListDelete(&(pstNextNode->stFreeNodeInfo));
                osMemMergeNode(pstNextNode);
            }
            //按照新节点的大小在list数组中找到合适的位置
            pstListHead = OS_MEM_HEAD(pPool, pstNode->uwSizeAndFlag);
            if (NULL == pstListHead)
            {
                printf("%s %d\n", __FUNCTION__, __LINE__);
                return;
            }
            将释放的内存和合并之后的生成的新节点插入合适的list
            LOS_ListAdd(pstListHead,&(pstNode->stFreeNodeInfo));
        }
    }
    

    这个函数就不详细分析了,不是很难,还有我也写累了。。。
    主要就是内存回收以及合并内存节点防止内存过于颗粒化出现大量碎片。

    liteos内存分配策略的优缺点

    liteos内存分配策略优点是简单,使用链表数组按照2的幂次方级数关系管理内存,缺点也很明显,容易出现内存碎片,举例如下:

    如果使用者每次都是分配–>释放—>分配—>释放,那么这样的方式是不会产生内存碎片的,但是如果按照分配—>分配—>释放—>释放。。。,这样不是交替的方式的话那么极容易产生内存碎片,即使没有使用的内存足够,但是如果没有使用的内存过于分散,那么用户分配还是会失败。

    liteos内存分配代码,在平时工作中帮助解决bug

    我们可以看到liteos的内存分配单吗相对简单,还是比较容易看懂的,所以我们自己的代码中也经常使用malloc等函数分配内存,有时候会忘记释放,或者其他的问题,引起系统出问题,这个时候,也许我们能使用liteos的LOS_MemAlloc替换掉我们的malloc这样很容易方便的定位为题。

    展开全文
  • 往期文章: 华为软件开发云测评报告一:项目管理 华为软件开发云测评报告二:代码...了解华为软件开发云测试管理服务功能,分析其优缺点; 自动化测试工具未来发展趋势; 产品简介 产品名称:华为软件开...

    往期文章:

    华为软件开发云测评报告一:项目管理

    华为软件开发云测评报告二:代码检查

    体验环境

    体验方式:PC端

    系统:Windows 64位

    浏览器类型:Chrome浏览器 

    浏览器版本:58.0.3029.110

    体验时间:2017.07.06

    分析目的

    了解华为软件开发云的测试管理服务功能,分析其优缺点;

    自动化测试工具未来的发展趋势;

    产品简介

    产品名称华为软件开发云

    定位:华为软件开发云(DevCloud)是集华为研发实践、前沿研发理念、先进研发工具为一体的研发云平台,面向开发者提供研发工具服务,让软件开发简单高效。

    产品slogan:集华为近30年研发精华开发神器;

    产品关键字:(从各服务网页源码中提取)项目管理服务,云端项目管理,项目外包协作、配置管理,代码托管服务,跨地域协同开发、代码检查服务,代码质量管控,多语言代码检查、编译构建,开发编译构建,混合语言构建平台、部署管理_软件开发云_华为企业云、测试管理服务,测试解决方案,产品用例设计,测试活动管理、发布管理服务,软件仓库,软件快速发布、流水线_软件开发云_华为企业云

    用户构成

    华为软件开发云为to B 平台,主要面向具有开发业务的技术团队、组织或个人。

    用户画像

    解经理是某IT公司的一枚测试部门主管,由于公司迭代周期快,测试管理流程低效、测试用例多且复杂,不好管理和控制,同时移动兼容性测试需要大量的安卓真机,安卓平台设备众多,版本各异,分辨率不统一,给测试造成巨大困难的同时,也加重了公司的运营成本;解经理目前急需一款能够提供全流程测试管理和移动兼容性的工具,来提升测试效率,降低测试成本。

    功能分析

    1、测试服务全局概览:目前软件开发云测试服务主要分为两大功能,一个是基于用例和需求的测试管理流程,另外一个重要的部分是移动端APP测试;

    测试管理:

     

    移动APP测试界面:

     

    2、测试管理:由于软件开发云是一款全流程的Devops平台,所以在项目管理中建立的Story需求可以直接在测试管理中的追溯试图中找到,以保证需求的编码和测试用例设计同时进行;

     

     

    3、用例设计:针对已经建立好的需求,创建用例,指派处理人新增测试操作,指明测试用例的测试步骤和预期结果;

     

    4、针对设计并分配好的测试用例,进行用例执行和结果设置,如果测试失败,则可以直接创建缺陷,关联相关负责人,进行缺陷修复;

     

    5、设计与验收:可以查看在设计中、测试中、已完成的用例,同时测试的验收报告也直观的展现本次迭代中的需求完成率、用例通过率、缺陷总数等信息;管理人员可以将报告以邮件的形式发送给组内成员,或者导出excel报表;

     

     

    6、移动app测试:目前支持遍历测试(安装、启动、登陆、遍历、卸载等)和性能采集测试,可以从软件开发云编译构建好的发布仓库中选择应用程序或者在本地导入apk包;

     

    7、机型支持情况:目前app测试支持的机型只有四款安卓机器(估计是由于公测阶段的原因,只推出了四款机型,后续支持的机型应该会逐步增多)

     

    8、兼容性测试报告:兼容性测试的内容、全面性和精确性需要非常重要,下图是测试结果:

     

    测试截屏:

     

    性能详情:

     

    日志:

     

    优劣分析

    优势:

    1、提供了一整套完善的自动化用例管理的流程,免去了复杂的人工维护及分配操作;

    2、基于华为软件开发云平台可以更好的把需求管理和测试管理结合起来,进行用例和需求的绑定;

    3、在用例测试时可以快速创建缺陷;

    4、直观的验收报告方便管理者对测试整体情况进行掌控;

    5、移动APP测试的分析报告详细直观,每一步的测试操作均有截屏显示,方便测试人员定位错误;

    劣势:

    1、目前移动端测试支持的安卓手机、平板型号和安卓版本较少,建议尽快增加其他型号的手机和系统版本;

    2、移动端测试目前速度较慢,测试一款手机一个安卓版本的时间大概需要15分钟左右,建议后台尽快扩容,减少用户等待时间,以获取最佳的体验;

    自动化测试工具的发展趋势分析

    1、移动测试

    由于移动设备和技术不断推陈出新,移动测试领域仍然是测试趋势的重中之重。移动应用软件对软件测试行业将产生重要的影响,主要包括有功能、性能、兼容性、安全性和易用性等方面的测试。专家们预测,如果移动市场以现有速度的继续发展,那么基于移动的自动化测试迟早会超越网站自动化测试,这只是个时间的问题。由于开源框架、移动DevOps和APP市场的不断增长,这为移动自动化测试开辟了一个很广阔的前景。

     2、API和微服务测试

      因为微服务可以在不改变其他应用程序和流程情况下进行测试,它更容易被测试和部署一个独立的功能,这使得应用软件和产品可以加快上线速度。因为它可以用于测试包含许多小的、独立流程和体系结构的而构成的复杂应用程序,所以这个趋势必然在2017年将持续升温。另一方面,为了对应用程序进行全面测试,测试应用程序与其他应用程序之间的依赖关系的接口测试也将是企业的最高要求之一。

    3、Web服务和SOA的测试自动化

      与API和微服务测试一样,Web服务和SOA体系结构的测试作为对应用程序的端到端进行性能测试也将同等重要。现在复杂应用系统的集成,要求测试系统之间消息是否能正确传输和响应,因此,将有越来越多的企业投资于SOA和Web服务的自动化测试。

    4、生命周期测试全自动化

      接口测试、Web服务测试和大数据测试将成为重要的测试发展趋势,可见今年测试自动化将不会仅仅局限在功能测试方面。企业将会开发“端到端的、全生命周期测试的自动化”,要求贯穿整个软件生命周期测试的单元测试、集成测试或系统测试的任何一部分都可以实现自动化。这种趋势肯定会给测试人员提供很多机会,从开始到结束的整个测试生命周期的所有自动化测试技术,而不再仅仅是功能测试的自动化技术。

     

    转载于:https://www.cnblogs.com/goldenfish/p/7158646.html

    展开全文
  • 了解华为软件开发云项目管理服务功能,分析其优缺点; 瀑布化开发到敏捷开发转型分析,以及未来软件开发模式发展方向; 产品简介 产品名称:华为软件开发云 定位:软件开发云(DevCloud)是集华为研...
  • 看看人家华为的项目组成员表是怎么做,跟你们公司比较,有哪些优缺点
  • 客户运行在其他云平台(比如阿里云)应用系统,如何搬迁到华为云,如何评估搬迁可行性和工作量,具体方案是什么以及有什么优缺点。 针对客户担心“如何避免被云厂商”绑定顾虑,客户应该如何选择更好技术...
  • ·客户运行在其他云平台(比如阿里云)应用系统,如何搬迁到华为云,如何评估搬迁可行性和工作量,具体方案是什么以及有什么优缺点。 ·针对客户担心“如何避免被云厂商”绑定顾虑,客户应该如何选择更好...
  • 相关文章:《华为软件开发云测评报告一:项目管理》 体验环境 ...了解华为软件开发云代码检查服务功能,分析其优缺点; 从人工代码检视到自动化代码检查,华为软件开发云如何保证代码质量;
  • 本文主要尝试回答两个问题:· 客户运行在其他云平台(比如阿里云)应用系统,如何搬迁到华为云,如何评估搬迁可行性和工作量,具体方案是什么以及有什么优缺点。· 针对客户担心“如何避免被云厂商”绑定...
  • 直接转发和隧道转发 WLAN网络中的报文分为管理报文(控制报文)和数据报文...隧道转发和直接转发存在各自的优缺点,使用时需要根据实际的需求选择配置隧道转发还是直接转发,隧道转发与直接转发的优缺点如表1-1所示:
  • 静态路由的优缺点 节省设备链路开销,运行稳定,是管理员手工配置的,是单向的,缺乏灵活性。所以,对大型网络来说,工作量较大,拓扑一旦发生改变,维护量变大,只适用于小型网络(路由条目少于十条)。 配置方法...
  • RIPOSPFIS-IS说出优缺点优点:RIP实现简单,配置容易,易于管理。OSPF适应范围广,支持大规模网络,最多可支持几百台路由器;支持掩码,对VLSM提供很好支持;快速收敛,网络拓扑结构发生变化后立即在自治系统中...
  • 文章目录华为的虚拟化平台CNAVRM虚拟化的优缺点虚拟化优点虚拟化缺点华为的私有云云管理平台IT服务化和IT自动化区别IT服务化IT自动化VDC和VPCVDCVPC云计算虚拟化和云计算使用场景FusionSphere服务器虚拟化华为云...
  • SDN相关资料 数据中心架构下ospf bgp如何选择及优缺点? - 数据中心 - 知乎组播扩展OSPF_百度百科carrier.huawei....华为发布面向用户下一代SDN网络编程语言IP 可视运维解决方案 - 华为可视运维,敏捷管理 - 华...
  • 4.4.6 你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms和G1,包括原理,流程,优缺点。 4.4.7 垃圾回收算法的实现原理。 4.4.8 当出现了内存溢出,你怎么排错。 4.4.9 JVM内存模型的相关知识了解多少,比如重...
  • SpringCloud微服务框架的优缺点 SpringCloud项目部署到k8s的流程 第十三章 SpringCloud组件介绍 服务注册与发现组件Eureka 客户端负载均衡组件Ribbon 服务网关Zuul 熔断器Hystrix API网关SpringCloud Gateway ...

空空如也

空空如也

1 2
收藏数 34
精华内容 13
关键字:

华为管理的优缺点