个人项目开发PSP实践-MyWCprj

MyWCprj.exe

Github仓库地址

1. What is MyWCprj.exe?

wc是linux下一个非常好用的代码统计小工具,可以通过 -c 、-w 、-l等选项分别进行对指定文件的代码字符数、词组数、行数统计。

应学校软件工程课程的PSP个人项目开发实践需要,特此尝试自己写一个用c++实现的wc(MyWCprj.exe)。

该程序仅能确保统计.c .cpp .h文件代码数的正确性。

语法

MyWCprj.exe [parameter] [fileOrDir_name1] [fileOrDir_name2] ……

功能参照

MyWCprj.exe -c file.c    //输出文件 file.c 的字符数

MyWCprj.exe -w file.c    //输出文件 file.c 的词的数目

MyWCprj.exe -l file.c    //输出文件 file.c 的行数

MyWCprj.exe -a file.c    //输出文件 file.c

MyWCprj.exe -s fileDir    //递归处理目录fileDir及其子目录中代码文件,无其他参数时仅列举目录fileDir及其子目录中代码文件(.c .cpp .h),可配合一个或多个 -c -w -l -a 一起处理。

MyWCprj.exe -l file1.c file2.c file3.c   //输出file1.c、file2.c、file3.c的行数

MyWCprj.exe -s -l DirPath1 DirPath2 DirPath3  //递归输出DirPath1、DirPath2、DirPath3目录及其子目录下所有代码文件的行数

测试示例

参考中典型的源代码文件 CommonSrcCode.cpp:

 1 #include"WChead.h"
 2
 3
 4 int main(int argc,char *argv[])
 5 {
 6     /*cout << "ar num=" << argc << endl;
 7     for (int i = 0; i < argc; i++)
 8     {
 9         cout << "No." << i << " ";
10         cout << "ar =" << argv[i] << endl;
11     }
12     system("PAUSE");*/
13
14     if (argc < 2)
15     {
16         cout << "" << endl;
17         return -1;
18     }
19
20     class_WordCal myWC;
21     myWC.workMain(argc, argv);
22
23     //system("PAUSE");
24     return 0;
25 }

测试:

# 运行环境:windows 10 pro,ver 1803,powershell
# 使用 dir 命令,可看出 I:\TmpCode 下的示例代码文件
PS ..\MyWCprj\Debug> dir I:\TmpCode
Directory: I:\TmpCode
Mode                LastWriteTime         Length Name

------
#典型的源代码文件 CommonSrcCode.cpp
-a----        9/14/2018   9:34 AM            384 CommonSrcCode.cpp
#空代码文件 EmptyCode.cpp
-a----        9/14/2018   7:29 PM              0 EmptyCode.cpp
#仅有字符‘a‘的代码文件 Onechar.cpp
-a----        9/14/2018   7:32 PM              1 Onechar.cpp
#仅有字符串“#pragma once”的代码文件 Oneline.cpp
-a----        9/14/2018   7:34 PM             12 Oneline.cpp
#仅有字符串“#define” 的代码文件 Oneword.cpp
-a----        9/14/2018   7:32 PM              7 Oneword.cpp    

# 使用 .\MyWCprj.exe -s -w -c -l -a I:\TmpCode 组合
# 可看出 MyWCprj.exe 递归输出当前目录下的代码文件对应信息
PS ..\MyWCprj\Debug> .\MyWCprj.exe -s -w -c -l -a I:\TmpCode
list_size: 5
No.0  I:\TmpCode\CommonSrcCode.cpp:
The Num of chars: 360  I:\TmpCode\CommonSrcCode.cpp
The Num of words: 45  I:\TmpCode\CommonSrcCode.cpp
The Num of Lines: 24  I:\TmpCode\CommonSrcCode.cpp
The Num of Effective lines: 8  I:\TmpCode\CommonSrcCode.cpp
The Num of Empty lines: 9  I:\TmpCode\CommonSrcCode.cpp
The Num of Comment lines: 8  I:\TmpCode\CommonSrcCode.cpp

