㈠ 找软件外包公司做项目,需要注意什么问题
喜妹把某些外包公司开发App的套路写出来给大家提个醒!一定要注意以下五点!
套路一、虚假的知名案例
一般来说,客户和外包公司有三次现实交流的机会。
1.初步交涉:双方建立联系,外包公司自我介绍,客户阐述需求。
2.实地考察:客户亲临外包公司,看看公司规模、办公场地、员工架构。
3.达成合作:确认需求,签署合同,开始研发。
三步环环相扣,内藏杀机。
初步交涉阶段,客户会问外包公司有哪些案例,某些不靠谱的外包公司会用各种成功案例吹嘘自己,美团是我们做的,滴滴交给我们外包过,陌陌也是我们的案例......但细问之后却不能说出产品细节和开发过程。
相比之下,那些敢拿出一些自家真实开发但是不知名的成功案例给客户看的外包公司更坦诚一些,也更值得信任(毕竟没有那么多的案例可以一成而就,很多需要时间的沉淀)。
套路二、需求不明确就直接报价
一般在初步交涉时,客户就会想了解报价情况。如果外包公司在未了解清楚需求后直接脱口而出一个准确的价格,那就可以直接pass了。
因为开发一个App,小到登录方式,大到产品信息架构,不同的需求对一个项目的定价就有很大区别。在需求不明确的情况下就直接说出价格的外包公司,纯粹就是为了利用低价引诱客户。
所以,当外包公司在报价前详细的问了很多需求,这才是对客户负责的表现,这会是一个好的开始。
套路三、公司全靠销售撑着
在利用知名案例和低价忽悠之后,就进入了第二步。毕竟客户还是会持有“眼见为实,耳听为虚”的怀疑态度,需要进行实地考察,看看他们的员工配置是怎样的,有几个工程师,有几个产品经理和UI,有几个做销售的。
某些外包公司只为了多接单,并不注重技术,所以工程师的人员占比会比较少,可能连产品经理都没有。
拿最常用的登录方式这一块来举例,如果前期没考虑周全,只想到用手机验证码登录,而在后期想增加通过微信、QQ登录。其实只是一个很简单的小需求,流程逻辑是同样的,但某些外包公司就会搬出合同来说事,只要增加了需求就要求加钱。
当然也有前期低价竞标,中途高价增加需求的;也有消极怠工,粗制滥造的;还有趾高气昂,求着开发的;更有雇无经验的实习生,磕磕绊绊开发......这样开发的App和外包公司完全是个无底洞,你放心吗?
所以,针对喜妹上面讲的那五“阴”真经,客户该如何擦亮眼去识破这些套路呢?别急,喜望软件来传授你天龙八“步”。
第一步、查明真伪
当他们说哪些哪些知名案例是他们做的时,不要光听,得看他们的案例图、UI图,有上线的App就去下载下来实际操作体验一下,看看逻辑功能有没有问题、设计风格怎么样、会不会突然闪退或崩溃等等。
第一次实地考察后,还可以偷偷去突击考察,考察员工、场地。毕竟真金不怕火炼,好公司不怕突击。
第二步、明确需求
只有自己最清楚自己要什么,你的app到底需要什么风格、需要什么功能、不需要什么功能,一定要有清晰的想法。可以听听外包团队的建议,但不能完全被他们带着走了。沟通好的细节需求也一定要全部落实到需求文档还有功能清单或者原型图上,挨个确认签字。
第三步、专业产品
外包团队一定要有产品经理这一个岗位,他是客户与程序员之间最好的沟通桥梁。当客户说不清需求,程序员也听不懂需求的时候,最好的翻译就是产品经理了。
专业的他们能站在用户及客户的角度上把需求掰碎了、捋顺了传达给程序员,可以避免很多沟通和开发问题,能让app开发更顺利。
第四步、跟踪进度
客户需要清楚app的开发流程及工期安排,在正式进入项目开发之前,外包团队会对项目研发周期、提测时间、预发布时间点进行初步的判断,把项目需求划分成节点进行迭代开发计划。每个节点开发且测试完成后给客户递交周报或验收确认,然后再继续开发下一节点。
第五步、检查合同
一般都没有一次就定好的合同,在签合同之前要考虑好:项目是否按照前期原型图做、功能是否完善可用、工期安排是否合理和付款方式等。法治社会,大家都是守法的人,正规的外包公司都会跟客户签订正规的开发合同。所以之前提到过的开发方式、需求、UI、工期和款项等,都必须要在合同里有严格的规定。
第六步、定制&成品
成品app就是套用其他app的模板,这样可能就没有自己的特色,如需增加功能就得另外加钱了。而定制开发就是完全根据客户自己的需求来做,价格比成品app要高,工期也会更长。
两者各有各的优劣势,客户可以自行分析选择,但要注意的是,若是直接购买成品,对于功能模块的增减,外包公司是否能做、价格是否合理,这个需要提前沟通清楚;若选择定制开发,就要防止外包公司不按前期原型图来做,而是给你套模板。
第七步、源码交付
别以为项目开发完就完全放心了,交付也是很重要的一块。外包团队需要按照合同规定,将源码(含源码)、说明文档、操作文档等所有项目的相关资料交付给客户。
包括但不限于:
1.前后端项目的所有最新源代码(含注释)
2.数据库设计文档
3.API接口文档
4.所有的开发者账号资料
5.原型设计稿
6.UI设计稿
7.项目相关文档等资料
一定要把源码拿到自己手上,方便后期进行迭代开发及系统维护。
第八步、完整服务
完整服务是指不仅提供单纯的技术服务,同时提供包括产品设计、用户体验、技术咨询及运营维护等一系列服务。外包团队需要有一条从开发到维护的完整服务链,用专业的经验让客户少走弯路。
无论是大型的外包公司,还是小型的外包团队,凡是不能用“All In”的态度为客户服务的外包,都不能算是好外包。
魔高一尺道高一丈,喜望软件传授了你如何见招拆招的天龙八“步”,可要好好收藏起来。其实对于我们软件开发服务商来说,我们与客户都是合作共赢的关系,最终是希望能帮客户赚到钱。所以在开发过程中,双方若是能坦诚相待,这是再好不过的啦。
㈡ C++课 没听··· 不懂··· 关于什么类啊 对象的~求详细解释
//修改后的程序如下:
#include <iostream>
using namespace std;
class stud
{
public: //增加public 定义,VS2010在未使用此定义时默认为 private
void setscore(int sc);
void inscore();
void getscore();
int score;
};
stud s;
int main()
{
s.setscore(0); // 增加 s. , 调用 s 的成员函数 , 下同
s.inscore();
s.getscore();
}
void stud::setscore(int sc) // 修改 函数类型,与类定义一致,增加stud::, 表示是 stud的成员函数
{ score=sc; }
void stud::inscore()
{ cin>>score; } // 去掉s. , 下同。
void stud::getscore()
{
cout<<score<<endl;
}
// 建议不在类的 成员函数中 使用 CIN,COUT等,否则失去封闭的意义了
㈢ 软件工程 静态测试的主要方法有哪些
(1)人工检测:是指不依靠计算机而是靠人工审查程序或评审软件,包括代码检查、静态结构分析和代码质量度量等;
(2)计算机辅助静态分析:利用静态分析工具对被测试程序进行特性分析,从程序中提取一些信息,以便检查程序逻辑的各种缺陷和可疑的程序构造。
静态测试包括代码检查、静态结构分析、代码质量度量等。它可以由人工进行,充分发挥人的逻辑思维优势,也可以借助软件工具自动进行。
(3)工程清单源码扩展阅读:
代码检查包括代码走查、桌面检查、代码审查等,主要检查代码和设计的一致性,代码对标准的遵循、可读性,代码的逻辑表达的正确性,代码结构的合理性等方面;可以发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分、违背程序编程风格的问题,包括变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等内容。
在实际使用中,代码检查比动态测试更有效率,能快速找到缺陷,发现30%~70%的逻辑设计和编码缺陷;代码检查看到的是问题本身而非征兆。但是代码检查非常耗费时间,而且代码检查需要知识和经验的积累。
代码检查应在编译和动态测试之前进行,在检查前,应准备好需求描述文档、程序设计文档、程序的源代码清单、代码编码标准和代码缺陷检查表等。静态测试具有的发现缺陷早、降低返工成本、覆盖重点和发现缺陷的概率高的优点以及耗时长、不能测试依赖和技术能力要求高的缺点。
㈣ 如何实现log4cxx日志输出方式
Log4cxx是开放源代码项目Apache Logging Service的子项目之一,用于为C++程序提供日志功能,以便开发者对目标程序进行调试
和审计。本文对log4cxx的使用及配置进行介绍,并给出一个可以快速开始的实例。最后,针对日志服务给出一些实践方面的建议。
1. 介绍
Log4cxx是开放源代码项目Apache Logging Service的子项目之一,是java社区着名的log4j的c++移植版,用于为C++程序提供日志
功能,以便开发者对目标程序进行调试和审计。
有关log4cxx的更多信息可以从Apache Loggin Service的网站http://logging.apache.org获得。当前的稳定版本为0.9.7,本文内
容及示例代码都是基于此版本。此外,示例代码的编译环境为Windows环境中的Microsoft Visual C++ .Net 2003。
本文的示例代码可以在此下载,其中也包含了预编译好的log4cxx的库文件。
2. 集成log4cxx到IDE
要使用log4cxx,首先需要将其集成到你的项目开发环境中。以下针对Windows环境中的Microsoft Visual C++ .Net 2003进行说明
,其他环境的配置信息请参考官方文档。
要让log4cxx为你工作,通常情况下需要如下几个步骤:
l 获取软件包:得到log4xx的源代码;
l 编译:构建库文件;
l 项目环境设置:加入log4cxx支持。
2.1 获取软件包
请从官方网站获得合适的版本。也可以从下面这个链接中直接获取(直接的链接地址可能不会永远有效):
http://mirror.vmmatrix.net/apache/logging/log4cxx/log4cxx-0.9.7.tar.gz
下载完成后解压缩到合适的目录中,因为我们在下一步中需要使用软件包,包括编译和复制必要的文件。
2.2 编译
原始发行包中不含编译后的代码,这个工作需要我们自己来做。打开你的IDE,并加载以下目录中的工程:
l Msvc\static:该工程产生log4cxx的静态链接库(lib4cxx.lib和lib4cxxs.lib);
l Msvc\dll:该工程产生log4cxx的动态链接库(lib4cxx.dll)。
通常情况下,工程都可以顺利编译通过。查看输出目录,把这些生成的库文件找出来,以便在下一步骤中使用。
2.3 项目环境设置
请先在IDE中打开一个需要加入日志功能的工程,或者出于实验目的,新建一个工程,以便对其进行设置。
首先需要设置log4cxx的include文件。这些文件位于log4cxx软件包的include\log4cxx目录内。请查看你的VC++ IDE中“工具->选
项->项目->VC++目录->包含文件”所列出的内容,以便确定你以何种方式加入这些include文件:
l 将include\log4cxx直接拷贝到已定义的包含文件目录中。如果将log4cxx看作是一项系统服务的话,这样做是胡合乎情理
的,因为你可以采用标准库的方式使用它,例如:#include <log4cxx/logger.h>
l 增加一个包含路径,以指向位于IDE外部的某一文件目录。可以简单的指向在2.1中解压缩后形成的log4cxx软件包目录。
下一步需要对2.2节产生的log4cxx库进行设置。这取决于你使用该库的方式:静态链接或者动态链接。
l 静态链接情况下需要做如下工作:为预编译器定义LOG4CXX_STATIC宏,设置位置为“项目->属性->配置属性->C/C++->预
处理器->预处理器定义”;为链接器指定依赖的库lib4cxxs.lib和Ws2_32.lib,设置位置为“项目->属性->配置属性->链接器->输
入->附加依赖项”。
l 动态链接情况下只需要为链接器指定依赖的库lib4cxxs.lib即可,设置方式同上。
3. 示例代码
本节展示了一个最简单的log4cxx示例,以便你可以快速的了解它。
该示例在功能上创建了一个日志服务,该日志可通过配置文件进行必要控制,并可以同时向文件和控制台输出信息。
在实现上,我们采用了一个简单的控制台程序,并使用动态链接库的方式使用log4cxx。
要实现这个目标,请按如下步骤进行:
1)创建一个名为logdemo的空白win32控制台工程,并按照2.3节所述内容对其进行设置。注意,这里我们使用动态连接口的方式。
2)在logdemo.cpp中加入实现日志功能的代码。完成后的代码清单如下:
#include "stdafx.h"
#include <log4cxx/logger.h>
#include <log4cxx/propertyconfigurator.h>
using namespace log4cxx;
int _tmain(int argc, _TCHAR* argv[])
{
//加载log4cxx的配置文件,这里使用了属性文件
PropertyConfigurator::configure("log4cxx.properties");
//获得一个Logger,这里使用了RootLogger
LoggerPtr rootLogger = Logger::getRootLogger();
//发出INFO级别的输出请求
LOG4CXX_INFO(rootLogger, _T("它的确工作了"));
//rootLogger->info(_T("它的确工作了")); //与上面那句话功能相当
return 0;
}
以Debug方式编译工程,调试程序直到成功为止。
3)新建一个文本文件,命名为log4cxx.properties,并键入如下内容:
# 设置root logger为DEBUG级别,使用了ca和fa两个Appender
log4j.rootLogger=DEBUG, ca, fa
4)复制log4cxx.dll到输出目录。在动态链接方式下,应用程序需要能够找到这个库文件。
5)运行生成的logdemo.exe文件,查看一下运行结果,看看我们工作有没有取得成效。如果一切顺利,无论是在控制台还是在输出
文件中,都应该能看到类似下面那样的输出内容:
2006-06-02 16:09:50,609 [2528] INFO root - 它的确工作了
4. 体系结构
4.1 核心类
Log4cxx有三个关键组件,它们是loggers, appenders和layouts。
Logger是log4cxx的核心类,只要执行日志操作;looger有层次结构,最顶层为RootLogger;logger是有级别的。每个logger可以附
加多个Appender。Appender代表了日志输出的目标,如输出到文件、控制台等等。对于每一种appender,都可以通过layout进行格
式设置。
这三类组件用示意图表示如下(不代表类关系):
(TODO:在此对三种组件分别进行说明)
4.2 配置类
此外在使用中还会用到的类有BasicConfigurator、PropertyConfigurator和DOMConfigurator等,用于对log4cxx进行配置。其中:
BasicConfigurator提供了一种简单配置,包括使用ConsoleAppder作为root appender和PatternLayout作为缺省布局。
PropertyConfigurator使用properties文件作为配置方式。
DOMConfigurator则使用properties文件作为配置方式。
(TODO:在此对配置内容进行说明)
5. 实践指导
在项目中是否使用日志,以及如何使用日志,对开发者来说都是一个需要做出的技术选择,这通常会牵扯到系统的性能,使用日志
的目的等问题。我们使用日志的方式,有些是这个行业积累了多年的经验,有些则纯粹关乎个人的喜好。
1)何时使用日志
通常情况下,日志的作用在于调试和审计,如果你的项目对此有特殊需求,即可考虑使用日志。
对于调试,通常用于IDE调试器无法达到的地方。一些常见的场景包括:
分布式组件的调试。在服务器端的组件,需要通过客户端的调用来验证其工作是否正确,此时利用日志的输出作为辅助工具对错误
进行诊断。
链接库调试。在无法跟踪进外部库中的情况下,这种方法非常有效。
生产环境下的调试。生产环境通常是指产品在客户处处于正式运行的状态,在出现问题时,开发者常常不在现场,借助日志的输出
进行错误判断就是一个非常有效的手段。
对于审计应用,则需要视特定的情况而定,程序级的记录能力,无疑可以作为业务级审计手段的有效补充。
无论是在哪种场景下,log4cxx都是可以胜任工作的,这取决于它的灵活的配置能力及多种类型的输出方式。
2)性能问题
关闭日志,通过配置文件设置日志的关闭和打开
使用宏代替logger的输出命令
选择性输出日志。建立logger的层次结构,根据级别选择性输出
输出目标。尽可能减少输出目标
选择合适的输出格式。使用SimpleLayout将达到与std::cout相当的速度。
3)其它
使用类的全限定名对logger命名
6. 结论
Log4cxx具有的一些显着特性使得C++者可以将其放入自己的工具箱中,这些特性包括灵活的配置能力,多种输出手段,丰富的格式
控制,出色的性能。如果在你的开发中需要借助于日志进行调试和审计,你也许需要log4cxx。最后,重要的一点是,如你所见,
log4cxx的使用是如此的简单。
㈤ delphi等窗口完全显示后执行一段代码
你说的或意思是不是像WORD 启动时效果
巧用Delphi制作溅射屏幕
(作者:施路)
精心编写的WINDOWS程序显示启动注意事项,称之为溅射屏幕(splash screen)。利用一点儿小小的内容,即可给程序的显示添加不少色彩。
由于工程本身创建程序的主窗口,且启动溅射屏幕必须在创建主窗口之前出现,所以工程文件必须创建自己的启动屏幕。这意味着用户必须修改源代码来创建工程文件,而这通常在DELPHI编程中是不需要的。下面的过程介绍了溅射屏幕的建立过程。
1、开始一个新的工程。将窗体命名为MainForm,同时将其Caption属性设置为SplashinDemo。把这个工程保存在一个目录中,如C:\Projects\Splashin。把MainForm的单元命名为Main,把工程文件命名为Splashin。
2、在MainForm中插入一个Button组件。将Button的Name属性改为ExitButton,而将其Caption属性改为Exit。为ExitButton的OnClick事件创建一个处理器,在过程的begin和end关键词之间插入Close;语句。
3、选取File|New Form命令,或者单击New Form速度按钮。添加一个新的窗体。
4、将这个窗体的Name属性改变为SplashForm,删除其Caption属性。此外,将其BorderStyle属性改变为bsnone,同时将BorderIcons下的三个子值设置为False。
5、保存这个工程。当Delphi提示读者提供单元文件名时,要确信当前目录为正确的目录。为SplashForm的单元文件名输入Splash。
6、将SplashForm的Enabled属性设置为False。这里不想让用户能够给窗口提供键盘和鼠标命令,这是极少见的情况之一。在这个例子中,我们想让程序对SplashForm的显示拥有完全的控制权。
7、由于窗口没有轮廓,所以从Additional组件类中插入一个Bevel组件对象。这有助于定义窗口的边缘。将Bevel1的Align属性设置为alClient。同时,将对象的Shape属性改变为bsFrame,将其Style属性改变为bsRaised。这些值由使用者来确定。
8、在SplashForm中插入想使用的组件,在这里不要插入任何按钮或者其他相互作用的控件。应用程序本身显示和去除启动溅射对话框。
9、选择Project菜单。高亮显示Splash工程个弹出式菜单。选择Options命令。在所产生的Project Options对话框中,选取Forms页标签。注意,MainForm和SplashForm位于自动创建的窗体列表中。高亮显示每个窗体并单击鼠标右按钮来将其移动到Available窗体。所有的Delphi窗体在运行时都是在内存中自动创建的,这要消耗内存和系统资源。在这样的一个案例中,程序是在运行时创建窗体的,读者应该从自动创建的列表中删除窗体。关闭ProjectOptions窗口。
10、接下来,修改工程的源代码,以便在显示主窗口之前显示溅射对话框。这里需要在工程文件中插入语句,以便与Splash.dpr工程文件相匹配。工程源代码如下:
program Project3;
uses
Forms,
main in 'main.pas' {MainForm},
splash in 'splash.pas' {SplashForm};
{$R *.RES}
begin
SplashForm:=TSplashForm.Create(Application);
SplashForm.Show;
SplashForm.Update;
Application.CreateForm(TMainForm,MainForm);
SplashForm.Close;
Application.Run;
end.
11、如果这时编译和运行程序,它就非常快速地显示和去除启动溅射对话框,以至用户可能没机会见到它。为了强迫对话框保持几秒钟的可见时间,请选取程序的MainForm。为窗体的OnCreate命令创建一个处理器。在关键词的前面添加一个名为stopTime的长整型变量。在begin和end之间插入两个语句:一个为对Windows GetTickCount函数的调用。来将stopTime设置为Windows已在运行的秒数;另一个语句为while语句,这个语句另外延迟2秒钟。程序清单如下:
unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TMainForm = class(TForm)
Exitbutton: TButton;
procere ExitbuttonClick(Sender: TObject);
procere FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procere TMainForm.ExitbuttonClick(Sender: TObject);
begin
close;
end;
procere TMainForm.FormCreate(Sender: TObject);
var
stopTime:LongInt;
begin
stopTime:=GetTickCount div 1000;
while ((GetTickCount div 1000)<(stopTime+2)) do
Sleep(1);
end;
end.
12、按F9编译、运行程序。
㈥ 安卓中的data下的文件怎么用快捷键导出到电脑
1. api
安卓官方文档中已经提供了很多demo,在使用未知的控件时,可以采用这种方式
2. 系统源码
系统源码是最好的老师,通过一步步的点击,进入系统的源码.或者我们需要调用系统的某个应用的activity时,都可以直接翻看系统源码
一般查看源码有以下的几种方式
1) 在自己的代码中直接ctrl+鼠标右键,点进去直接查看,这种方式适合于只是简单的查看系统在api中所描述的实现逻辑
2) 直接进去源码翻看,比较适合于对安卓工程文件相当熟悉的工程师,一般查看都是先从资源清单文件开始,系统源码比较有特点,英语稍微好一点,能够将自己想表达的意思直接搜索清单文件,比如说要打开系统的主页面launcher应用程序,那么路径是在.../packages/apps/launcher2,最好还是要非常熟悉安卓工程的构成,这样在翻阅的时候,你想搜索什么,定位会很清晰的
3) 新建工程,从系统的源码导入(还是要对安卓工程和安卓系统源码的组织结构有一定的了解,导入工程后一般会有错误的,但是这不是我们所关心的,我们不是在编译源码),通过搜索关键字,一般我们搜索的方式或者操作步骤如下:(通用搜索在eclipse中直接快捷键ctrl+H即可)
i. 查看到系统的某个activity中的内容,这个东东就算用脚丫子想,也是在values/strings.xml中,就是是动态变化的一些值(除了数值),都是在这个里面(国际化嘛)
ii. 通过查找到vlaues,那么就看到了对应的name,name的通常情况下,是在布局文件中引用的,也有的是在java代码中的(这是比较特殊的),那么直接搜索name
iii. 安卓通用情况,那么这是看到后台就有values和layout文件下的文件,layout下的文件是我们关心的,打开layout下的这个文件,看到控件的id,再次搜索id
iv. 搜索到id,打开对应的java文件就看到了,一路ctrl+K,定位到处理的逻辑
v. 代码逻辑看懂后,复制粘贴,报错的很有可能是底层隐藏的方法,隐藏的方法,是可望而不可即的吗?非也,只不过使用的方式特殊一点而已,用反射不就搞定啦?
3. 参照他人的代码
1) 查看系统后台日志
一般在看到某个应用在调用系统的activity时,我们好奇他发送了怎么样的intent, logcat中会显示的,想实现这个目的,采用这种方式是比较简单的
2) 反编译
反编译是一种很好的方式,什么时候需要使用到反编译呢?
一般如下的几种场景使用到反编译
(1) 要参照其他应用的图片
(2) 要参照其他应用的布局
(3) 要参照其他应用的逻辑处理
针对以上的几个需求场景,我们的处理方式分别如下:
只是获取图片的处理:
图片在安卓应用中不是隐私的东西,要获取到的话,很简单,直接下载到其他应用的apk文件,即安装包,将后缀名修改为.zip即可,解压缩开,在res/drawable***的文件下,这就是对应的图片
参照其他应用的布局
要参照布局,那么就需要借助工具了,不能简单的使用上面获取图片的处理方式,可以使用apktool这个工具,操作步骤如下:
进入到apktool的目录下,打开控制台,输入如下的命令 apktool d 对应的apk全路径和文件名即可解压开,在apktool的文件中发现新多了一个文件夹,名字与apk的名字相同,这就成功了,可以查看布局文件了
参照其他应用的程序逻辑
同样需要借助工具,dex2jar和gui
操作步骤:
将apk的文件后缀名修改为zip
解压缩找到对应的dex文件
将dex文件转变为jar文件就可以了,使用dex2jar的命令dex2jar classpath.dex 然后文件自动转换,生成的文件位于dex2jar的目录下
将文件使用gui打开即可(这只是未加密的文件的处理方式,已经加密的,那么就需要我们学习学习smali语言了,才能分析文件
㈦ 什么是 源程序清单
源代码的集合.
㈧ 如何使用 Pylint 来规范 python 代码风格
Pylint 在 linux 上的安装
1. 在 Linux 上,首先安装 Python 的包(高于版本 2.2),并在环境变量 $PATH 中添加 Python 可执行文件的路径。
2. 下载 Pylint、logilab-astng (version >= 0.14) 和 logilab-common (version >= 0.13) 的包 , 使用 tar zxvf *.tar.gz解压缩这些包。
3. 依次进入 logilab-astng、logilab-common 和 Pylint 解开的文件夹中,运行命令 Python setup.py install来安装。
4. 安装完成后,就可以通过 pylint [options] mole_or_package来调用 Pylint 了。
Pylint 在 Windows 上的安装
1. 安装 Python 的包(高于版本 2.2),右键单击桌面上的我的电脑图标,选择属性,高级,环境变量,在 $PATH 中添加 Python 的安装路径,如 C:\Python26\。
2. 使用解压缩工具解压缩所有的包。
3. 打开命令行窗口,使用 cd依次进入 logilab-astng、logilab-common 和 Pylint 解开的文件夹中,运行命令 python setup.py install来安装。
4. 安装完成后,在 Python 的安装路径下出现一个 Scripts 文件夹,里面包含一些 bat 脚本,如 pylint.bat 等。
5.
为了使调用 pylint.bat 的时候不需要输入完整路径,在 Python 的安装目录下创建 pylint.bat
的重定向文件,这是一个纯文本文件 pylint.bat,里面包含 pylint.bat
的实际路径,如:C:\Python26\Scripts\pylint.bat。
6. 安装完成后,可以通过 pylint [options] mole_or_package来调用 Pylint 了。
Pylint 的调用
清单 1. Pylint 的调用命令
pylint [options] mole_or_package
使用 Pylint 对一个模块 mole.py 进行代码检查:
1. 进入这个模块所在的文件夹,运行 pylint [options] mole.py
这种调用方式是一直可以工作的,因为当前的工作目录会被自动加入 Python 的路径中。
2. 不进入模块所在的文件夹,运行 pylint [options] directory/mole.py
这种调用方式当如下条件满足的时候是可以工作的:directory 是个 Python 包 ( 比如包含一个 __init__.py 文件 ),或者 directory 被加入了 Python 的路径中。
使用 Pylint 对一个包 pakage 进行代码检查:
1. 进入这个包所在文件夹,运行 pylint [options] pakage。
这种调用方式是一直可以工作的,因为当前的工作目录会被自动加入 Python 的路径中。
2. 不进入包所在的文件夹,运行 pylint [options] directory/ pakage。
这种情况下当如下条件满足的时候是可以工作的:directory 被加入了 Python 的路径中。比如在 Linux 上,export PYTHONPATH=$PYTHONPATH: directory。
此外,对于安装了 tkinter 包的机器,可以使用命令 pylint-gui打开一个简单的 GUI 界面,在这里输入模块或者包的名字 ( 规则同命令行 ), 点击 Run,Pylint 的输出会在 GUI 中显示。
Pylint 的常用命令行参数
-h,--help
显示所有帮助信息。
--generate-rcfile
可以使用 pylint --generate-rcfile 来生成一个配置文件示例。可以使用重定向把这个配置文件保存下来用做以后使用。也可以在前面加上其它选项,使这些选项的值被包含在这个产生的配置文件里。如:pylint --persistent=n --generate-rcfile > pylint.conf,查看 pylint.conf,可以看到 persistent=no,而不再是其默认值 yes。
--rcfile=<file>
指定一个配置文件。把使用的配置放在配置文件中,这样不仅规范了自己代码,也可以方便地和别人共享这些规范。
-i <y_or_n>, --include-ids=<y_or_n>
在输出中包含 message 的 id, 然后通过 pylint --help-msg=<msg-id>来查看这个错误的详细信息,这样可以具体地定位错误。
-r <y_or_n>, --reports=<y_or_n>
默认是 y, 表示 Pylint 的输出中除了包含源代码分析部分,也包含报告部分。
--files-output=<y_or_n>
将
每个 mole /package 的 message 输出到一个以 pylint_mole/package. [txt|html]
命名的文件中,如果有 report 的话,输出到名为 pylint_global.[txt|html]
的文件中。默认是输出到屏幕上不输出到文件里。
-f <format>, --output-format=<format>
设置输出格式。可以选择的格式有 text, parseable, colorized, msvs (visual studio) 和 html, 默认的输出格式是 text。
--disable-msg=<msg ids>
禁止指定 id 的 message. 比如说输出中包含了 W0402 这个 warning 的 message, 如果不希望它在输出中出现,可以使用 --disable-msg= W0402
Pylint 的输出
Pylint的默认输出格式是原始文本(raw text)格式 ,可以通过 -f <format>,--output-format=<format> 来指定别的输出格式如html等等。在Pylint的输出中有如下两个部分:源代码分析部分和报告部分。
源代码分析部分:
对于每一个 Python 模块,Pylint 的结果中首先显示一些"*"字符 , 后面紧跟模块的名字,然后是一系列的 message, message 的格式如下:
MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE
MESSAGE_TYPE 有如下几种:
(C) 惯例。违反了编码风格标准
(R) 重构。写得非常糟糕的代码。
(W) 警告。某些 Python 特定的问题。
(E) 错误。很可能是代码中的错误。
(F) 致命错误。阻止 Pylint 进一步运行的错误。
清单 2. Pylint 中的 utils 模块的输出结果
************* Mole utils
C: 88:Message: Missing docstring
R: 88:Message: Too few public methods (0/2)
C:183:MessagesHandlerMixIn._cat_ids: Missing docstring
R:183:MessagesHandlerMixIn._cat_ids: Method could be a function
R:282:MessagesHandlerMixIn.list_messages: Too many branches (14/12)
报告部分:
在源代码分析结束后面,会有一系列的报告,每个报告关注于项目的某些方面,如每种类别的 message 的数目,模块的依赖关系等等。具体来说,报告中会包含如下的方面:
检查的 mole 的个数。
对于每个 mole, 错误和警告在其中所占的百分比。比如有两个 mole A 和 B, 如果一共检查出来 4 个错误,1 个错误是在 A 中,3 个错误是在 B 中,那么 A 的错误的百分比是 25%, B 的错误的百分比是 75%。
错误,警告的总数量。
回页首
使用 Pylint 分析 Python 代码的具体示例
下面是一个从 xml 文件中读取一些值并显示出来的一段 Python 代码 dw.py,代码如下:
清单 3. 源码
import string
#!/usr/bin/env python
import xml.dom.minidom
xmlDom=xml.dom.minidom.parse("identity.xml")
organizations = xmlDom.getElementsByTagName('DW')
for org in organizations:
procts = org.getElementsByTagName('linux')
for proct in procts:
print 'ID: ' + proct.getAttribute('id')
print 'Name: ' + proct.getAttribute('name')
print 'Word Count: ' + proct.getAttribute('count')
清单 4. identity.xml 的内容
<IBM>
<DW>
<linux id="100" name="python" count="3000" />
</DW>
</IBM>
这时候使用 Pylint 的结果(这是从 html 格式的输出中拷贝的)为:
清单 5. Pylint 的分析结果
************* Mole dw
C:1:Missing docstring
C:5:Operator not preceded by a space xmlDom=xml.dom.minidom.parse("identity.xml") ^
C:5:Invalid name "xmlDom" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C:6:Invalid name "organizations" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
Report 部分省略
输出中第一部分是源代码分析,第二部分是报告。输出结果中有这么多信息,从哪里开始分析呢?首先使用如下的步骤来分析代码:
1. 因为输出结果太长,所以可以先不让它输出报告部分,先根据源代码分析部分来找出代码中的问题。使用选项 "--reports=n"。
2. 使用选项 "--include-ids=y"。可以获取到源代码分析部分每条信息的 ID。
清单 6. 使用 pylint --reports=n --include-ids=y dw.py 的结果
************* Mole dw
C0111: 1: Missing docstring
C0322: 5: Operator not preceded by a space xmlDom=xml.dom.minidom.parse("identity.xml") ^
C0103: 5: Invalid name "xmlDom" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 6: Invalid name "organizations" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
每个信息前面都会加上一个 id, 如果不理解这个信息的意思,可以通过 pylint --help-msg=id来查看。
清单 7. 使用 pylint --help-msg= C0111 的结果
C0111: *Missing docstring*
Used when a mole, function, class or method has no docstring. Some special
methods like __init__ doesn't necessary require a docstring.
This message belongs to the basic checker.
3. 开始分析每个源代码中的问题。从上面知道,第一个问题的原因是缺少 docstring,在代码中增加 docstring, 修改后的代码如下:
清单 8. 增加 docstring 修改后的源码
#!/usr/bin/env python
"""This script parse the content of a xml file"""
import xml.dom.minidom
xmlDom=xml.dom.minidom.parse("identity.xml")
organizations = xmlDom.getElementsByTagName('DW')
for org in organizations:
procts = org.getElementsByTagName('linux')
for proct in procts:
print 'ID: ' + proct.getAttribute('id')
print 'Name: ' + proct.getAttribute('name')
print 'Word Count: ' + proct.getAttribute('count')
重新运行 pylint --reports=n --include-ids=y dw.py,结果为:
清单 9. 运行结果
************* Mole dw
C0322: 7: Operator not preceded by a space
xmlDom=xml.dom.minidom.parse("identity.xml")
^
C0103: 7: Invalid name "xmlDom" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 8: Invalid name "organizations" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
可以看到源代码中的第一个问题已被解决。
4. 关于第二个 C0322 的问题,这里的分析结果说明得比较清楚,是代码第七行中的等号运算符两边没有空格。我们在这里加上空格,重新运行 pylint --reports=n --include-ids=y dw.py,结果为:
清单 10. 运行结果
************* Mole dw
C0103: 7: Invalid name "xmlDom" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C0103: 8: Invalid name "organizations" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
5.
可以看到现在问题只剩下 C0103 了。这里的意思是变量命名规则应该符合后面正则表达式的规定。Pylint
定义了一系列针对变量,函数,类等的名字的命名规则。实际中我们不一定要使用这样的命名规则,我们可以定义使用正则表达式定义自己的命名规则,比如使用选
项 --const-rgx='[a-z_][a-z0-9_]{2,30}$',我们将变量 xmlDom改为 xmldom, 代码如下:
清单 11. 将变量 xmlDom 改为 xmldom 后的源码
#!/usr/bin/env python
"""This script parse the content of a xml file"""
import xml.dom.minidom
xmldom = xml.dom.minidom.parse("identity.xml")
organizations = xmldom.getElementsByTagName('DW')
for org in organizations:
procts = org.getElementsByTagName('linux')
for proct in procts:
print 'ID: ' + proct.getAttribute('id')
print 'Name: ' + proct.getAttribute('name')
print 'Word Count: ' + proct.getAttribute('count')
运行 pylint --reports=n --include-ids=y --const-rgx='[a-z_][a-z0-9_]{2,30}$' dw.py,结果中就没有任何问题了。
6. 如果希望一个组里的人都使用这些统一的规则,来规范一个部门的代码风格。比如说大家都使用 --const-rgx='[a-z_][a-z0-9_]{2,30}$'作为命名规则,那么一个比较便捷的方法是使用配置文件。
使用 pylint --generate-rcfile > pylint.conf来生成一个示例配置文件,然后编辑其中的 --const-rgx选项。或者也可以直接 pylint --const-rgx='[a-z_][a-z0-9_]{2,30}$' --generate-rcfile > pylint.conf,这样生成的配置文件中 --const-rgx选项直接就是 '[a-z_][a-z0-9_]{2,30}$'了。
以后运行 Pylint 的时候指定配置文件:pylint --rcfile=pylint.conf dw.py
这样 Pylint 就会按照配置文件 pylint.conf中的选项来指定参数。在一个部门中,大家可以共同使用同一个配置文件,这样就可以保持一致的代码风格。
7. 如果把 report 部分加上,即不使用 --reports=n,可以看到报告部分的内容。
㈨ android开发如何调试
能够在eclipse上运行调试应用程序之前,你必须为它创建一个启动项。启动项指定哪个工程将被启动,哪个activity开始工作,以及使用哪些模拟器选项等。
按照以下步骤为Eclipse版本的应用程序创建合适的启动项:
打开启动项管理工具。
在Eclipse 3.3 (Europa)的版本中,酌情选择 Run > Open RunDialog... or Run > Open Debug Dialog... 。
在Eclipse3.4 (Ganymede)版本中,酌情选择 Run > Run Configurations...or Run > Debug Configurations... 。
在左边的工程类型列表选择Android Application选择,双击(或者点击右键选择new),创建一个新的启动项。
输入启动项名称。
在Android标签中,浏览要开始的工程和Activity 。
在Target标签中,设置想要显示的屏幕及网络属性,以及其他任何模拟器启动选项。
你可以在Common标签中设置更多的选项.
按下Apply保存启动配置,或者按下Run或Debug()。
运行和调试应用程序
一旦你设定了工程和工程启动配置,你就可以按照以下的说明运行和调试应用程序了。
从eclipse主菜单,根据情况选择Run>Run 或者 Run>Debug,开始运行或者调试活动启动项。
注意,这里活动启动项是在运行配置管理中最最近一次选中的那个。它不一定就是在Eclipse Navigation 面板中选择的程序(如果有的话)
设置和修改活动启动项,可以使用启动项管理工具。如何获得启动项管理工具可以参考创建一个启动项
运行或调试应用程序将触发以下动作:
启动模拟器,如果他还没有开始运行。
编译工程, 如果在上次编译的基础上修改过代码,将重新编译。在模拟器上安装应用程序。
Run选项,开始运行程序。
Debug 在"Wait for debugger "模式下启动程序,然后打开调试窗口并将Eclipse Java调试器和程序关联。
利用其他IDEs和工具开发Android应用程序
通常我们使用安装有ADT插件的eclipse Eclipse with the ADT plugin.来开发Android程序,这个插件将编辑,build和调试功能集成到IDE上。
然而,如果你想在其他的IDE上开发程序,例如IntelliJ,或者使用没有ADT插件的eclipse也可以。SDK提供了安装,编译,调试应用程序所需要的工具。
创建一个android工程
Android SDK包含一个activityCreator的程序,它将为工程产生多个stub文件和一个build文件。你可以用这个程序创建一个新的 Android工程或者在现有代码上创建工程,如SDK中包含的例子。对于Linux 和Mac系统,SDK提供activityCreator.py,一个 Python脚本,Windows上则是activityCreator.bat一个批处理脚本。无论是哪种平台,用法是一样的。
按以下步骤运行activityCreator创建Android工程:
在命令行下,切换到SDK下的tools/目录下,为你的工程文件新建一个目录。如果你是在现有代码上创建工程,切换到程序的根目录下。
运行activityCreator。在命令行下,你必须指定完全合格的类名作为参数。如果你是创建一个全新的工程,这个类代表的与它同名的stub类和脚本文件。如果是在现有代码上创建工程,必须指定软件包中其中一个Activity类的名称。命令选项的脚本包括:
--out <folder> 设定输出目录。默认情况下输出目录为当前目录。如果你想为工程文件创建一个新的目录,可以使用这个选项来指向它。
--ide intellij, 在一个新的项目中生成IntelliJIDEA 工程文件。
这里有个例子:
~/android_linux_sdk/tools $ ./activityCreator.py --out myprojectyour.package.name.ActivityName
package: your.package.name
out_dir: myproject
activity_name: ActivityName
~/android_linux_sdk/tools $
activityCreator脚本生成以下文件和目录(但是不能重写已有文件):
AndroidManifest.xml 程序的清单文件,同时为工程指定Activity类。
build.xml 一个Ant文件,用来编译/打包应用程序。
src/your/package/name/ActivityName.java 你指定的输入Activity类。
your_activity.iml, your_activity.ipr, your_activity.iws [only with the-ide intelliJ flag] intelliJ工程文件
res/ 资源目录.
src/ 源代码目录.
bin/ build脚本的输出目录.
现在你可以将开发文件夹移到任何地方,但是记住,必须使用tool/文件夹下的adb程序将文件发送到模拟器上。因此你需要在你工作环境和tools/文件夹之间活动。
当然你需要避免移动SDK目录,因为它将打断编译脚本。(再重新build之前需要手动更新SDK的映射路径)
编译 android应用程序
使用activityCreator生成的Ant文件build.xml来编译程序
如果你没有,你可以通过Apache Ant home page得到Ant文件。安装它,并确定它在你的可执行文件路径下。
呼叫Ant之前,你需声明JAVA_HOME环境变量,并将它设置为JDK的安装路径。
注 意:在windows上,JDK默认的安装路径为"ProgramFiles",这个路径将会引起Ant失败,因为路径中间有空格。解决这个问题,你可以像这样指定环境变量 JAVA_HOME:JAVA_HOME=c:\Prora~1\Java\ 然而简单的解决方法是将JDK安装在没有空格的目录下。例如:c:\java\jdk1.6.0_02.
如果你还没有这么准备好,按照上面创建一个新的工程的介绍建立一个工程。
现在你可以为你的工程运行Ant编译文件,只需在build.xml同文件夹下输入ant即可。每次修改原文件或是资源,都需要重新运行ant,它将把最新版的应用程序打包以便deploy.
运行Android程序
运行一个编译好的程序,你需要用adb工具将.apk文件加载到模拟器的/data/app/目录下,用法如下面介绍。
启动模拟器(命令行下运行sdk目录下的/tools/emulator)。
模拟器切换到主画面(最好不要在程序运行的时候向模拟器安装程序,可以按home键离开应用程序)。
运 行adb,安装myproject/bin./<appname>.apk文件。例如,安装Lunar Lander 示例,命令行下,切换到SDK目录下的/sample/LunarLander子目录下,输入../../tools/adbinstall bin/LunarLander.apk
在模拟器中,打开可执行程序列表,卷动屏幕,选中并启动你的应用程序。
注意:当你第一次安装一个Activity时,你可能需要在启动项显示之前,或者其它程序调用它之前重新启动模拟器。因为软件包管理工具通常只有在模拟器启动时才能完全的审查manifests。
为程序附加调试器
这一节我们介绍如何在屏幕上显示调试信息(例如CPU使用率),以及如何将IDE和模拟器上运行的程序关联起来。
使用eclipse插件可以自动的生成调试器。但你也可以通过配置IDES来监听调试端口得到调试信息。
启动Dalvik Debug Monitor Server (DDMS) 工具 ,它在IDE和模拟器之间扮演着端口转换服务的角色。?
设置模拟器调试配置选项。例如,等到调试信息被加载后才启动应用程序。注意,很多调试选项无需DDMS也可以使用,例如模拟器上显示CPU的使用效率,或者屏幕的刷新频率。
配置IDE,使得调试时IDE与8700端口关联 .how to set up Eclipse to debug your project. 包含以下信息。
配置IDE附加调试端口
DDMS将为每一个虚拟机分配一个特殊的调试端口,这个端口在模拟器上可以找到。你必须将你的IDE与此端口(虚拟机上信息栏中有列出这些端口)关联或者是默认的端口8700。这样可以使IDE 连接到模拟器上程序列表中的任一个程序。
你的IDE需要能够关联模拟器上正在运行的程序,显示它的线程,并允许你挂起它,检查它的状态,设置断点。如果你在开发设置面板选择了“等待调试”,应用程序将等到Eclipse连接后才运行,所以你需要在连接之前设置断点。
修改正在调试的程序,或者在当前程序运行时选择“等待调试”将引起系统杀死这个应用程序。如果你的程序处于一种坏的状态,你可以使用方式杀死它,方法很简单,只需要设置和钩掉复选框。
㈩ C++ int i[233];我直接这样写代表了什么意思
C++ int i[233];直接这样写代表了,定义了一个整形的数组,共有233个整形元素,数组的名字叫做i。