Paul Jiang's Blog

  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

软件工程导论-软件危机

发表于 2018-11-06 | 更新于 2020-05-17 | 分类于 管理

产生的问题

软件危机是指在计算机软件的开发和维护过程中所遇到的一系列严重问题。
1.对软件开发成本和进度的估计常常很不准确。
2.用户对“已完成的”软件系统不满意的现象经常发生。
3.软件产品的质量往往靠不住。
4.软件常常是不可维护的。
5.软件通常没有适当的文档资料。
6.软件成本在计算机系统总成本中所占的比例逐年上升。
7.软件开发生成率提高的速度,远远跟不上计算机应用迅速普及深入的趋势。

产生问题的原因

1.与软件本身的特点有关,2.和软件开发与维护的方法不正确有关。
软件是计算机系统中的逻辑部件,软件缺乏“可见性”,软件的质量也较难评价,因此,管理和控制软件开发过程相当困难。
软件是程序、数据及相关文档那个的完整集合。必须充分认识到软件开发不是某种个体劳动的神秘技巧,而应该是一种组织良好、管理严密、各类人员协同配合、共同完成的工程项目。

软件工程的7条基本原理

1.用分阶段的生命周期计划严格管理。不成功的软件项目中有一半是由于计划不周造成的。
2.坚持进行阶段评审。
3.实行严格的产品控制。
4.采用现代程序设计技术。
5.结果应能清楚地审查。
6.开发小组的人员应该少而精。
7.承认不断改进软件工程实践的必要性。

传统方法学和面向对象方法学。

传统方法学采用结构化技术来完成软件开发的各项任务,并使用适当的软件工具或软件工程环境来支持结构化技术的运用。强调自顶向下顺序地完成软件开发的各阶段任务。这种技术要么面向行为,要么面向数据。
面向对象方法是一个主动地多次反复迭代的演化过程。面向对象方法把数据和行为看成是同等重要的。

软件生命周期

软件生命周期由软件定义、软件开发和运行维护。
软件定义:问题定义、可行性研究、需求分析。
软件开发:总体设计、详细设计、编码、单元测试、综合测试。
运行维护。

LoadRunner-介绍

发表于 2018-11-06 | 更新于 2020-05-17 | 分类于 测试
  • 基于底层的通信协议
  • 覆盖广泛(将近50种协议)
  • 无代理监测
  • 深层诊断
  • 深层挖据客户端到web服务,web服务到应用服务,应用服务到数据库服务的各个时间段响应时间。

用途:

压力测试
容量规划
硬件选型

模块

  1. 虚拟用户生成器
  2. Controller
  3. Analysis

操作流程:

  1. Vugen:生成脚本
  2. Controller:起到调度压力测试并管理监控器
  3. Load Generators:模拟大量真实用户的产生
  4. 性能监控器(利用系统已有的软件实现无代理windows performance等等)
  5. Analysis

测试步骤

1. 测试计划

业务流程
输入
环境(监控)

2. 创建脚本

录制

建议:录制->基于URL的脚本

回放
增强功能

  • 事务(持续时间)
  • 参数化:唯一性;数据依赖;日期约束;数据缓存(绕过数据库等缓存机制,测试更具真实性)
  • 验证:文本检查(web_reg_find)
  • 关联:
    比如SessionID
    录制时12345,回放时就变成45678,导致服务器认为是不同的用户
    解决方案
    将sessionID关联起来,保存到一个临时参数中,需要时读取出来

    3. 设计场景

    1.手工场景
    2.目标场景

    4. 执行场景

    单个场景
    混合类场景
  • 第一次:3~5个虚拟用户
    增强日志
    无思考时间
  • 第二次:20%
    标准日志
    5秒思考时间
  • 第三次:100%
    出错日志
    思考时间随机
  • 第四次:100%++

    5. 收集分析

    6. 继续执行第4步

LoadRunner自带测试Demo账号密码
账号:jojo
密码:bean

Selenium-介绍

发表于 2018-11-06 | 更新于 2020-05-17 | 分类于 测试

Selenium
IE-Driver
Selenium RC

UNIX环境高级编程-UNIX标准化

发表于 2018-11-04 | 更新于 2020-05-17 | 分类于 操作系统

20世纪80年代UNIX版本的剧增以及它们之间差别的扩大,导致很多大用户(例如美国政府)呼吁对其进行标准化。所有标准化工作的一个重要部分是对每种实现必须定义的各种限制进行说明。