No.1  I:\TmpCode\EmptyCode.cpp:
The Num of chars: 0  I:\TmpCode\EmptyCode.cpp
The Num of words: 0  I:\TmpCode\EmptyCode.cpp
The Num of Lines: 0  I:\TmpCode\EmptyCode.cpp
The Num of Effective lines: 0  I:\TmpCode\EmptyCode.cpp
The Num of Empty lines: 1  I:\TmpCode\EmptyCode.cpp
The Num of Comment lines: 0  I:\TmpCode\EmptyCode.cpp

No.2  I:\TmpCode\Onechar.cpp:
The Num of chars: 1  I:\TmpCode\Onechar.cpp
The Num of words: 1  I:\TmpCode\Onechar.cpp
The Num of Lines: 0  I:\TmpCode\Onechar.cpp
The Num of Effective lines: 1  I:\TmpCode\Onechar.cpp
The Num of Empty lines: 0  I:\TmpCode\Onechar.cpp
The Num of Comment lines: 0  I:\TmpCode\Onechar.cpp

No.3  I:\TmpCode\Oneline.cpp:
The Num of chars: 12  I:\TmpCode\Oneline.cpp
The Num of words: 2  I:\TmpCode\Oneline.cpp
The Num of Lines: 0  I:\TmpCode\Oneline.cpp
The Num of Effective lines: 1  I:\TmpCode\Oneline.cpp
The Num of Empty lines: 0  I:\TmpCode\Oneline.cpp
The Num of Comment lines: 0  I:\TmpCode\Oneline.cpp

No.4  I:\TmpCode\Oneword.cpp:
The Num of chars: 7  I:\TmpCode\Oneword.cpp
The Num of words: 1  I:\TmpCode\Oneword.cpp
The Num of Lines: 0  I:\TmpCode\Oneword.cpp
The Num of Effective lines: 1  I:\TmpCode\Oneword.cpp
The Num of Empty lines: 0  I:\TmpCode\Oneword.cpp
The Num of Comment lines: 0  I:\TmpCode\Oneword.cpp

2. PSP实践

PSP2.1表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 430 120
Estimate 估计这个任务需要多少时间 30 15
Development 开发 400 300
Analysis 需求分析 (包括学习新技术) 150 45
Design Spec 生成设计文档 20 40
Design Review 设计复审 (和同事审核设计文档) 20 60
Coding Standard 代码规范 (为目前的开发制定合适的规范)划 10 85
Design 具体设计 30 120
Code Review 代码复审 30 60
Test 测试(自我测试,修改代码,提交修改) 30 120
PReporting 报告 110 50
Test Report 测试报告 30 60
Size Measurement 计算工作量 20 40
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 60 70
合计 计划 430 680

3. 分析思路

由于曾经有过在linux上逆向分析二进制程序的经验,对于ltrace 、wcobjdumpptracegdb等二进制分析与调试工具有一定的了解与使用经历,所以对于wc功能也有一定的了解。

于是乎,去GNUWC命令行工具的C源码,简洁且优雅,在性能与可读性上有非常好的平衡。据其分析之,于是就以C++的方式实现了-c-w-l的功能,并初步封装入c++自定义的类class_WordCal中。

对于-a功能,要求分析出待统计代码文件的空行、注释行、有效代码行。先是与室友沟通,结果很天马行空,基于字符判断的分析模式利用代码实现很困难且可读性不佳,于是在google中查阅与编译原理、代码预处理相关的网页与资料,结果在csdn论坛中获得启发。依然是源码注释行统计.请进来看看,感谢之至!。可利用状态机的思想:

