QTP

1.QTP Sample 登录测试脚本:

Dim istatus
Dim text1
For i=1 to DataTable.GetSheet(“Action1”).GetRowCount ‘循环Action1 Sheet 里面的数据
SystemUtil.Run “C:\Program Files\HP\QuickTest Professional\samples\flight\app\flight4a.exe”
Dialog(“Login”).WinEdit(“Agent Name:”).Set DataTable.GetSheet(“Action1”).GetParameter(“name”).ValueByRow(i)’DataTable(“name”, “Action1”)’dtGlobalSheet
Dialog(“Login”).WinEdit(“Password:”).SetSecure DataTable.GetSheet(“Action1”).GetParameter(“pwd”).ValueByRow(i) 
istatus=DataTable.GetSheet(“Action1”).GetParameter(“status”).ValueByRow(i)
Dialog(“Login”).WinButton(“OK”).Click
If Dialog(“Flight Reservations”).Exist Then ‘判断第三方界面是否存在,即错误警告界面

if Dialog(“Flight Reservations”).Static(“Agent name must be at least 4 characters long.”).Exist Then
text1=Dialog(“Flight Reservations”).Static(“Agent name must be at least 4 characters long.”).GetROProperty(“Text”)

elseif Dialog(“Flight Reservations”).Static(“Incorrect password. Please”).GetROProperty(“Text”).Exist then
text1=Dialog(“Flight Reservations”).Static(“Incorrect password. Please”).GetROProperty(“Text”) ‘存在获取界面的Text值赋予text1

elseif Dialog(“Flight Reservations”).Static(“Password must be at least 4 characters long”).Exist then
text1=Dialog(“Flight Reservations”).Static(“Password must be at least 4 characters long”).GetROProperty(“Text”)
elseif Dialog(“Flight Reservations”).Static(“Please enter agent name”).Exist then
text1=Dialog(“Flight Reservations”).Static(“Please enter agent name”).GetROProperty(“Text”)
else Dialog(“Flight Reservations”).Static(“please enter password”).Exist
text1=Dialog(“Flight Reservations”).Static(“please enter password”).GetROProperty(“Text”)
End If

If text1=istatus then ‘如果Text是预期结果的值,打印text1
Reporter.ReportEvent micPass,DataTable.GetSheet(“Action1”).GetParameter(“case”).ValueByRow(i),DataTable.GetSheet(“Action1”).GetParameter(“status”).ValueByRow(i)
else
Reporter.ReportEvent micFail,”异常”,text1 ‘ 否则异常
end if
wait(2) ‘可有可无
Dialog(“Flight Reservations”).WinButton(“确定”).Click ‘关掉错误警告界面
Dialog(“Login”).WinButton(“Cancel”).Click ‘关掉本次登录界面,便于下一个循环
else
Reporter.ReportEvent micPass,DataTable.GetSheet(“Action1”).GetParameter(“status”).ValueByRow(i),DataTable.GetSheet(“Action1”).GetParameter(“case”).ValueByRow(i)
Window(“Flight Reservation”).Close
End If

Next

‘ For i=1 to DataTable.GetSheet(“Action1”).GetRowCount
‘ DataTable.setCurrentRow(i)
‘ DataTale.Raw(“columnname,”Action1”);

脚本下载地址 http://dl.dbank.com/c01dbcjxya

Advertisements

javascript 对象不支持此属性或方法

对象不支持此属性或方法
2010年01月19日 星期二 下午 03:38
经历一:
调用JS时出现 “对象不支持此属性或方法”

Html代码 复制代码
  1. <a href=“#” class=“” onclick=“selectSeat()”><img                   src=“../../images/icon_ok.gif” align=“absmiddle”>选座位</a>

明明JS中有定义selectSeat(),却老是提示
对象不支持此属性或方法

后得知是因为名字重复的原因,将function selectSeat()改为chooseSeat()问题解决。

记下来,下次勿再为此所扰

经历二:
也是提示这个错误,说什么也找不到错误的原因;后来看到一个function和页面某元素的id/name重名,改为不一样后,问题没了。结论:
不要把js函数名和页面元素名命名为相同的名称,否则会产生不可预料的错误。