UNIX标准化

ISO C

ISO C标准的意图是提供C程序的可移植性,使其能适合于大量不同的操作系统,而不只是UNIX系统。此标准不仅定义了C程序设计语言的语法和语义,还定义了其标准库。因为所有现今的UNIX系统都提供C标准中定义库例程,所以该标准库是很重要的。
如同大多数标准一样,在批准标准和修改软件以使其符合标准这两者之间有一段时间上的延迟。随着供应商的编译系统不断眼睛,对ISO C标准最新版本的支持也越来越多。

gcc对ISO C标准1999版本的当前符合程度的总结可见:http://www.gnu.org/software/gcc/c99status.html

按照该标准定义的各个头文件,可将ISO C库分成24个区。

头文件 FreeBSD 5.2.1 Linux 2.4.22 Mac OS X 10.1 Solaris 说明
assert.h x x x x 验证程序断言
complex.h x x x 支持复数算数运算
ctype.h x x x x 字符类型
errno.h x x x x 出错码
fenv.h x x 浮点环境
float.h x x x x 浮点常量
inttypes.h x x x x 整形格式转换
iso646.h x x x x 替代关系操作符宏
limits.h x x x x 实现常量
locale.h x x x x 局部类别
math.h x x x x 数学常量
setjmp.h x x x x 非局部goto
signal.h x x x x 信号
stdarg.h x x x x 可变参数表
stdbool.h x x x x 布尔类型和值
srddef.h x x x x 标准定义
stdint.h x x x 整型
stdio.h x x x x 标准I/O库
stdlib.h x x x x 实用程序函数
string.h x x x x 字符串操作
tgmath.h x 通用类型数学宏
time.h x x x x 时间和日期
wchar.h x x x x 扩展的多字节和宽字符支持
wctype.h x x x x 宽字符分类和映射支持

ISO C头文件依赖于操作系统所配置的C编译器版本。FreeBSD 5.2.1配置了gcc 3.3.3版,Solaris 9同时配置了gcc 2.95.3版和gcc 3.2版,Mandrate 9.2 (Linux 2.4.22)配置了gcc 3.3.1版,Mac OS X配置了gcc 3.3版。Mac OS X还包括了gcc的较早版本。

IEEE POSIX

POSIX是一系列由IEEE制定的标准。POSIX指的是可移植的操作系统接口(Portable Operating System)。它原来指的只是IEEE标准1003.1-1988(操作系统接口),后来则扩展成包括很多标记为1003的标准及标准草案,包括shell和实用程序。
该标准的目的是提高应用程序在各种UNIX系统环境之间的可以执行。它定义了“依从POSIX的”(POSIX compliant)操作系统必须提供的各种服务。
由于1003.1标准定义了一个接口而不是一种实现,所以并不区分系统调用和库函数。标准中的所有例程都称为函数。
标准是不断演变的,1003.1标准也不例外。该标准的1988版,即IEEE 1003.1-1988经修改后提交给ISO。最终的文档作为IEEE Std.1003.1-1990正式出版,这也就是国际标准ISO/IEC 9945-1:1990。该标准通常被称为POSIX.1。
1003.1的2001版与以前各版本有较大的差别,它组合了1003.1的多次修订、1003.2标准以及Single UNIX Specification第2版的若干部分,最终形成了IEEE标准1003.1-2001,其中包括了下列借个标准。

  • ISO/IEC 9945-1(IEEE标准1003.1-1996),它包括

    1. IEEE标准1003.1-1990。
    2. IEEE标准1003.1b-1993(实时扩展)。
    3. IEEE标准1003.1c-1995(pthreads)。
    4. IEEE标准1003.1i-1995(实时技术勘误表)。
  • IEEE P1003.1a标准草案(系统接口修订版)。

  • IEEE标准1003.1d-1999(高级实时扩展)。
  • IEEE标准1003.1j-2000(更高级实时扩展)。
  • IEEE标准1003.1q-2000(文件跟踪)。
  • IEEE标准1003.2d-1994(批处理扩展)。
  • IEEE P1003.2b草案标准(附加的使用程序)。
  • IEEE标准 1003.1g-2000(协议无关接口)的某些部分。
  • ISO/IEC 9945-2(IEEE标准1003.2-1993)。
  • Single UNIX Specification第2版本的基本规范,包括

    1. 系统接口定义,第5发行版。
    2. 命令和使用程序,第5发行版。
    3. 系统接口和头文件,第5发行版。
  • 开放组技术标准,网络服务,5.2发行版。

  • ISO/IEC 9899:1999,C编程语言。