假定一开始是非注释状态,读入一个字符,如果不是/,保持非注释状态继续读入字符,
如果字符是/,读入下一个字符,如果不是*,保持非注释状态,如果是*,进入注释状态;
在注释状态,类似的读入字符,如果不是*,保持注释状态继续读入字符,
如果字符是*,读入下一个字符,如果不是/,保持注释状态,如果是/,退出注释状态进入非字符状态。

于是自己依据该思想创建了一个结构体:

1 typedef struct {
2     bool bEffective;        //有效行标识
3     bool bComm1;            //    "//"    注释行标识
4     bool bComm2;            //    "/**/"    注释行标识
5 }AllStatus;    //高级统计状态标识结构体

具体的功能思路的代码实现见Github代码有。

至于-s功能,由于对windows的文件操作不算太熟悉,于是在网上查找目录递归遍历的思路,基本上就是调用诸如_findfirst 、_findnext的库函数,逐个获取目录下的子目录或文件的路径并存之于对应的string类的vector,遇到子目录则对子目录路径进行递归遍历。如此反复,最终可获得一个关于所有子目录路径的vector<string>,和关于所有代码文件路径的vector<string>。然后根据每一个代码文件路径实现指定的分析与信息输出功能即可。难点在于如何实现递归遍历上,这对于提升编程能力与启发编程思想来说是一个很好的实践。

4. 大体设计

  1. 高级统计(-a)状态结构体AllStatus:

    1 typedef struct {
    2     bool bEffective;        //有效行标识
    3     bool bComm1;            //    "//"    注释行标识
    4     bool bComm2;            //    "/**/"    注释行标识
    5 }AllStatus;    //高级统计状态标识结构体
  2. 数据统计类 class_data:

     1 class class_Data
     2 {
     3 public:
     4     int iNumOfChar;                //存储当前文件的字符数
     5     int    iNumOfWord;                //存储当前文件的单词数
     6     int iNumOfLine;                //存储当前文件的行数
     7     int iNumOfEffectiveLine;    //存储当前文件的有效代码行数
     8     int iNumOfEmptyLine;        //存储当前文件的空行数
     9     int iNumOfCommentLine;        //存储当前文件的注释行数
    10     string strTmpRowStr;        //临时存储刚从文件读入的一行代码
    11     AllStatus allStatus;        //高级统计状态机
    12
    13     class_Data()
    14     {
    15         iNumOfChar = 0;
    16         iNumOfWord = 0;
    17         iNumOfLine = 0;
    18         iNumOfEffectiveLine = 0;
    19         iNumOfEmptyLine = 0;
    20         iNumOfCommentLine = 0;
    21         allStatus.bComm1 = false;
    22         allStatus.bComm2 = false;
    23         allStatus.bEffective = false;
    24         allStatus.bEmpty = false;
    25     }
    26
    27     ~class_Data()
    28     {
    29
    30     }
    31
    32 };
  3. 总功能类设计class_WordCal:

     1 class class_WordCal : public class_Data
     2 {
     3 public:
     4     bool bOpChar;                        //字符统计输出开关
     5     bool bOpLine;                        //行数统计输出开关
     6     bool bOpWord;                        //词组统计输出开关
     7     bool bOpRecursion;                    //递归统计开关
     8     bool bOpAll;                        //更复杂数据统计开关
     9     int iFileNameIndex;                    //存储文件名的stringVector中带操作的文件名下标
    10     ifstream tmpifs;                    //存储当前打开文件的文件读操作类
    11     vector<string> vStrFileOrDirName;    //存储当前文件名的stringVector
    12     vector<string> vStrCodeFilePath;    //存储文件或目录路径的stringVector
    13     string strFilePath;                    //存储当前文件的路径
    14
    15
    16     void Option(int argc, char *argv[]);            //功能选择函数
    17     void Display(int Index);                        //统计输出函数
    18     void StringSkip(string s, int &pos);            //当s中存在‘ ‘ ‘\t‘ ‘\n‘ ‘\r‘时,将pos置于该字符之后
    19     void myFileFind(string DirPath);                //对传入目录路径下的所有代码文件(.c .cpp .h) 录入至 vStrCodeFilePath 中
    20     void DirList(vector<string> &vStr, const string strPath);    //从strPath指定的路径中递归查找代码文件,并录入至vStrCodeFilePath中
    21
    22     int getword(FILE *fp);                            //从输入流中获取下一个词组,读取至文件结尾或异常情况出现时返回0,返回1则为其他情况
    23     Status SetIfstream(vector<string> vStr, int Index);    //设置打开文件的文件读操作类
    24     //Status CountFromFile(int Index);                //(旧代码,不兼容-s统计功能)对vStrFileOrDirName中第Index个文件名对应文件进行代码统计(-l -w -c)
    25     //Status CountFromFileAll(int Index);            //(旧代码,不兼容-s统计功能)对vStrFileOrDirName中第Index个文件名对应文件进行高级代码统计(-a)
    26
    27     Status CountFromDir(int Index);                    //对vector<string>中第Index个目录下的所有代码文件进行递归统计(-s)
    28     Status CountFromFile(vector<string> vStr, int Index);//对vector<string>中第Index个文件名对应文件进行代码统计(-l -w -c)
    29     Status CountFromFileAll(vector<string> vStr, int Index);//对vector<string>中第Index个文件名对应文件进行高级代码统计(-a)
    30     void Display(vector<string> vStr, int Index);    //vector<string>中第Index个文件名输出统计函数
    31     Status EmptyCheck(string s, int pos);            //空行检查与统计
    32
    33     void CountMain();                                //统计功能入口
    34     void workMain(int argc, char *argv[]);            //类主功能函数入口
    35
    36 };