经历三:

<input type=”button” name=”submit” value=”修改” onclick=”empty();”>

当name写的submit的时候出现:对象不支持此属性或方法。改成button,就没有事了。

<input type=”button” name=”button” value=”修改” onclick=”empty();”>

Oracle 问题集

1. 导入dump文件:

imp user/pass@ORCL full=y file=”文件位置.dmp” ignore=y

2. ora-01536:超出表空间“users”的空间限额:

alter user 你的用户名 quota unlimited on 你建表的表空间的名字;

3.修改IP后Oracle 无法使用

emca -config dbcontrol db

How to restore Grub 2 after reinstalling Windows XP/Vista/Win7

How to restore Grub 2 after reinstalling Windows XP/Vista/Win7

THIS POST WAS WRITTEN BY ADMIN ON OCTOBER 20, 2009
POSTED UNDER: GENERAL

After reinstalling Windows in the computer dual boot with both Windows and Ubuntu Linux,you need restore grub because mbr has been rewritten.This tutorial shows how to restore grub 2.

Update:Today I ghost my XP system,but after restore grub,I cannot boot into XP by clicking the old windows option in grub menu.So you’d better to run this command to renew the grub2 boot list after trying following method:

sudo update-grub

1).Using grub4dos
First download grub4dos from here.
1. For XP user,copy the file “grldr”(without quotes) from grub4dos package to C:\.Editboot.ini (hidden file in C:\) and add this line to the file:

c:\grldr="grub4dos"

For Vista/win7 user,copy the file “grldr”,”grldr.mbr” to C:\.Create boot.ini file in the root directory of C:,copy and paste following into this file.

[boot loader]
timeout=0
default=c:\grldr.mbr
[operating systems]
C:\grldr.mbr="Grub4Dos"

2. Now,create menu.lst in root directory of C:,its content:

timeout 0
default 0
title grub2
find --set-root /boot/grub/core.img
kernel /boot/grub/core.img
boot

Restart computer,and select boot from Grub4Dos.Then select boot up Ubuntu in grub menu.
Once login,use this command to install grub into mbr:

sudo grub-install /dev/sda

2).Using Ubuntu 9.10 livecd or higher(My Choice)
Here assuming the Ubuntu partition is sda7,and /boot partition is sda6 (if you have a separate /boot partition).
Boot up ubuntu from the livecd,open terminal and run:

sudo -i
mount /dev/sda7 /mnt
mount /dev/sda6 /mnt/boot  #skip this one if not have a separate /boot partition
grub-install --root-directory=/mnt/ /dev/sda

If you miss “grub.cfg” file,use following to recreate:

mount --bind /proc /mnt/proc
mount --bind /dev /mnt/dev
mount --bind /sys /mnt/sys
chroot /mnt update-grub
umount /mnt/sys
umount /mnt/dev
umount /mnt/proc
exit

3).Using the cd/usb boot up with grub
Boot up the cd/usb,press c in grub menu.Type:

grub>find /boot/grub/core.img
grub>root (hdx,y)   (previous command will output the x,y)
grub>kernel /boot/grub/core.img
grub>boot

After the boot command,you’ll go into grub2 menu.Select to boot up ubuntu,and run this command to restore grub:

sudo grub-install /dev/sda