POSIX.1标准现有Austin Group(http://www.opengroup.org/austin)的开放工作组维护。为了保证它们与实际需求吻合,仍需经常对这些标准进行更新或再修订。

Single UNIX Specification

Single UNIX Specification(单一UNIX规范)是POSIX.1标准的一个超集,定义了一些附加的接口,这些接口扩展了基本的POSIX.1规范所提供的功能。相应的系统接口全集被称为X/Open系统接口。_XOPEN_UNIX符号常量表示了XSI扩展的几口。
XSI还定义了实现必须支持POSIX.1的哪些可选部分才能认为是遵循XSI的。它们包括文件同步、存储映射文件、存储保护及线程接口。只有遵循XSI的实现才能称为UNIX系统。

FIPS

FIPS的含义是联邦信息处理标准。它有美国政府出版,用于计算机系统的采购。FIPS 151-1(1989年4月)基于IEEE标准1003.1-1988及ANSI C标准草案。
POSIX.1 FIPS的影响是:它要求任何希望向美国政府销售POSIX.1兼容的计算机系统的厂商应支持POSIX.1的某些可选功能。

窗口与消息

发表于 2018-11-04 | 更新于 2020-05-17 | 分类于 客户端

1.定义WNDCLASS窗口类

2.通过RegisterClass注册窗口。

3.窗口的创建。通过CreateWindow创建窗口

4.窗口的显示。通过ShowWindow将窗口显示在屏幕上,UpdateWindow使窗口客户区重绘。

5.消息循环。GetMessage函数用于从消息对立中对消息进行检索。TranslateMessage返还给Windows以进行某些键盘消息的转换。DispatchMessage再次返还给Windows,截下来Windows会将这条消息发送给合适的窗口过程来处理。

6.窗口过程。窗口过程WndProc接收消息并进行处理

队列消息和非队列消息

消息可以是队列消息,也可以是非队列消息。队列消息是指那些由Windows放入程序的消息队列中的消息。而非队列消息则是由Windows对窗口过程的直接调用而产生的。

队列消息主要由用户的输入产生,比如按键消息等。

非队列消息包括队列消息以外的其他所有消息。通常由调用特定的Windows函数引起。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// testWin32.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "testWin32.h"

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名

// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;

// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TESTWIN32, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTWIN32));

// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int) msg.wParam;
}



//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TESTWIN32));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TESTWIN32);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassEx(&wcex);
}

//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // 将实例句柄存储在全局变量中

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}

操作系统概念-线程

发表于 2018-11-04 | 更新于 2020-05-17 | 分类于 操作系统

线程是CPU调度的基本单元,它由线程ID、程序计数器、寄存器集合和栈组成。
操作系统提供的线程支持包括用户层的用户线程和内核层的内核线程。
用户线程和内核线程之间存在着三种常见的关系:

  1. 多对一模型
    多个用户线程映射到一个内核线程。
    缺点是如果一个相称阻塞了系统调用,那么整个进程都会被阻塞。

  2. 一对一模型
    一个用户线程映射到一个内核线程。
    缺点是创建内核线程的开销会影响到应用程序的性能。

  3. 多对多模型
    线程库提供了创建和管理线程的API。
    目前主要的三种线程库是:1.POSIX Phread;2.Win32;3.Java。
    由于Java是运行在虚拟机上的,通常都是调用虚拟机的宿主操作系统上的线程库。

UNIX环境高级编程-UNIX系统实现

发表于 2018-11-04 | 更新于 2020-05-17 | 分类于 操作系统

实现

标准只是接口的规范。这些标准由制造商采用,然后转变成具体实现。
UNIX的各种版本和变体都起源于在PDP-11系统上运行的UNIX分时系统第6版和第7版。这两个版本是在贝尔实验室意外首先得到广泛应用的UNIX系统。从树上演变出三个分支:

  1. AT&T分支,从此到处了系统III和系统V。
  2. 加州大学伯克利分校分支,从此到处4.xBSD实现。
  3. 由AT&T贝尔实验室的计算科学研究中心开发的UNIX研究版本,从此到处UNIX分时系统第8、第9版以及于1990年发布的最后一版第10版。

限制