5. 关键功能伪码

1. -c -w -l :

 1 wc_basic_function(FileName)
 2 {
 3     File *fp = fopen(FileName, "r");
 4     char c;
 5     bool bEnd = false;
 6     while(bEnd != true)
 7     {
 8         while ((c = getc(fp)) != EOF)
 9         {
10             if (isalpha(c))    //调用stdarg.h中的isalpha(),判断是否为词组,是则词组数++;
11             {
12                 iNumOfWord++;
13                 break;
14             }
15             iNumOfChar++;
16             if ((c) == ‘\n‘)
17             {
18                 iNumOfLine++;
19             }
20         }
21         while (c != EOF)    //由于词组判断完后上一个循环结束,此循环将继续统计行数及字符数。
22         {
23             iNumOfChar++;
24             if ((c) == ‘\n‘)
25             {
26                 iNumOfLine++;
27             }
28             if (!isalpha(c))
29             {
30                 break;
31             }
32             c = getc(fp);
33         }
34         bEnd = (c != EOF);
35     }
36 }

2. -a:

  1 function_GetFileAllInfo()
  2 {
  3     Status tmpStatus;
  4     allStatus.bComm1 = allStatus.bComm2 = allStatus.bEffective = false;    //高级统计状态机初始化
  5     iNumOfEffectiveLine = iNumOfEmptyLine = iNumOfCommentLine = 0;    //代码行数、空行数、注释行数置零初始化
  6     while (!tmpifs.eof())
  7     {
  8         pos = 0;
  9         allStatus.bEffective  = false;
 10         getline(tmpifs, strTmpRowStr);    //读取文件中的一行代码
 11
 12         StringSkip(strTmpRowStr, pos);
 13
 14         tmpStatus = EmptyCheck(strTmpRowStr, pos);    //空行检查与统计
 15         if (en_true == tmpStatus)
 16         {
 17             continue;
 18         }
 19         else if (en_fail == tmpStatus)
 20         {
 21             return en_fail;
 22         }
 23
 24         while (1)
 25         {
 26             if (false == allStatus.bComm2
 27                 &&    ‘/‘ == strTmpRowStr[pos]
 28                 && ‘/‘ == strTmpRowStr[pos + 1])    //读取到"//"的情况
 29             {
 30                 if (false == allStatus.bEffective)
 31                 {
 32                     iNumOfCommentLine++;
 33                 }
 34                 else
 35                 {
 36                     iNumOfEffectiveLine++;
 37                 }
 38                 break;
 39             }
 40
 41             if (false == allStatus.bComm2
 42                 &&    ‘}‘ == strTmpRowStr[pos]
 43                 && ‘/‘ == strTmpRowStr[pos + 1]
 44                 && ‘/‘ == strTmpRowStr[pos + 2])    //读取到"}//"的情况
 45             {
 46                 if (false == allStatus.bEffective)
 47                 {
 48                     iNumOfCommentLine++;
 49                 }
 50                 else
 51                 {
 52                     iNumOfEffectiveLine++;
 53                 }
 54                 break;
 55             }
 56
 57             if (false == allStatus.bComm2
 58                 &&    ‘/‘ == strTmpRowStr[pos]
 59                 && ‘*‘ == strTmpRowStr[pos + 1])    //读取到"/*"的情况
 60             {
 61                 pos += 2;
 62                 allStatus.bComm2 = true;
 63                 continue;
 64             }
 65             if (true == allStatus.bComm2)    //    "/**/"的过滤处理
 66             {
 67                 if (‘*‘ == strTmpRowStr[pos] && ‘/‘ == strTmpRowStr[pos + 1])    //读到"*/"时的状态处理
 68                 {
 69                     pos++;
 70                     allStatus.bComm2 = false;
 71                     iNumOfCommentLine++;
 72                 }
 73                 else if (‘\0‘ == strTmpRowStr[pos])    //读取至行末时的处理
 74                 {
 75                     if (true == allStatus.bEffective)    //若此时为有效代码状态,则代码行数++。例如 printf("hello\n"); /*this is a hello print*/
 76                     {
 77                         iNumOfEffectiveLine++;
 78                     }
 79                     else    //否则,此处代表纯注释行,则注释行数++
 80                     {
 81                         iNumOfCommentLine++;
 82                     }
 83                     break;
 84                 }
 85                 pos++;
 86                 continue;
 87             }
 88
 89
 90             if (‘\0‘ == strTmpRowStr[pos])    //运行至行末
 91             {
 92                 if (allStatus.bEffective == false)
 93                 {
 94                     if (allStatus.bComm1 || allStatus.bComm2)    //纯注释行
 95                     {
 96                         ++iNumOfCommentLine;
 97                     }
 98                 }
 99                 else if (allStatus.bEffective == true)
100                 {
101                     ++iNumOfEffectiveLine;
102                 }
103                 break;
104             }
105             pos++;
106             allStatus.bEffective = true;
107         }
108     }
109     tmpifs.close();
110 }