(FROM http://ubuntuguide.net/how-to-restore-grub-2-after-reinstalling-windows-xpvistawin7)

新浪微博OAuth认证详解及验证数据储存

新浪微博OAuth认证详解及验证数据储存

网上很多关于OAuth的文章,但是包括sina本身都都没有详细的的介绍,包括验证过程和验证后数据的储存,所以参考了Twitter的认证过程写下一些详细的注释代码。

在我们开始前,我们先建立一张数据库来保存用户信息,下面是一个基本的 Mysql 的例子:

1
2
3
4
5
6
7
8
9
CREATE TABLE `oauth_users` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `oauth_provider` VARCHAR(10),
    `oauth_uid` text,
    `oauth_token` text,
    `oauth_secret` text,
    `username` text,
    PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

注意 oauth_token 和 oauth_secret 这两个字段。sina的 OAuth 认证需要 token 和 token_secret 两个参数来完成认证,所以我们需要预留两个字段来记录他们。

然后我们需要依次完成以下工作:

向 SinaAPI发起认证申请
注册/或者登录,如果用户已经有帐号的情况下
将相关数据保存在 Session 中

基于 OAuth 的认证流程从生成一个网址开始。用户被重定向到该网址要求认证,认证通过后,会重定向到我们的应用服务器,并会将两个认证后的参数通过 URL 方式传回。

建立index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
session_start();
//if( isset($_SESSION['last_key']) ) header("Location: weibolist.php");
include_once( 'config.php' );
include_once( 'weibooauth.php' );
// 创建 sinaOAuth 对象实例
$sinaOAuth = new WeiboOAuth( WB_AKEY , WB_SKEY  );
$keys = $sinaOAuth->getRequestToken();
// Requesting authentication tokens, the parameter is the URL we will be redirected to
$aurl = $sinaOAuth->getAuthorizeURL( $keys['oauth_token'] ,false , 'http://t.yourtion.com/sina/callback.php');
// 保存到 session 中
$_SESSION['keys'] = $keys;
?>
<a href="<?=$aurl?>">Use Oauth to login</a>

接下来,我们还需要在这个文件中完成以下三件事:

验证 URL 中的数据
验证 Session 中的 token 数据
验证 Session 中的 secret 数据

如果所有数据库都是合法的,我们需要创建一个新的 SinaOAuth 对象实例,跟之前不同的是,我们要把获取到的 token 数据做为参数传入对象。之后,我们应该可以获取到一个 access token,这个获取到的数据应该是一个数组,这个 access token 是我们唯一需要保存起来的数据。

建立callback.php

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
<?php
session_start();
include_once ('config.php');
include_once ('weibooauth.php');
if (!empty($_GET['oauth_verifier']) && !empty($_SESSION['keys']['oauth_token']) &&
    !empty($_SESSION['keys']['oauth_token']))
{
    // SinaOAuth 对象实例,注意新加入的两个参数
    $sinaOAuth = new WeiboOAuth(WB_AKEY, WB_SKEY, $_SESSION['keys']['oauth_token'],
        $_SESSION['keys']['oauth_token_secret']);
    // 获取 access token
    $access_token = $sinaOAuth->getAccessToken($_REQUEST['oauth_verifier']);
    // 将获取到的 access token 保存到 Session 中
    $_SESSION['access_token'] = $access_token;
    // 获取用户信息
    $user_info = $sinaOAuth->get('account/verify_credentials');
    // 打印用户信息
<div id="_mcePaste">   mysql_connect(DATABASE_HOST, DATABASE_USER, DATABASE_PSSWORD);</div>
<div id="_mcePaste">   mysql_select_db(DATABASE_DB_NAME);</div>
//更换成你的数据库连接,在config.php中
    if (isset($user_info->error) or empty($user_info['id']))
    {
        // Something's wrong, go back to square 1
        header('Location: index.php');
    } else
    {
        // Let's find the user by its ID
        $sql = "SELECT * FROM oauth_users WHERE oauth_provider='sina' AND oauth_uid=" .$user_info['id'];
        $query = mysql_query($sql);
        $result = mysql_fetch_array($query);
        // If not, let's add it to the database
        if (empty($result))
        {
            $sql = "INSERT INTO oauth_users (oauth_provider, oauth_uid, username, oauth_token, oauth_secret) VALUES ('sina', '" .
                $user_info['id'] . "', '" . $user_info['screen_name'] . "', '" . $access_token['oauth_token'] .
                "', '" . $access_token['oauth_token_secret'] . "')";
            $query = mysql_query($sql);
            $query = mysql_query("SELECT * FROM oauth_users WHERE id = ".mysql_insert_id());
            $result = mysql_fetch_array($query);
        } else
        {
            // Update the tokens
            $query = mysql_query("UPDATE oauth_users SET oauth_token = '" . $access_token['oauth_token'] .
                "', oauth_secret = '" . $access_token['oauth_token_secret'] .
                "' WHERE oauth_provider = 'sina' AND oauth_uid = " . $user_info['id']);
        }
        $_SESSION['id']=$result['id'];
        $_SESSION['username']=$result['username'];
        $_SESSION['oauth_uid']=$result['oauth_uid'];
        $_SESSION['oauth_provider']=$result['oauth_provider'];
        $_SESSION['oauth_token']=$result['oauth_token'];
        $_SESSION['oauth_secret']=$result['oauth_secret'];
        header('Location: update.php');
    }
} else
{
    // 数据不完整,转到上一步
    header('Location: index.php');
}
?>

你可以通过 $user_info->id 来获得用户的 ID,通过 $user_info->screen_name 来获取用户名,等等,其它的信息也可以通过同样的方式获取。

需要重点指出的是,oauth_verifier 这个传回来的参数不能被重用,如果上面的代码已经正确输出了用户信息,你可以试着重新刷新页面,应该会看到页面会抛出一个错误信息,因为 oauth_verifier 已经被我们用过一次了。要再次使用,需要到 index.php 页面重新发起一个认证请求。

用户注册

获得了用户信息后,现在我们要开始把用户信息注册到我们自己的数据库中,当然前提是用户没有在本地数据库注册过。

上面代码中的数据库链接信息要改成你自己的。如果用户已经存在于我们的数据库中,我们需要更新用户的 tokens 字段,因为这说明 Twitter 生成了新的 tokens,数据库中的 tokens 已经过期了。如果用户不存在,我们需要新加一条记录,并将相关的数据保存在 Session中,最后重定向回 update.php 页面。update.php代码如下:

需要注意的是,上面代码中的 SQL 没有经过验证,你在实际使用的时候可能要经过修改。连接数据库前,我们需要先验证一下用户是否已经登录。有了用户名,我们就可以展示一条个性的欢迎信息了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
include_once ('config.php');
include_once ('weibooauth.php');
session_start();
if(!empty($_SESSION['username'])){
    // User is logged in, redirect
    header('index.php');
}
?>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="zh-CN">
<head profile="http://gmpg.org/xfn/11">
    <title>通过 OAuth 进行身份验证--Yourtion</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
<h2>Hello <?=$_SESSION['username'] ?></h2>
</body>
</html>

这就是OAuth认证和储存的主要过程,希望对你有帮助。
代码下载:SinaOauth

(From  http://blog.yourtion.com/?p=1837)

OAuth

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。

OAuth是OpenID的一个补充,但是完全不同的服务。

认证和授权过程

在认证和授权的过程中涉及的三方包括:

  • 服务提供方,用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。
  • 用户,存放在服务提供方的受保护的资源的拥有者。
  • 客户端,要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站。在认证过程之前,客户端要向服务提供者申请客户端标识。

使用OAuth进行认证和授权的过程如下所示:

  1. 用户访问客户端的网站,想操作用户存放在服务提供方的资源。
  2. 客户端服务提供方请求一个临时令牌。
  3. 服务提供方验证客户端的身份后,授予一个临时令牌。
  4. 客户端获得临时令牌后,将用户引导至服务提供方的授权页面请求用户授权。在这个过程中将临时令牌和客户端的回调连接发送给服务提供方
  5. 用户服务提供方的网页上输入用户名和密码,然后授权该客户端访问所请求的资源。
  6. 授权成功后,服务提供方引导用户返回客户端的网页。
  7. 客户端根据临时令牌从服务提供方那里获取访问令牌。
  8. 服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌。
  9. 客户端使用获取的访问令牌访问存放在服务提供方上的受保护的资源。

(From http://zh.wikipedia.org/wiki/OAuth)

5.png

twitter或豆瓣用户一定会发现,有时候,在别的网站,点登录后转到 twitter登录,之后转回原网站,你会发现你已经登录此网站了,比如像feedtwitterrss2twitter推特中文圈(这个目前好像有点问题转回来的时候是个错误地址) 这种网站就是这个效果。其实这都是拜 OAuth所赐。

OAuth是什么?

OAuth是一个开放的认证协议,让你可以在Web或桌面程序中使用简单而标准的,安全的API认证。

OAuth有什么用?为什么要使用OAuth?

网络开放是一个不变的趋势,那么不可避免的会有各种网络服务间分享内容的需要。

举个我们身边国内的例子吧:比如人人网想要调用QQ邮箱的联系人列表,现在的方法是你需要在人人网输入你的QQ号,QQ密码才能调用,虽然网站上可能都自谓“不保留QQ用户名密码”,但是大家信吗?

OAuth就是为了解决这个问题而诞生的,用户访问第三方资源,不再需要网站提交你的用户名,密码。这样好处自己是安全,而且不会泄露你的隐私给不信任的一方。

OAuth原理

OAuth中有三方:一,用户;二,Consumer(不知杂翻译,类似上面的 twitterfeed 角色);三,服务提供商(如上例的twitter角色)。

一,Consumer 向 服务提供商 申请接入权限

可得到:Consumer Key,Consumer Secret。twitter申请oauth的话,在 setting – connection – developer 里面申请。 同时给出三个访问网址:

  1. request_token_url = ‘http://twitter.com/oauth/request_token&#8217;
  2. access_token_url = ‘http://twitter.com/oauth/access_token&#8217;
  3. authorize_url = ‘http://twitter.com/oauth/authorize&#8217;

二,当Consumer接到用户请求想要访问第三方资源(如twitter)的时候

Consumer需要先取得 请求另牌(Request Token)。网址为上面的 request_token_url,参数为:

  1. oauth_consumer_key:Consumer Key
  2. oauth_signature_method:签名加密方法
  3. oauth_signature:加密的签名 (这个下面细说)
  4. oauth_timestamp:UNIX时间戳
  5. oauth_nonce:一个随机的混淆字符串,随机生成一个。
  6. oauth_version:OAuth版本,可选,如果设置的话,一定设置为 1.0
  7. oauth_callback:返回网址链接。
  8. 及其它服务提供商定义的参数

这样 Consumer就取得了 请求另牌(包括另牌名 oauth_token,另牌密钥 oauth_token_secret。

三,浏览器自动转向服务提供商的网站:

网址为 authorize_url?oauth_token=请求另牌名

四,用户同意 Consumer访问 服务提供商资源

那么会自动转回上面的 oauth_callback 里定义的网址。同时加上 oauth_token (就是请求另牌),及 oauth_verifier(验证码)。

五,现在总可以开始请求资源了吧?

NO。现在还需要再向 服务提供商 请求 访问另牌(Access Token)。网址为上面的 access_token_url,参数为:

  1. oauth_consumer_key:Consumer Key
  2. oauth_token:上面取得的 请求另牌的名
  3. oauth_signature_method:签名加密方法
  4. oauth_signature:加密的签名 (这个下面细说)
  5. oauth_timestamp:UNIX时间戳
  6. oauth_nonce:一个随机的混淆字符串,随机生成一个。
  7. oauth_version:OAuth版本,可选,如果设置的话,一定设置为 1.0
  8. oauth_verifier:上面返回的验证码。
  9. 请求 访问另牌的时候,不能加其它参数。

这样就可以取得 访问另牌(包括Access Token 及 Access Token Secret)。这个就是需要保存在 Consumer上面的信息(没有你的真实用户名,密码,安全吧!)

六,取得 访问另牌 后,

Consumer就可以作为用户的身份访问 服务提供商上被保护的资源了。提交的参数如下:oauth_consumer_key:Consumer Key

  1. oauth_token:访问另牌
  2. oauth_signature_method:签名加密方法
  3. oauth_signature:加密的签名 (这个下面细说)
  4. oauth_timestamp:UNIX时间戳
  5. oauth_nonce:一个随机的混淆字符串,随机生成一个。
  6. oauth_version:OAuth版本,可选,如果设置的话,一定设置为 1.0
  7. 及其它服务提供商定义的参数

OAuth安全机制是如何实现的?

OAuth 使用的签名加密方法有 HMAC-SHA1,RSA-SHA1 (可以自定义)。拿 HMAC-SHA1 来说吧,HMAC-SHA1这种加密码方法,可以使用 私钥 来加密 要在网络上传输的数据,而这个私钥只有 Consumer及服务提供商知道,试图攻击的人即使得到传输在网络上的字符串,没有 私钥 也是白搭。

私钥是:consumer secret&token secret  (哈两个密码加一起)

要加密的字符串是:除 oauth_signature 外的其它要传输的数据。按参数名字符排列,如果一样,则按 内容排。如:domain=kejibo.com&oauth_consumer_key=XYZ&word=welcome………………….

前面提的加密里面都是固定的字符串,那么攻击者岂不是直接可以偷取使用吗?

不,oauth_timestamp,oauth_nonce。这两个是变化的。而且服务器会验证一个 nonce(混淆码)是否已经被使用。

那么这样攻击者就无法自已生成 签名,或者偷你的签名来使用了。

(From http://kejibo.com/oauth/)

 

OAuth_Authentication_Flow

(From http://home.open-open.com/space-361-do-blog-id-3342.html)

左翼 ?右翼?

(百度百科)

左翼和右翼政治观点的区别,表现哲学观、历史观上,也表现在对经济的政策上,
表现在变革与保守上。严格说来左翼和右翼是民主政体下的两个派别,是两党制的
渊源,是自由主义的两个群体,而专制政体下是不存在这两个派别的,所以左翼和
右翼是民主政治的概念。

在哲学观、历史观上,左翼一般认为历史是人民创造的,信奉“小民史观”,其政治主张
是偏向下层人民,草根阶层的。左翼反对贫富悬殊,追求社会公平和“均贫富”,认为贫困
是由于“不公正”而造成的,国家、社会应对个人的不幸负责。左翼梦想一个和谐的、公正
的社会,在经济政策上主张加强国家宏观控制,扩大税收,特别是针对富人的税收,扩大
公共福利,甚至不惜举办国家公共工程来解决经济危机和失业问题。左翼总的来说是变革的
、进步的,是自由主义和民主政治的原教旨阵地。

右翼则正好相反,右翼信奉的是“英雄史观”,认为历史是英雄创造的,其政治主张是偏向
中产阶级、精英阶层的。右翼特别反对左翼的“均贫富”的观点,认为这实际上是在追求终
点的平等,是错误的。右翼和左翼共同之处是都追求起点的平等,但右翼更强调个人的使命
感和责任感,强调国家应给每一个公民以机会,尊重每一个人的个性,强调平等受教育(基
础教育)的权力,认为人必须对自已的命运负责,贫困只能源于自已的低素质、懒惰和无能,
不能怪其他的因素。右翼的经济政策是主张自由放任的,主张小政府、大社会,对经济的干预
和宏观调控越少越好,通过主张减税、减少公共福利、刺激投资来解决失业问题和社会问题
,认为福利越多,人的的依赖性就越强,进取心就越差,就会鼓励懒惰,打击勤奋,因此对一
个国家的前途将造成消极的影响。

右翼强调“法律和秩序”,是保守主义的,也反对变革,右翼的经济观点是正宗的自由主义,但
其政治观点是自由主义的侧门。在民主政治下,左翼和右翼,不存在谁正确谁错误、谁先进谁
反动的问题,左翼和右翼是一个国家、一个民族的左右手,是缺一不可的。一个国家不可能长期
由左翼执政,否则社会太均匀、太福利化将会阻碍经济的发展,同时容易走向民粹主义;一个国家
同样不能由右翼长期执政,否则贫富悬殊就会导致社会不公正,分配不公,最终也会阻碍经济的发展。
一个国家的“自由进程”之路不可能是笔直的,自由之路就象公路一样是弯弯曲曲的,民主政治就是一辆
汽车,要想在自由之路上顺利前进,就必须要随时调整方向盘,一会儿向右拐弯,一会儿向左拐弯,只有
这样,这辆汽车才不会冲出公路而翻车倾覆,才会顺利直达终点。所以,左翼和右翼的轮流执政,轮流
调整国家前进之路,是民主政治下两党制的基础。真正成熟的民主国家,一般只有左、右两个主要政党,
而政党林立的民主国家,其民主政治仍是不成熟的、幼稚的,还处在民主政治的低级阶段。