UNIX系统实现定义了很多幻数和常量,其中有很多已被硬编码进程序中,或用特定的技术确定。由于大量标准化工作的努力,已有若干种可移植的方法用以确定这些幻数和实现定义的限制。这非常有助于软件的可移植性。
以下两种类型的限制是必需的:

  1. 编译时限制(例如,短整型的最大值是什么?)。
  2. 运行时限制(例如,文件名可以有多少个字符?)。

编译时限制可在头文件中定义,程序在编译时可以包含这些头文件。但是,运行时限制则要求进程调用一个函数以获得此种限制值。
另外,某些限制在一个给定的实现中可能是固定的,而在另一个实现上则可能是变化的。这类限制的一个例子是文件名的最大字符数。文件名的最大长度依赖于该文件处于何种文件系统中,例如,根文件系统中的文件名长度限制可能是14个字符,而在另一个文件系统中文件名长度限制可能是255个字符,这是运行时限制的一个例子。
为了解决这类问题,提供了一下三种限制:

  1. 编译时限制
  2. 不与文件或目录相关联的运行时限制(sysconf函数)
  3. 与文件或目录相关联的运行时显示(pathconf和fpathconf函数)

冲突

就整体而言,这些不同的标准之间配合的相当好。但是我们也很关注它们之间的差别,特别是ISO C标准和POSIX.1之间的差别。
有一个相同的术语,即每秒钟滴答数,但ISO C和POSIX.1的定义却不懂,在Solaris中看到,其中clock返回微秒数(因此,CLOCK_PER_SEC是一百万),而sysconf为每秒钟的滴答数返回的值是100。
另一个可能产生冲突的领域是:在ISO C标准定义函数时,可能没有考虑到POSIX.1的某些要求。在POSIX环境下,有些函数可能要求有一个与C环境下不同的实现,因为POSIX环境中多个进程,而ISO C环境则很少考虑主机操作系统。

Unicode

发表于 2018-11-04 | 更新于 2020-05-17 | 分类于 客户端

Unicode

Unicode是ASCII字符编码的一个扩展。Unicode用的是16位字符编码。

0x0000-0x007F:ASCII码

0x0080-0x00FF:ISO 8859-1 ASCII扩展码

char和宽字符

char *p = “Hello”;

wchar_t *pW = L”Hello”;

大写的字母L(表示长整型),这向编译器表明这个字符串将用宽字符存储。

TCHAR.H

宽字符运行库函数比正常的函数要大。为此你可能希望创建另个版本的程序,一个用ASCII字符串而另一个使用Unicode字符串。而最好的办法则是维护一个单一的源代码文件,但可以编译成ASCII或Unicode。

但这是有问题的,因为运行库函数具有不同名称,字符变量的定义也不同。

一个答案是使用包含在Microsoft Visual C++中的TCHAR.H头文件。这个头文件并不是ANSI C标准的一部分,所以其中的每一个函数和宏都有一个下划线前缀。TCHAR.H为那些需要字符串参数的普通运行库函数提供了一系列 的替代名称。这些函数有时被称为“通用”的函数名字,因为它们可以指Unicode或非Unicode版本的函数。

如果一个命名为_UNICODE的标识符被定义了并且TCHAR.H头文件被包含在你的程序中

#define _tcslen wcslen

如果_UNICODE没有被定义

#define _tcslen strlen

同样,_UNICODE定义

typedef wchar_t TCHAR

_UNICODE没有被定义

typedef char TCHAR

深入分析GCC

发表于 2018-11-04 | 更新于 2020-05-17 | 分类于 操作系统

UNIX环境高级编程-文件IO

发表于 2018-11-04 | 更新于 2020-05-17 | 分类于 操作系统

UNIX系统中的大多数文件IO只需要用到5个函数:open,read,write,lseek,close。
这5个函数通常被称为不带缓冲的IO(unbuffered io),每个read和write都调用内核中的一个系统调用。

1
2
3
4
5
int open(const char *pathname, int oflag, ... /* mode_t mode*/);
int close(int filedes);
off_t lseek(int filedes, off_t offset, int whence);
ssize_t read(int filedes, void *buf, size_n nbytes);
ssize_t write(int filedes, const void *buf, size_t nbytes);

IO效率

1…161718…22

Paul Jiang

212 日志
26 分类
26 标签
Links
  • 褚霸
  • 章亦春
  • Martin Fowler
© 2020 Paul Jiang
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Gemini v6.5.0