3. -s:

递归算法伪码:

 1 class cal{
 2     ...
 3     vector<string> vFilePath;
 4     vector<string> vDirPath;
 5     ...
 6     wc_GetFile_main(string strDirPath)    //递归遍历目录,并将所有代码文件路径传入FilePath中
 7     {
 8         string tmpStr;
 9         DirList(vDirPath, strDirPath + "\\*");    //从strDirPath + "\\*"指定的路径中递归查找代码文件,并录入至vFilePath中;将strDirPath的子目录名传入vDirPath中。
10         for (i = 0; i < vDirPath.size(); ++i)
11         {
12             tmpPath = strDirPath + "\\" + vDirPath[i];    //子目录路径拼接。
13             myFileFind(tmpPath);    //对子目录进行递归操作。
14         }
15     }
16
17     DirList(verctor<string> &vStr,string strPath)    //获取当前目录下的子目录名与代码文件路径,分别录入到vStr与vFilePath中。
18     {
19         vector<string> vStrTmp;
20         _finddata_t fileDir;
21         long lfDir = _findfirst(strPath.c_str(), &fileDir);
22         int tmpPos;
23
24         if (-1l == lfDir)    //尚未实现具体的文件类型识别,仅进行_findfirst是否成功的判断
25         {
26             cout << "DirList: "<< strPath <<"   File or dir not found!" << endl;
27         }
28         else
29         {
30             string tmp = strPath;
31             tmp.erase(tmp.size() - 1, 1);//去除路径中的‘*‘
32             do
33             {
34                 string FileOrDirName(fileDir.name);
35                 if (FileOrDirName.find(‘.‘) == -1)    //目录则将目录名传入vStrTmp中
36                 {
37                     vDirPath.push_back(fileDir.name);
38                 }
39                 else if(
40                         ((tmpPos = FileOrDirName.find(".cpp")) != -1 && FileOrDirName[tmpPos + 4] == ‘\0‘)    //精确匹配.cpp字串
41                     ||    ((tmpPos = FileOrDirName.find(".c")) != -1  && FileOrDirName[tmpPos + 2] == ‘\0‘)    //精确匹配.c字串
42                     || ((tmpPos = FileOrDirName.find(".h")) != -1 && FileOrDirName[tmpPos + 2] == ‘\0‘)        //精确匹配.h字串
43                     )//代码文件则将其路径传入vStrCodeFilePath中
44                 {
45                     vFilePath.push_back(tmp + FileOrDirName);
46                 }
47             } while (_findnext(lfDir, &fileDir) == 0);
48         }
49         _findclose(lfDir);
50         vStr = vStrTmp;
51     }
52     ...
53 };

在获得到所有代码文件路径的vector<string> vFilePath后,逐一对vFilePath内各个路径进行代码统计与信息输出即可,简单的迭代就可以实现。

总结

  1. 前期的准备工作非常重要,知识学习与储备、类似的程序框架的参考、算法的评估、按需求设计功能模块等等,都是为中期代码开发提供方向与实现基础的,不重视前期工作的话在中期代码开发与后期的测试、文档撰写方面要吃很大的亏,代码体现的思路与实现方式也难以简洁优雅。这次实践中我就是吃了这个亏,导致在具体代码实现时做了很多前期需要做的工作,流程很乱,效率不高。
  2. 注意待统计代码文件的编码类型,utf-8在此程序中表现良好。曾在测试环节中遇到对unicode编码的文件进行统计,算法失败地一塌糊涂,统计结果与实际也相差甚远。在接近有一个半小时的时间里都是在debug,试图在算法上找错误的根源,无果。最终发现是unicode编码下宽字符串的问题,换用utf-8后表现良好。
  3. 此次的时间较赶,感觉代码质量还不高,找机会整理好思路,按PSP的流程进行代码重构。

原文地址:https://www.cnblogs.com/HelloGaveu/p/9649580.html

时间: 2024-10-14 03:53:44

个人项目开发PSP实践-MyWCprj的相关文章

Android 实践项目开发 总结

  Android 实践项目开发 总结 课程:移动平台应用开发实践  班级:201592  姓名:杨凤  学号:20159213 成绩:___________       指导老师:娄嘉鹏          实验日期 :2015.12.06. 实验名称:                   android 百度地图开发 实验目的与要求: 1.实现定位 2.查询公交路线       3.目的地查询 实验目的: 在这次的项目开发中,我做的软件主要功能是调用百度地图的接口,实现定位.查询公交路线 和查

C#项目开发实践前言

以前没有做过项目开发实现讲解,都是在工作过程当中,自己主动学习,查找资料,因为在以前的公司就我一人在做c#WinForm开发,所以,有时候在公司培训会上,我也会为新的员工进行过一些简单的项目讲解,基于在培训过程当中自己的不足,以及在学习查找资料过程当中,在网上查找资料有时真的很费劲,而目前想找一个为当前实现找一个互相交流的平台也不太容易,所以,我有一个想法就是提供一个相互学习交流的平台,践于很多时候有大部分人员不能及时交流或某些原因不方便,不能及时有效的提供一些信息,所以这个交流平台上,会把所以

《机器学习项目开发实践》链接失效的新地址

最近收到一本<机器学习项目开发实践>,快速翻了翻觉讲的挺基础,主要还可以顺带学习一下F#.但是细读的时候才发现本书会需要在OneDrive上下载一些训练数据,在第一个链接也就是1.3.1小节的第一段中"http://1drv.ms/1sDThtz"这个地址就已经失效了,翻到后面也没找到什么备用链接.最后只有联系出版社,在半个多月的交涉中责编终于回复我了.新的资源地址:https://github.com/mathias-brandewinder/machine-learni

百度地图V2.0实践项目开发工具类bmap.util.js V1.4

/** * 百度地图使用工具类-v2.0(大眾版) * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email [email protected] * @company KWT.Shenzhen.Inc.com * @notice 有些功能需要加入外部JS库才能使用,另外还需要申请地图JS key . * 申请地址:http://developer.baidu.com/map/apply-key.ht

[1.30] 保持的力量:接口开发最佳实践

神啊,求你赐给我平静的心,去接受我无法改变的事:赐给我勇气,去做我能改变的事:赐给我智慧,去分辨两者的不同. --平静之祷 1.30.1 论保持的力量 追到一个心仪的女生不难,难于如何保持和培养一份真挚的感情:获得一时的财富也不难,难于如何长久保持收益:创业的公司很容易博得一时媒体的关注以及某次天使的投资,但难于如何排除各种障碍.充分利用各方资源发展成中企业及至上市公司. 同样,提供一时的接口很容易,但当我们需要不断为接口提供升级,以及当我们维护提供一整套接口时,面临的困难和问题会越来越大.所以

[转]基于Starling移动项目开发准备工作

最近自己趁业余时间做的flash小游戏已经开发得差不多了,准备再完善下ui及数值后,投放到国外flash游戏站.期间也萌生想法,想把游戏拓展到手机平台.这两天尝试了下,除去要接入ane接口的工作,小游戏本身不用做任何改动就可以迁移到android和ios手机平台.只是在手机上,游戏的掉帧情况非常严重,远达不到pc上的体验效果.看来做flash移动游戏,不用starling框架是不行的.打算这几天学习下starling,对项目进行改造. 基于Starling移动项目开发准备工作 转自: Starl

atitit.微信项目开发效率慢的一些总结

#---理念问题..这个是最大的问题.. 要有专人提升开发效率才好.. #---没有一个好的开发方法体系.... ini deve 法. fell asd+xp+ipd 比较好.. #---团队配合弱的.. 研发体系延续早期的一个独立的开发团队负责一个独立产品... 面对客户小批量个性化的需求,太高的成本.太长的周期,做会亏本,不做会损失市场 #---需求管理不足...没有需求更改流程. 需要需求管理,需求的范围不断扩大... 作者 老哇的爪子 Attilax 艾龙,  EMAIL:[email

Android企业级应用程序开发完整训练:精通Android商业级开发最佳实践的24堂课

从企业级商业实战的角度入手,24小时内通过23个动手实战案例,循序渐进的对Android商业级别的应用程序开发要点各个击破,依托于在多年的Android(6款完整的硬件产品和超过20款应用软件)开发和企业级培训经验(超过150期的次Android的企业内训和公开课),旨在在实务的基础之上帮助你完成任何复杂程序的高质量Android应用程序开发,让Android开发跟上想象的速度.最后,通过ActivityManagerService揭秘Android应用程序一切行为背后的核心根源,让你从此开发应

Hadoop MapReduce开发最佳实践(上篇)

body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI",Tahoma,Helvetica,Sans-Serif,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5;}