精华内容
下载资源
问答
  • Java常用加密技术和代码总结

    万次阅读 多人点赞 2016-07-15 17:18:02
    Java常用加密技术和代码总结,还通过一些生活中容易理解的场景来解释算法复杂的逻辑。

    总结类文章,把一些常用的Java加密技术和核心代码写在这边,供参考。

    首先大家要记住现代密码学最重要的原则柯克霍夫原则:
    数据的安全基于密钥而不是算法的保密。也就是说即使密码系统的任何细节已为人悉知,只要密匙未洩漏,它也应是安全的。

    具体来说:
    系统必须可用,非数学上不可译码。
    系统不一定要保密,可以轻易落入敌人手中。
    密匙必须可以不经书写的资料交换和记忆,且双方可以改变密匙。
    系统可以用于电讯。
    系统可以转移位置,它的功能必须不用经过几个人之手才可达到。
    系统容易使用,不要求使用者的脑力过份操劳或有很多的规则。

    一、主要的加密方式代码提供方
    JDK:代码在java安装目录下的jre\lib\jce.jar包里;
    CC:Apache公司提供的org.apache.commons.codec
    主页:http://commons.apache.org/proper/commons-codec/
    BC:org.bouncecastle
    主页:http://www.bouncycastle.org/java.html
    基本常用的使用JDK就够了。

    二、Base64算法
    1、从现在加密算法的复杂性来看Base64这种都不好意思说自己是加密,不过对于完全不懂计算机的人来说也够用了。采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
    Base64编码一般用于url的处理,或者说任何你不想让普通人一眼就知道是啥的东西都可以用Base64编码处理后再发布在网络上。

    package com.amuro.strategy.base64;
    
    import java.util.Base64;
    
    import com.amuro.strategy.IStrategy;
    
    /**
     * Base64算法基于64个基本字符,加密后的string中只包含这64个字符
     * @author Amuro
     *
     */
    public class Base64Strategy implements IStrategy
    {
        public String encode(String src)
        {
            byte[] encodeBytes = Base64.getEncoder().encode(src.getBytes());
            return new String(encodeBytes);
        }
    
        public String decode(String src)
        {
            byte[] decodeBytes = Base64.getDecoder().decode(src.getBytes());
            return new String(decodeBytes);
        }
    }
    

    2、Base64编码对应关系表
    这里写图片描述

    三、消息摘要算法(Message Digest)
    消息摘要(Message Digest)又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。HASH函数的抗冲突性使得如果一段明文稍有变化,哪怕只更改该段落的一个字母,通过哈希算法作用后都将产生不同的值。而HASH算法的单向性使得要找到哈希值相同的两个不同的输入消息,在计算上是不可能的。所以数据的哈希值,即消息摘要,可以检验数据的完整性。
    用大白话来说,任何一段数据应该都和人一样是唯一的,唯一的标识是什么,人类的话目前就是指纹,而数据的指纹是什么呢?没错,就是消息摘要算法产生的这一段String。比如我们在注册网站的时候,客户端向服务器传输的,应该是我们输入的密码进行消息摘要处理后的内容,这样就算服务器被攻破,Hack也无法知道用户真实的密码是什么。不过有说现在MD5和SHA已经被攻破了,具体大家可以谷歌。
    1、MD5

    package com.amuro.strategy.message_digest;
    
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    import org.apache.commons.codec.binary.Hex;
    
    import com.amuro.strategy.IStrategy;
    
    /**
     * 消息摘要算法
     * @author Amuro
     *
     */
    public class MD5Strategy implements IStrategy
    {
    
        public String encode(String src)
        {
            try
            {
                MessageDigest md = MessageDigest.getInstance("MD5");
                byte[] encodeBytes = md.digest(src.getBytes());
    
                return Hex.encodeHexString(encodeBytes);
            }
            catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
            }
            return null;
        }
    
        public String decode(String src)
        {
            throw new RuntimeException("MD5 no decode");
        }
    
    }
    

    2、SHA

    package com.amuro.strategy.message_digest;
    
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    import org.apache.commons.codec.binary.Hex;
    
    import com.amuro.strategy.IStrategy;
    
    /**
     * 安全散列算法
     * @author Amuro
     *
     */
    public class SHAStrategy implements IStrategy
    {
    
        public String encode(String src)
        {
            try
            {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(src.getBytes());
                return Hex.encodeHexString(md.digest());
            }
            catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
            }
            return null;
        }
    
        public String decode(String src)
        {
            throw new RuntimeException("SHA no decode");
        }
    
    }
    

    四、对称加密
    采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。而因为加密和解密都使用同一个密钥,如何把密钥安全地传递到解密者手上就成了必须要解决的问题。当然,安全性较低带来的优点就是优计算量小、加密速度快、加密效率高。
    然并卵,现代计算机对这种级别的计算量早就不care了,安全才是最重要的。
    1、DES
    DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”,是一种使用密钥加密的块算法。DES 算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是 1972 年美国 IBM 公司研制的对称密码体制加密算法。 明文按 64 位进行分组,密钥长 64 位,密钥事实上是 56 位参与 DES 运算(第8、16、24、32、40、48、56、64 位是校验位, 使得每个密钥都有奇数个 1)分组后的明文组和 56 位的密钥按位替代或交换的方法形成密文组的加密方法。

    package com.amuro.strategy.des;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    
    import org.apache.commons.codec.binary.Hex;
    
    import com.amuro.strategy.IStrategy;
    
    /**
     * 
     * @author Amuro
     *
     */
    public class DESStrategy implements IStrategy
    {
        private Cipher cipher;
        private SecretKey generateKey;
    
        public String encode(String src)
        {
            try
            {
                KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
                keyGenerator.init(56);//size
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] keyBytes = secretKey.getEncoded();
    
                DESKeySpec desKeySpec = new DESKeySpec(keyBytes);
                SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
                generateKey = secretKeyFactory.generateSecret(desKeySpec);
    
                cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, generateKey);
                byte[] resultBytes = cipher.doFinal(src.getBytes());
    
                return Hex.encodeHexString(resultBytes);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public String decode(String src)
        {
            try
            {
                cipher.init(Cipher.DECRYPT_MODE, generateKey);
                byte[] result = Hex.decodeHex(src.toCharArray());
                return new String(cipher.doFinal(result));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
    }
    

    2、3DES
    3DES,也就是“Triple DES”,中文名“三重数据加密算法”,它相当于是对每个数据块应用三次 DES 加密算法。由于计算机运算能力的增强,原版 DES 密码的密钥长度变得容易被暴力破解;3DES 即是设计用来提供一种相对简单的方法,即通过增加 DES 的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

    package com.amuro.strategy.des;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESedeKeySpec;
    
    import org.apache.commons.codec.binary.Hex;
    
    import com.amuro.strategy.IStrategy;
    
    public class _3DESStrategy implements IStrategy
    {
        private Cipher cipher;
        private SecretKey generateKey;
    
        public String encode(String src)
        {
            try
            {
                KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
                keyGenerator.init(168);//size
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] keyBytes = secretKey.getEncoded();
    
                DESedeKeySpec desKeySpec = new DESedeKeySpec(keyBytes);
                SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");
                generateKey = secretKeyFactory.generateSecret(desKeySpec);
    
                cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, generateKey);
                byte[] resultBytes = cipher.doFinal(src.getBytes());
    
                return Hex.encodeHexString(resultBytes);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public String decode(String src)
        {
            try
            {
                cipher.init(Cipher.DECRYPT_MODE, generateKey);
                byte[] result = Hex.decodeHex(src.toCharArray());
                return new String(cipher.doFinal(result));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    }
    

    3、AES
    AES,全称为“Advanced Encryption Standard”,中文名“高级加密标准”,在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。AES 加密算法作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。AES 设计有三个密钥长度:128,192,256 位。相对而言,AES 的 128 密钥比 DES 的 56 密钥强了 1021 倍。

    package com.amuro.strategy.des;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    import org.apache.commons.codec.binary.Hex;
    
    import com.amuro.strategy.IStrategy;
    
    public class AESStrategy implements IStrategy
    {
        private Cipher cipher;
        private SecretKey generateKey;
    
        public String encode(String src)
        {
            try
            {
                KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                keyGenerator.init(128);//size
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] keyBytes = secretKey.getEncoded();
    
                generateKey = new SecretKeySpec(keyBytes, "AES");
    
                cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, generateKey);
                byte[] resultBytes = cipher.doFinal(src.getBytes());
    
                return Hex.encodeHexString(resultBytes);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public String decode(String src)
        {
            try
            {
                cipher.init(Cipher.DECRYPT_MODE, generateKey);
                byte[] result = Hex.decodeHex(src.toCharArray());
                return new String(cipher.doFinal(result));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    }
    

    4、PBE
    PBE,全称为“Password Base Encryption”,中文名“基于口令加密”,是一种基于密码的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数杂凑多重加密等方法保证数据的安全性。
    PBE算法没有密钥的概念,把口令当做密钥了。因为密钥长短影响算法安全性,还不方便记忆,这里我们直接换成我们自己常用的口令就大大不同了,便于我们的记忆。但是单纯的口令很容易被字典法给穷举出来,所以我们这里给口令加了点“盐”,这个盐和口令组合,想破解就难了。同时我们将盐和口令合并后用消息摘要算法进行迭代很多次来构建密钥初始化向量的基本材料,使破译更加难了。

    package com.amuro.strategy.pbe;
    
    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.PBEKeySpec;
    import javax.crypto.spec.PBEParameterSpec;
    
    import org.apache.commons.codec.binary.Hex;
    
    import com.amuro.strategy.IStrategy;
    
    /**
     * 基于口令的加密(password),对称 + 消息摘要
     * @author Amuro
     *
     */
    public class PBEStrategy implements IStrategy
    {
        private Cipher cipher;
        private SecretKey generateKey;
        private PBEParameterSpec pbeParameterSpec;
    
        public String encode(String src)
        {
            try
            {
                SecureRandom secureRandom = new SecureRandom();
                byte[] salt = secureRandom.generateSeed(8);
    
                String password = "amuro";
                PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
                SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
                generateKey = secretKeyFactory.generateSecret(pbeKeySpec);
    
                pbeParameterSpec = new PBEParameterSpec(salt, 100);
                cipher = Cipher.getInstance("PBEWITHMD5andDES");
                cipher.init(Cipher.ENCRYPT_MODE, generateKey, pbeParameterSpec);
                byte[] resultBytes = cipher.doFinal(src.getBytes());
                return Hex.encodeHexString(resultBytes);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public String decode(String src)
        {
            try
            {
                cipher.init(Cipher.DECRYPT_MODE, generateKey, pbeParameterSpec);
                byte[] result = Hex.decodeHex(src.toCharArray());
                return new String(cipher.doFinal(result));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
    }
    

    五、非对称加密
    非对称加密算法需要两个密钥来进行加密和解密,分别是公钥和私钥。需要注意的一点,这个公钥和私钥必须是一对的,如果用公钥对数据进行加密,那么只有使用对应的私钥才能解密,反之亦然。由于加密和解密使用的是两个不同的密钥,因此,这种算法叫做非对称加密算法。
    1、RSA
    其实,在早在 1978 年的时候,RSA就已经出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。其原理就如上面的工作过程所述。RSA 算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

    package com.amuro.strategy.asymmetric;
    
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    import javax.crypto.Cipher;
    
    import org.apache.commons.codec.binary.Hex;
    
    import com.amuro.strategy.IStrategy;
    
    public class RSAStrategy implements IStrategy
    {
        private RSAPublicKey rsaPublicKey;
        private RSAPrivateKey rsaPrivateKey;
    
        public String encode(String src)
        {
            try
            {
                //初始化密钥
                KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
                keyPairGenerator.initialize(512);
                KeyPair keyPair = keyPairGenerator.generateKeyPair();
                rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
                rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
    
                //私钥加密 公钥解密
                PKCS8EncodedKeySpec pkcs8EncodedKeySpec 
                    = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
                byte[] resultBytes = cipher.doFinal(src.getBytes());
    
                //私钥解密 公钥加密
    //          X509EncodedKeySpec x509EncodedKeySpec =
    //                  new X509EncodedKeySpec(rsaPublicKey.getEncoded());
    //          KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    //          PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
    //          Cipher cipher = Cipher.getInstance("RSA");
    //          cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    //          byte[] resultBytes = cipher.doFinal(src.getBytes());
    
                return Hex.encodeHexString(resultBytes);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public String decode(String src)
        {
            try
            {
                //私钥加密 公钥解密
                X509EncodedKeySpec x509EncodedKeySpec =
                        new X509EncodedKeySpec(rsaPublicKey.getEncoded());
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.DECRYPT_MODE, publicKey);
                byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));
    
                //私钥解密 公钥加密
    //          PKCS8EncodedKeySpec pkcs8EncodedKeySpec 
    //              = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
    //          KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    //          PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    //          Cipher cipher = Cipher.getInstance("RSA");
    //          cipher.init(Cipher.DECRYPT_MODE, privateKey);
    //          byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));
    
                return new String(resultBytes);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    

    2、DH算法
    DH,全称为“Diffie-Hellman”,他是一种确保共享KEY安全穿越不安全网络的方法,也就是常说的密钥一致协议。由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成“一致”的、可以共享的密钥。也就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。
    以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!

    package com.amuro.strategy.asymmetric;
    
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Objects;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyAgreement;
    import javax.crypto.SecretKey;
    import javax.crypto.interfaces.DHPublicKey;
    import javax.crypto.spec.DHParameterSpec;
    
    import org.apache.commons.codec.binary.Hex;
    
    import com.amuro.strategy.IStrategy;
    
    public class DHStrategy implements IStrategy
    {
        private Cipher cipher;
        private SecretKey receiverSecretKey;
    
        public String encode(String src)
        {
            try
            {
                //初始化发送方密钥
                KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
                senderKeyPairGenerator.initialize(512);
                KeyPair senderkeyPair = senderKeyPairGenerator.generateKeyPair();
                PrivateKey senderPrivateKey = senderkeyPair.getPrivate();
                byte[] senderPublicKeyBytes = senderkeyPair.getPublic().getEncoded();//发送方的公钥
    
                //初始化接收方密钥,用发送方的公钥
                KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
                X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyBytes);
                PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
                DHParameterSpec dhParameterSpec = 
                        ((DHPublicKey)receiverPublicKey).getParams();
                KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
                receiverKeyPairGenerator.initialize(dhParameterSpec);
                KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
                PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();
                byte[] receiverPublicKeyBytes = receiverKeyPair.getPublic().getEncoded();
    
                KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
                receiverKeyAgreement.init(receiverPrivateKey);
                receiverKeyAgreement.doPhase(receiverPublicKey, true);
                receiverSecretKey = receiverKeyAgreement.generateSecret("DES");
    
                //发送方拿到接收方的public key就可以做加密了
                KeyFactory senderKeyFactory = KeyFactory.getInstance("DH");
                x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyBytes);
                PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec);
                KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
                senderKeyAgreement.init(senderPrivateKey);
                senderKeyAgreement.doPhase(senderPublicKey, true);
                SecretKey senderSecretKey = senderKeyAgreement.generateSecret("DES");
    
                if(Objects.equals(receiverSecretKey, senderSecretKey))
                {
                    cipher = Cipher.getInstance("DES");
                    cipher.init(Cipher.ENCRYPT_MODE, senderSecretKey);
                    byte[] result = cipher.doFinal(src.getBytes());
                    return Hex.encodeHexString(result);
                }
    
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public String decode(String src)
        {
            try
            {
                cipher.init(Cipher.DECRYPT_MODE, receiverSecretKey);
                byte[] result = Hex.decodeHex(src.toCharArray());
                return new String(cipher.doFinal(result));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
    }
    

    六、数字签名证书
    非对称加密已经灰常安全了,但是还有一个破绽:
    服务器A公布了自己的公钥,我的电脑是用服务器A的公钥加密数据后再发给服务器A的;这时候服务器B侵入了我的电脑,把我用来加密的公钥换成了它的公钥,于是我发出去的数据就会被服务器B的私钥破解了。肿么防止公钥被篡改呢?
    对,我们想到了前面的消息摘要,服务器A把公钥丢给我的时候,同时去CA申请一份数字证书,其实主要就是公钥的消息摘要,有了这份证书,当我再用公钥加密的时候,我就可以先验证一下当前的公钥是否确定是服务器A发送给我的。
    这里就贴一种RSA的:

    package com.amuro.strategy.signature;
    
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Signature;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    public class RSASign
    {
        public static boolean verifySign(String src)
        {
            try
            {
                KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
                keyPairGenerator.initialize(512);
                KeyPair keyPair = keyPairGenerator.generateKeyPair();
                PublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
                PrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
    
                PKCS8EncodedKeySpec pkcs8EncodedKeySpec 
                    = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
                Signature signature = Signature.getInstance("MD5withRSA");
                signature.initSign(privateKey);
                signature.update(src.getBytes());
                //生成签名bytes
                byte[] signBytes = signature.sign();
    
                X509EncodedKeySpec x509EncodedKeySpec =
                        new X509EncodedKeySpec(rsaPublicKey.getEncoded());
                keyFactory = KeyFactory.getInstance("RSA");
                PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
                signature = Signature.getInstance("MD5withRSA");
                signature.initVerify(publicKey);
                signature.update(src.getBytes());
                boolean isVerified = signature.verify(signBytes);
    
                return isVerified;
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
    
            return false;
        }
    
    }
    

    关于数字签名和非对称加密算法的使用,还看到一个非常棒的例子,分享给大家:
    唉,这个月买了太多的书,到月底揭不开锅了。正巧在QQ上遇到了Clark:
    1-2-3:“Clark,我需要200两纹银,能否借给我?”
    Clark:“没问题。我这就给你转账。请给我一张借条。”
    1-2-3:“太谢谢了,我这就用Word写一个借条给你。”
    然后,我新建一个Word文档,写好借条,存盘。然后,然后怎么办呢?我不能直接把借条发送给Clark,原因有:
    1. 我无法保证Clark不会在收到借条后将“纹银200两”改为“纹银2000两”。
    2. 如果我赖账,Clark无法证明这个借条就是我写的。
    3. 普通的Word文档不能作为打官司的证据。
    好在我早就申请了数字证书。我先用我的私钥对借条进行加密,然后将加密后的密文用QQ发送给Clark。Clark收到了借条的密文后,在数字证书认证中心的网站上下载我的公钥,然后使用我的公钥将密文解密,发现确实写的是“借纹银200两”,Clark就可以把银子放心的借给我了,我也不会担心Clark会篡改我的借条,原因是:
    1. 由于我发给Clark的是密文,Clark无法进行修改。Clark倒是可以修改解密后的借条,但是Clark没有我的私钥,没法模仿我对借条进行加密。这就叫防篡改。
    2. 由于用我的私钥进行加密的借条,有且只有我的公钥可以解密。反过来讲,能用我的公钥解密的借条,一定是使用我的私钥加密的,而只有我才拥有我的私钥,这样Clark就可以证明这个借条就是我写的。这就叫防抵赖。
    3. 如果我一直赖着不还钱,Clark把我告上了法庭,这个用我的私钥加密过的Word文档就可以当作程堂证供。因为我国已经出台了《中华人民共和国电子签名法》,使数字签名具有了法律效力。
    您一定已经注意到了,这个使用我的私钥进行了加密的借条,具有了防篡改、防抵赖的特性,并且可以作为程堂证供,就跟我对这个借条进行了“签名”的效果是一样的。对了,“使用我的私钥对借条进行加密”的过程就叫做数字签名。

    今天就酱~

    展开全文
  • 股票常用名词解释与技术指标公式

    千次阅读 2009-10-06 16:29:00
    股票常用名词解释 什么叫委比、委差?委比是衡量一段时间内场内买、卖盘强弱的技术指标。它的计算公式为:委比=(委买手数-委卖手数)/(委买手数+委卖手数)×100%。从公式中可以看出,“委比”的取值范围从...

    股票常用名词解释

     

    什么叫委比、委差?
    委比是衡量一段时间内场内买、卖盘强弱的技术指标。它的计算公式为:委比=(委买手数-委卖手数)/(委买手数+委卖手数)×100%。从公式中可以看出,“委比”的取值范围从-100%至+100%。若
    “委比”为正值,说明场内买盘较强,且数值越大,买盘就越强劲。反之,若“委比”为负值,则说明市道较弱。
    上述公式中的“委买手数”是指即时向下三档的委托买入的总手数,“委卖手数”是指即时向上三档的委托卖出总手数。如:某股即时最高买入委托报价及委托量为15.00元、130手,向下两档分别为14.99元、150手,14.98元、205手;最低卖出委托报价及委托量分别为15.01元、270手,向上两档分别为15.02元、475手,15.03元、655手,则此时的即时委比为-48.54%。显然,此时场内抛压很大。
    通过“委比”指标,投资者可以及时了解场内的即时买卖盘强弱情况。
    委差就是委买手数与委卖手数的差值。

    什么叫量比?
    “量比”是当日场内每分钟平均成交量与过去五日每分钟平均成交量之比。
          显然,量比大于1,表明目前场内交投活跃,成交较过去几日增加。

    什么叫内、外盘?
    内盘:以买入价成交的交易,买入成交数量统计加入内盘。
    外盘:以卖出价成交的交易。卖出量统计加入外盘。内盘,外盘这两个数据 大体可以用来判断买卖力量的强弱。若外盘数量大于内盘,则表现买方力量较强,若 内盘数量大于外盘则说明卖方力量较强。

    通过外盘、内盘数量的大小和比例,投资者通常可能发现主动性的买盘多还是主动性的抛盘多,并在很多时候可以发现庄家动向,是一个较有效的短线指标。

    但投资者在使用外盘和内盘时,要注意结合股价在低位、中位和高位的成交情况以及该股的总成交量情况。因为外盘、内盘的数量并不是在所有时间都有效,在许多时候外盘大,股价并不一定上涨;内盘大,股价也并不一定下跌。

    庄家可以利用外盘、内盘的数量来进行欺骗。在大量的实践中,我们发现如下情况:

    1、股价经过了较长时间的数浪下跌,股价处于较低价位,成交量极度萎缩。此后,成交量温和放量,当日外盘数量增加,大于内盘数量,股价将可能上涨,此种情况较可靠。

    2、在股价经过了较长时间的数浪上涨,股价处于较高价位,成交量巨大,并不能再继续增加,当日内盘数量放大,大于外盘数量,股价将可能继续下跌。

    3、在股价阴跌过程中,时常会发现外盘大、内盘小,此种情况并不表明股价一定会上涨。因为有些时候庄家用几笔抛单将股价打至较低位置,然后在卖1、卖2挂卖单,并自己买自己的卖单,造成股价暂时横盘或小幅上升。此时的外盘将明显大于内盘,使投资者认为庄家在吃货,而纷纷买入,结果次日股价继续下跌。

    4、在股价上涨过程中,时常会发现内盘大、外盘小,此种情况并不表示股价一定会下跌。因为有些时候庄家用几笔买单将股价拉至一个相对的高位,然后在股价小跌后,在买1、买2挂买单,一些者认为股价会下跌,纷纷以叫买价卖出股票,但庄家分步挂单,将抛单通通接走。这种先拉高后低位挂买单的手法,常会显示内盘大、外盘小,达到欺骗投资者的目的,待接足筹码后迅速继续推高股价。

    5、股价已上涨了较大的涨幅,如某日外盘大量增加,但股价却不涨,投资者要警惕庄家制造假象,准备出货。

    6、当股价已下跌了较大的幅度,如某日内盘大量增加,但股价却不跌,投资者要警惕庄家制造假象,假打压真吃货。

    什么叫市盈率?
             市盈率简单地讲,就是股票的市价与股票的每股税后收益(或称每股税后利润)的比率。例如:某股票的股价是24元,每股年净收益为0.60元,则该股票的市盈率为24/0.6=40元。其计算公式为:S=P/E。其中,S表示市盈率,P表示股票价格,E表示股票的每股净收益。
            很显然,股票的市盈率与股价成正比,与每股净收益成反比。股票的价格越高,则市盈率越高;而每股净收益越高,市盈率则越低。
            目前常说的市盈率为静态的,由于税后收益每半年更新一次,所以这个指标一般比较滞后,不能做为判断行情的主要指标。

    什么叫换手率?
    所谓换手就是持有股票的人把股票卖给买股票的人。所谓换手率就是成交数量(股数)除以流通盘(该股流通的股数)所得得商再乘以100%。股票换手率高表示该股成交活跃,有上涨趋势。

    什么叫净资?
    每股净资产值反映了每股股票代表的公司净资产价值,是支撑股票市场价格的重要基础。每股净资产值越大,表明公司每股股票代表的财富越雄厚,通常创造利润的能力和抵御外来因素影响的能力越强。 净资产收益率是公司税后利润除以净资产得到的百分比率,用以衡量公司运用自有资本的效率。例:其税后利润为2亿元,净资产为15亿元,净资产收益率就是13.33%(即<2亿元/15亿元>*100%)。

    什么叫除权、除息、复权?
    除权、除息之后,股价随之产生了变化,往往在股价走势图上出现向下的跳空缺口,但股东的实际资产并没有变化。如:10元的股票,10送10之后除权报价为5元,但实际还是相当于10元。这种情况可能会影响部分投资者的正确判断,看似这个价位很低,但有可能是一个历史高位,在股票分析软件中还会影响到技术指标的准确性。

    所谓复权就是对股价和成交量进行权息修复,按照股票的实际涨跌绘制股价走势图,并把成交量调整为相同的股本口径。例如某股票除权前日流通盘为5000万股,价格为10元,成交量为500万股,换手率为10%,10送10之后除权报价为5元,流通盘为1亿股,除权当日走出填权行情,收盘于5.5元,上涨10%,成交量为1000万股,换手率也是10%(和前一交易日相比具有同样的成交量水平)。复权处理后股价为11元,相对于前一日的10元上涨了10%,成交量为500万股,这样在股价走势图上真实反映了股价涨跌,同时成交量在除权前后也具有可比性。

    向前复权,就是保持现有价位不变,将以前的价格缩减,将除权前的K线向下平移,使图形吻合,保持股价走势的连续性。

    向后复权,就是保持先前的价格不变,而将以后的价格增加。上面的例子采用的就是向后复权。

    两者最明显的区别在于向前复权的当前周期报价和K线显示价格完全一致,而向后复权的报价大多低于K线显示价格。例如,某只股票当前价格10元,在这之前曾经每10股送10股,前者除权后的价格仍是10元,后者则为20元。

    股票技术指标公式

    CR能量指标

    计算方法:
    先在N日内统计强势累加HIGHN和与弱势累加和LOWN。若某日的最高价高于昨日中价,则将今日最高价与昨日中价的差累加到HIGHN中;若某日的最低价低于昨日中价,则将昨日中价与今日最低价的差累加到中LOWN。

    缺省时,系统在副图上绘制四条线,分别为26日CR,以及CR的5日均线MA1、10日均线MA2、20日均线MA3。
    应用法则:
    CR的性格介于AR与BR之间,比较接近BR。一般而言,CR低于100时买入风险不大。

    KDJ随机指标

    KDJ指标的中文名称是随机指数,是由GeorgeLane首创的。它的计算公式为:n日RSV=(Ct-Hn)/(Hn-Ln)×100;其中,Ct为当天的收盘价;Hn和Ln是最近n日内(包括当天)出现的最高价和最低价。


    K线

    K线图又称蜡烛线、阴阳线或棒线,原来是日本米市商人用来记录米市当中的行情波动,后因其标画方法具有独到之处,因而在股市及期市中被广泛引用。
    K线将买卖双方力量的增减与转变过程及实战结果用图形表示出来。经过近百年来的使用与改进,K线理论被投资人广泛接受。
    画法:
    K线之开盘价与收盘价之间以实体表示。若收盘价高于开盘价,以中空实体表示,称红线或阳线;若收盘价低于开盘价,则以黑色实体表示,称黑线或阴线。若当天最高价高于实体之高价,则在实体上方另加细线,称为上影线;当天最低价低于实体之低价,也在实体下方另加细线,称为下影线。一般来说,上影线愈长表示向下的压力愈大;而下影线愈长表示市场向上的支撑力愈大。K线的实体表示密集交易区。

    MACD平滑异同移动平均线
    Moving Average Convergence and Divergence

    平滑异同移动平均线,简称MACD,是近来美国所创的技术分析工具。MACD吸收了移动平均线的优点。运用移动平均线判断买卖时机,在趋势明显时收效很大,但如果碰上牛皮盘整的行情,所发出的信号频繁而不准确。根据移动平均线原理所发展出来的MACD,一来克服了移动平均线假信号频繁的缺陷,二来能确保移动平均线最大的战果。
    计算方法:
    MACD是计算两条不同速度(长期与中期)的指数平滑移动平均线(EMA)的差离状况来作为研判行情的基础。
    1、首先分别计算出收市价HORT日指数平滑移动平均线与LONG日指数平滑移动平均线,分别记为EMA(SHORT)与EMA(LONG)。
    2、求这两条指数平滑移动平均线的差,即:

    DIFF=EMA(SHORT)-EMA(LONG)
    3、再计算DIFF的MID日指数平滑移动平均,记为DEA。
    4、最后用DIFF减DEA,得MACD。MACD通常绘制成围绕零轴线波动的柱形图。
    在绘制的图形上,DIFF与DEA形成了两条快慢移动平均线,买进卖出信号也就决定于这两条线的交叉点。很明显,MACD是一个中长期趋势的投资技术工具。
    缺省时,系统在副图上绘制SHORT=12,LONG=26,MID=9时的DIFF线、DEA线、MACD线(柱状线)。

    应用法则:
    1、DIFF与DEA均为正值,即都在零轴线以上时,大势属多头市场,DIFF向上突破DEA,可作买。
    2、DIFF与DEA均为负值,即都在零轴线以下时,大势属空头市场,DIFF向下跌破DEA,可作卖。
    3、当DEA线与K线趋势发生背离时为反转信号。
    4、DEA在盘局时,失误率较高,但如果配合RSI及KD,可以适当弥补缺憾。
    5、分析MACD柱形图,由正变负时往往指示该卖,反之往往为买入信号。

    OBV能量潮

    能量潮是将成交量数量化,制成趋势线,配合股价趋势线,从价格的变动及成交量的增减关系,推测市场气氛。其主要理论基础是市场价格的变化必须有成交量的配合,股价的波动与成交量的扩大或萎缩有密切的关连。通常股价上升所需的成交量总是较大;下跌时,则成交量总是较小。价格升降而成交量不相应升降,则市场价格的变动难以为继。
    计算方法
    以某日为基期,逐日累计每日上市股票总成交量,若隔日指数或股票上涨,则基期OBV加上本日成交量为本日OBV。隔日指数或股票下跌,则基期OBV减去本日成交量为本日OBV。一般来说,只是观察OBV的升降并无多大意义,必须配合K线图的走势才有实际的效用。

    应用法则:

    1、当股价上升而OBV线下降,表示买盘无力,股价可能会回跌。
    2、股价下降时而OBV线上升,表示买盘旺盛,逢低接手强股,股价可能会止跌回升。
    3、OBV线缓慢上升,表示买气逐渐加强,为买进信号。
    4、OBV线急速上升时,表示力量将用尽为卖出信号。
    5、OBV线对双重顶第二个高峰的确定有较为标准的显示,当股价自双重顶第一个高峰下跌又再次回升时,如果OBV线能够随股价趋势同步上升且价量配合,则可持续多头市场并出现更高峰。相反,当股价再次回升时OBV线未能同步配合,却见下降,则可能形成第二个顶峰,完成双重顶的形态,导致股价反转下跌。
    6、OBV线从正的累积数转为负数时,为下跌趋势,应该卖出持有股票。反之,OBV线从负的累积数转为正数时,应该买进股票。
    7、OBV线最大的用处,在于观察股市盘局整理后,何时会脱离盘局以及突破后的未来走势,OBV线变动方向是重要参考指数。

    RSI相对强弱指标
    Relative Strength Index

    相对强弱指数的理论认为,在一个正常的股市中,只有多空双方的力量取得均衡,股价才能稳定。
    计算方法:
    (1)
    (2)

    公式中的RS又称为相对强弱值,公式(1)把强弱的变化幅度限定在0~100之间。
    缺省时,系统在副图上绘制三条线,分别为6日线RSI1,12日线RSI2,24日线RSI3。
    RSI反应了股价变动的四个因素: 上涨的天数、下跌的天数、上涨的幅度、下跌的幅度。它对股价的四个构成要素都加以考虑, 所以在股价预测方面其准确度较为可信。

    根据正态分布理论, 随机变数在靠近中心数值附近区域出现的机会最多, 离中心数值越远, 出现的机会就越小。
    在股市的长期发展过程中,绝大多数时间里相对强弱指数的变化范围介于30和70之间,其中又以40和60之间的机会最多,超过80或者低于20的机会较少。 而出现机会最少的是高于90及低于10。
    应用法则:
    1、66日RSI值高于85, 市场处于超买状态;6日RSI低于15, 市场处于超卖状态。在85附近出现M头可以卖出,15附近出现W底可以买进。
    2、RSI在50以下为弱势市场,50以上为强势市场。
    3、RSI在50以上的准确性较高。
    4、盘整时, RSI一底比一底高,表示多头强势,后市可能再涨一段,反之一底比一底低是卖出信号。
    5、若股价尚在盘整阶段,而 RSI已整理完成,则价位将随之突破整理区。
    6、当RSI 与股价出现背离时,一般为转势的信号。代表着大势反转,此时应选择正确的买卖时机。
    结合快速与慢速两条RSI线来确定买卖时机:把6天和12天RSI结合起来使用,当图形上6日RSI线向上突破12日RSI时,即为买进的信号。当6日RSI线向下跌破12日RSI,即为卖出信号。尤其当RSI处于低位30以下发出的买入信号与高位70以上发出的卖出信号极为可靠。
    7、RSI图形之反压线(下降趋势线)呈现15度至30度时,最具反压意义,如果反压线的角度太陡,很快地会被突破,失去反压之意义。相反,RSI图形之支撑线(上升趋势线)呈现负15度至负30度时,最具支撑意义,如果支撑线的角度太陡,将会很容易地被突破,失去支撑之意义。

    ROC变动速率
    Rate of Change

    这是测量价位动量(Momentom)的一种方法。变动速率在零上下变动,若ROC在零之上且继续上升, 表示上涨动量继续增加。若ROC值虽然在零之上,但目前正处于下降情形表示上涨动量已经降低,卖点出现。若ROC值在零以下,且ROC继续下降,表示“下跌动量”仍在增加,反之若ROC已反转上升,表示“下跌动量”已减弱,买点出现。
    计算方法:
    当日收市价与N日前的收市价的差除以N日前的收市价,再乘以100。N的缺省值为12。

    应用法则:
    1.当ROC由上而下跌破0时为卖出时机,另ROC由下而上穿破0时为买进信号。
    2.当股价创新高点,而ROC未配合上升,意谓上涨动力减弱,此背离现象,应慎防股价反转而下。
    3.当股价创新低点,而ROC未配合下降,意谓下跌动力减弱,此背离现象,应逢低承接。
    4、若股价与ROC在低水平同步上升,显示短期趋向正常或短期会有股价反弹现象。
    5.若股价与ROC在高水平同步下降,显示短期趋向正常或短期会有股价回落现象。

    BOLL布林带

    计算方法:

    BOLL带绘制支撑线(下)、阻力线(上)、中线。

    中线:收盘价的N日移动平均

    偏移值=P×收盘价的标准差

    中线加偏移值得阻力线,减偏移值得支撑线。

    参数:N设定统计天数,缺省值26

    P设定BOLL带宽度,缺省值2

    应用法则:

    1、股价向上空越支撑线,买入信号

    2、股价向上穿越阻力线,卖出信号

    VOL成交量

    配合K线图,若当日收市价较前一日收市价上涨,以空心柱表示;反之以实心柱表示。

    持仓量
    就是这个期货品种的合约市场持有的总量。

    动量线
    它基于恒速的原则,在涨 势中,每一段时间的涨幅应该一致,跌势中,每段时间的跌幅亦应一致,如果幅度不一致,往往意味着趋势有反转的可能。 算法及公式: MOM = 今天收盘价 - N天前的收盘价

    BBI多空指标

    计算方法:
    三日平均指数(股价)加六日平均指数(股价)加十二日平均指数(股价)加二十四日平均指数(股价),其总和除以四。缺省时,系统在主图上绘制BBI线。
    应用法则:
    1.多空指标线所有功能同平均线。
    2.高价区收盘价跌破多空指标线时准备卖出。
    3.低价区收盘价突破多空指标线时准备买入。
    4.当日股价位于多空指标线上时为短多行情,当日股价位于多空指标之下时为短空行情。
    多空指标线向上,股价在多空指标之上代表多头势强。
    多空指标线向下,股价在多空指标之下代表空头势强。

    负量指标

    NVI(Negative Volume Index)
    与正量指标一样是依照成交量的变化与股价的涨跌所算出的一个指标, 当NVI向上表示弱势. 本指标可设定一条平均线。它可指示“醒目资金”在大众未找到市场方向时已经入市,这些资金可能是内幕人士或投资大户的,研究负量指标走势,对后市有一定指导作用。
    算法及公式:
    如果今天成交量比昨日小
    NVI = 前一日NVI + 100 * 涨跌幅
    否则,NVI = 前一天NVI
    应用原则:
    1. 当NVI指标向下穿越其平均线时,是买入信号
    2. 当NVI指标向上穿越其平均线时,是卖出信号



    BIAS乖离率

    若股价在移动平均线之上,乖离率为正,反之为负;当股价与平均线相同,乖离率为零。乖离率周而复始穿梭在零的上方或下方。从长期图形变动可看出正乖离率大至某百分比以上便是卖出时机,负乖离率低至某百分比之下是买进时机。多头市场的狂涨与空头市场的狂跌会使乖高率达到意想不到的百分比,但是出现次数极少,时间亦短。
    计算方法:

    缺省时,系统在副图上绘制N=6日,12日,24日三条乖离线BIAS1、BIAS2、BIAS3。

    应用法则:
    由计算方法看出,乖离率表现当日指数或个股当日收盘价与移动平均线之间的差距。例如十天乖离率即表示了最近10天买进者的获利情形,正的乖离率愈大,表示短期获利愈大,则获利回吐的可能性愈高;负的乖离率愈大,则空头回补的可能性也愈高。
    乖离率究竟达到何种程度才是买进时机?并没有统一的原则,使用者只能凭经验判断一段行情的强势或弱势做为买卖股票的依据。

    价格线
    就是无K线的收盘线。

    开盘K线
    就是以开盘价画出的K线图。

    OBV能量潮

    能量潮是将成交量数量化,制成趋势线,配合股价趋势线,从价格的变动及成交量的增减关系,推测市场气氛。其主要理论基础是市场价格的变化必须有成交量的配合,股价的波动与成交量的扩大或萎缩有密切的关连。通常股价上升所需的成交量总是较大;下跌时,则成交量总是较小。价格升降而成交量不相应升降,则市场价格的变动难以为继。

    计算方法
    以某日为基期,逐日累计每日上市股票总成交量,若隔日指数或股票上涨,则基期OBV加上本日成交量为本日OBV。隔日指数或股票下跌,则基期OBV减去本日成交量为本日OBV。一般来说,只是观察OBV的升降并无多大意义,必须配合K线图的走势才有实际的效用。

    应用法则:

    1、当股价上升而OBV线下降,表示买盘无力,股价可能会回跌。
    2、股价下降时而OBV线上升,表示买盘旺盛,逢低接手强股,股价可能会止跌回升。
    3、OBV线缓慢上升,表示买气逐渐加强,为买进信号。
    4、OBV线急速上升时,表示力量将用尽为卖出信号。
    5、OBV线对双重顶第二个高峰的确定有较为标准的显示,当股价自双重顶第一个高峰下跌又再次回升时,如果OBV线能够随股价趋势同步上升且价量配合,则可持续多头市场并出现更高峰。相反,当股价再次回升时OBV线未能同步配合,却见下降,则可能形成第二个顶峰,完成双重顶的形态,导致股价反转下跌。
    6、OBV线从正的累积数转为负数时,为下跌趋势,应该卖出持有股票。反之,OBV线从负的累积数转为正数时,应该买进股票。
    7、OBV线最大的用处,在于观察股市盘局整理后,何时会脱离盘局以及突破后的未来走势,OBV线变动方向是重要参考指数。

    收盘价
    收盘价是指某一期货合约收市前五分钟内经集合竞价产生的成交价格。集合竞价未产生成交价格的, 以集合竞价前的最后一笔成交价为收盘价。

    W&R威廉指标
    Williams Overbought/Oversold Index

    全名为“威廉氏超买超卖指标”,属于分析市场短期买卖走势的技术指标。
    计算方法:

    HN :N日内最高价
    LN :N日内最低价
    C :当日收盘价
    N: 缺省值14

    威廉指数值在0至100之间波动,威廉指数的值越小,市场的买气越重;其值越大,市场卖气越浓。

    应用法则:

    1.当威廉指数线高于80,市场处于超卖状态,行情即将见底,80的横线一般称为卖出线。

    2.当威廉指数线低于20,市场处于超卖状态,行情即将见顶,20的横线一般称为“买入线”。

    3.与相对强弱指数配合使用,充分发挥二者在判断强弱市及炒买炒卖现象的互补功能,可得出对大市走向较为准确的判断.

    4.威廉指数与动力指标配合使用,在同一时期的股市周期循还内,可以确认股价的高峰与低谷。

    5.使用威廉指数作为测市工具,既不容易错过大行情,也不容易在高价区套牢。但由于该指标太敏感,在操作过程中,最好能结合相对强弱指数等较为平缓的指标一起判断。

    PSY心理线

    心理线主要研究投资者的心理趋向,将一定时期内投资人趋向买方或卖方的心理事实转化为数值,形成人气指标,从而判断股价的未来走势。一般以12天为短期投资指标,以24日为中期投资指标。
    计算方法
    以N天心理线为例,其计算方法如下:

    心理线=(N日内上涨天数/N)×100
    缺省时,系统在副图上绘制12日心理线。
    心理线最好与K线相互对照,如此更能从股价变动中了解超买或超卖情形。
    由心理线来看,当一段上升行情展开前,通常超卖现象的最低点会出现两次,因此,投资人观察心理线,若发现某一天的超卖现象严重,短期内低于此点的机会极小,当心理线向上变动而再度回落此点时,就是买进的机会。反之亦然。所以,无论上升行情或下跌行情展开前,都会出现两次以上的买点与卖点,使投资人有充分的时间研判未来股价变动方向,再作进出之最后决策。

    应用法则:

    1、一段上升行情展开前,通常超卖之低点会出现两次。同样,一段下跌行情展开前,超买的最高点也会出现两次。
    2、心理线指标介于25至75之间是合理的变动范围,这一区间属于常态分布。
    3、超过75或低于25时,就有超买或超卖现象出现。在大多头、大空头市场初期可将超买超卖点调至高于83和低于17,直到行情尾声,再回调至75与25。
    4、当低于10时是真正的超卖,反弹的机会相对提高,此时为买进时机。
    5、高点密集出现两次为卖出信号,低点密集出现两次是买进信号。
    6、心理线和成交量比率(VR)配合使用,确定短期买卖点,可以找出每一波的高低点。

     

    展开全文
  • 常用技术面试题(软件测试)

    万次阅读 2020-05-22 22:04:15
    这是小编整理的软件测试常用技术面试题 请看下面 你的测试职业发展是什么?  测试经验越多,测试能力越高。所以我的职业发展是需要时间积累的,一步步向着高级测试工程师奔去。而且我也有初步的职业规划,前3年...

    这是小编整理的软件测试常用的技术面试题
    请看下面

    1. 你的测试职业发展是什么?
       测试经验越多,测试能力越高。所以我的职业发展是需要时间积累的,一步步向着高级测试工程师奔去。而且我也有初步的职业规划,前3年积累测试经验,按如何做好测试工程师的要点去要求自己,不断更新自己改正自己,做好测试任务。

    2. 你认为测试人员需要具备哪些素质
        做测试应该要有一定的协调能力,因为测试人员经常要与开发接触处理一些问题,如果处理不好的话会引起  2、些冲突,这样的话工作上就会不好做。还有测试人员要有一定的耐心,有的时候做测试很枯燥乏味。除了耐心,测试人员不能放过每一个可能的错误。

    3. 你为什么能够做测试这一行
        虽然我的测试技术还不是很成熟,但是我觉得我还是可以胜任软件测试这个工作的,因为做软件测试不仅是要求技术好,还有有一定的沟通能力,耐心、细心等外在因素。综合起来看我认为我是胜任这个工作的。

    4. 测试的目的是什么?
        测试的目的是找出软件产品中的错误,是软件尽可能的符合用户的要求。当然软件测试是不可能找出全部错误的。

    5. 测试分为哪几个阶段?
        一般来说分为5个阶段:单元测试、集成测试、确认测试、系统测试、验收测试

    6. 单元测试的测试对象、目的、测试依据、测试方法?
        测试对象是模块内部的程序错误,目的是消除局部模块逻辑和功能上的错误和缺陷。测试依据是模块的详细设计,测试方法是采用白盒测试。

    7. 怎样看待加班问题
        加班的话我没有太多意见,但是我还是觉得如果能够合理安排时间的话,不会有太多时候加班的。

    8. 结合你以前的学习和工作经验,你认为如何做好测试。
        根据我以前的工作和学习经验,我认为做好工作首先要有一个良好的沟通,只有沟通无障碍了,才会有好的协作,才会有更好的效率,再一个就是技术一定要过关,做测试要有足够的耐心,和一个良好的工作习惯,不懂的就要问,实时与同事沟通这样的话才能做好测试工作。

    9. 你为什么选择软件测试行业
        因为之前了解软件测试这个行业,觉得他的发展前景很好。

    10. 根据你以前的工作或学习经验描述一下软件开发、测试过程,由哪些角色负责,你做什么
        要有架构师、开发经理、测试经理、程序员、测试员。我在里面主要是负责所分到的模块执行测试用例。

    11. 根据你的经验说说你对软件测试/质量保证的理解
        软件质量保证与测试是根据软件开发阶段的规格说明和程序的内部结构而精心设计的一批测试用例(即输入数据和预期的输出结果),并根据这些测试用例去运行程序,以发现错误的过程。它是对应用程序的各个方面进行测试以检查其功能、语言有效性及其外观排布。

    12. 软件测试的流程是什么?
        需求调查:全面了解系统概况、应用领域、软件开发周期、软件开发环境、开发组织、时间安排、功能需求、性能需求、质量需求及测试要求等。根据系统概况进行项目所需的人员、时间和工作量估计以及项目报价。
        制定初步的项目计划。
        测试准备:组织测试团队、培训、建立测试和管理环境等。
        测试设计:按照测试要求进行每个测试项的测试设计,包括测试用例的设计和测试脚本的开发等。
        测试实施:按照测试计划实施测试。
        测试评估:根据测试的结果,出具测试评估报告。

    13. 你对SQA的职责和工作活动(如软件度量)的理解?
        SQA就是独立于软件开发的项目组,通过对软件开发过程的监控,来保证软件的开发流程按照指定的CMM规程(如果有相应的CMM规程),对于不符合项及时提出建议和改进方案,必要时可以向高层经理汇报以求问题的解决。通过这样的途径来预防缺陷的引入,从而减少后期软件的维护成本。SQA主要的工作活动包括制定SQA工作计划,参与阶段产物的评审,进行过程质量、功能配置及物理配置的审计等;对项目开发过程中产生的数据进行度量等等。

    14. 说说你对软件配置管理的理解
        项目在开发过程中要用相应的配置管理工具对配置项(包括各个阶段的产物)进行变更控制,配置管理的使用取决于项目规模和复杂性及风险的水平。软件的规模越大,配置管理就越显得重要。还有在配置管理中,有一个很重要的概念,那就是基线,是在一定阶段各个配置项的组合,一个基线就提供了一个正式的标准,随后的工作便基于此标准,并只有经过授权后才能变更这个标准。配置管理工具主要有CC,VSS,CVS,SVN等,我只用过SVN,对其他的工具不是很熟悉。

    15. 怎样写测试计划和测试用例
        简单点,测试计划里应有详细的测试策略和测试方法,合理详尽的资源安排等,至于测试用例,那是依赖于需求(包括功能与非功能需求)是否细化到功能点,是否可测试等。

    16. 你在测试中发现了一个 bug ,但是开发经理认为这不是一个 bug ,你应该怎样解决。
      首先,将问题提交到缺陷管理库里面进行备案。然后,要获取判断的依据和标准:根据需求说明书、产品说明、设计文档等,确认实际结果是否与计划有不一致的地方,提供缺陷是否确认的直接依据;如果没有文档依据,可以根据类似软件的一般特性来说明是否存在不一致的地方,来确认是否是缺陷;根据用户的一般使用习惯,来确认是否是缺陷;与设计人员、开发人员和客户代表等相关人员探讨,确认是否是缺陷;合理的论述,向测试经理说明自己的判断的理由,注意客观、严谨,不参杂个人情绪。等待测试经理做出最终决定,如果仍然存在争议,可以通过公司政策所提供的渠道,向上级反映,并有上级做出决定。

    17. 给你一个网站,你如何测试?
      首先,查找需求说明、网站设计等相关文档,分析测试需求。制定测试计划,确定测试范围和测试策略,一般包括以下几个部分:功能性测试;界面测试;性能测试;数据库测试;安全性测试;兼容性测试
      设计测试用例,链接测试、提交功能的测试和界面测试、性能测试。
      数据库测试:要具体决定是否需要开展。数据库一般需要考虑连结性,对数据的存取操作,数据内容的验证等方面。
      安全性测试:
      1 基本的登录功能的检查
      2 是否存在溢出错误,导致系统崩溃或者权限泄露
      3 相关开发语言的常见安全性问题检查,例如 SQL 注入等。
      4 如果需要高级的安全性测试,确定获得专业安全公司的帮助,外包测试,或者获取支持兼容性测试,根据需求说明的内容,确定支持的平台组合:浏览器的兼容性;操作系统的兼容性;软件平台的兼容性;数据库的兼容性开展测试,并记录缺陷。

    18. 软件生存周期及其模型是什么?
      软件生存周期是软件开发全部过程、活动和任务的结构框架,是从可行性研究到需求分析、软件设计、编码、测试、软件发布维护的过程。在经历需求、分析、设计、实现、部署后,软件将被使用并进入维护阶段,直到最后由于缺少维护费用而逐渐消亡。这样的一个过程,称为"生命周期模型"(Life Cycle Model)。

    19. 什么是软件测试?软件测试的目的与原则
      使用人工或自动手段,来运行或测试某个系统的过程。其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。
      软件测试的目的:
      测试是程序的执行过程,目的在于发现错误;
      软件测试的原则:
      1、软件测试应尽早执行,并贯穿于整个软件生命周期
      2、软件测试应追溯需求
      3、必须确定预期输出(或结果)
      4、必须彻底检查每个测试结果
      5、严格执行测试计划,排除测试的随意性
      6、注意合法合理的输入,也要注意非法的非预期的输入
      7、检查程序是否做了不该做的
      8、测试应从“小规模”开始,逐步转向“大规模”
      9、反复使用同样的测试会使软件具有抵抗力
      10、关注缺陷的修复

    20. 软件配置管理的作用?软件配置包括什么?
      软件配置管理作为软件开发过程的必要环节和软件开发管理的基础,贯穿整个软件生命周期,同时对软件开发过程的宏观管理即项目管理也有重要的支持作用。一个软件开发组织真正有效的实施软件配置管理,将会使软件开发过程有更好的可预测性,使系统具有可重复性,大大提高软件组织的竞争力。
      软件配置包括如下内容:配置项识别、工作空间管理、版本控制、变更控制、状态报告和配置审计

    21. 什么是软件质量?
      软件质量:软件产品的特性可以满足用户的功能、性能需求的能力。

    22. 目前主要的测试用例设计方法是什么?
      1、白盒测试:
      逻辑覆盖、循环覆盖、基本路径覆盖
      2、黑盒测试:
      边界值分析法、等价类划分、错误猜测法、因果图法、状态图法、测试大纲法、随机测试和场景法

    23. 软件的安全性应从哪几个方面 去测试?
      软件安全性测试包括程序、数据库安全性测试。
      根据系统安全指标不同测试策略也不同。用户认证安全的测试要考虑问题:
      1、明确区分系统中不同用户权限,系统中会不会出现用户冲突,系统会不会因用户的权限的改变造成混乱;
      2、用户登陆密码是否是可见、可复制,是否可以通过绝对途径登陆系统(拷贝用户登陆后的链接直接进入系统)用户退出系统后是否删除了所有鉴权标记,是否可以使用后退键而不通过输入口令进入系统
      3、系统网络安全的测试要考虑问题,测试采取的防护措施是否正确装配好,有关系统的补丁是否打上,模拟非授权攻击,看防护系统是否坚固
      4、采用成熟的网络漏洞检查工具检查系统相关漏洞(即用最专业的黑客攻击工具攻击试一下,现在最常用的是 NBSI 系列和 IPhacker IP )
      5、采用各种木马检查工具检查系统木马情况,采用各种防外挂工具检查系统各组程序的外挂漏洞
      6、数据库安全考虑问题:
      系统数据是否机密(比如对银行系统,这一点就特别重要,一般的网站就没有太高要求)
      系统数据的完整性
      系统数据可管理性
      系统数据的独立性
      系统数据可备份和恢复能力(数据备份是否完整,可否恢复,恢复是否可以完整)

    24. 什么是测试用例 什么是测试脚本 两者的关系是什么?
      为实施测试而向被测试系统提供的输入数据、操作或各种环境设置以及期望结果的一个特定的集合。测试脚本是为了进行自动化测试而编写的脚本。测试脚本的编写必须对应相应的测试用例

    25. 简述什么是静态测试、动态测试、黑盒测试、白盒测试、α测试 β测试
      静态测试:不运行程序本身而寻找程序代码中可能存在的错误或评估程序代码的过程。
      动态测试是实际运行被测程序,输入相应的测试实例,检查运行结果与预期结果的差异,判
      定执行结果是否符合要求,从而检验程序的正确性、可靠性和有效性,并分析系统运行效率
      和健壮性等性能。
      黑盒测试:一般用来确认软件功能的正确性和可操作性,目的是检测软件的各个功能是否能得
      以实现,把被测试的程序当作一个黑盒,不考虑其内部结构,在知道该程序的输入和输出之间
      的关系或程序功能的情况下,依靠软件规格说明书来确定测试用例和推断测试结果的正确
      性。
      白盒测试:根据软件内部的逻辑结构分析来进行测试,是基于代码的测试,测试人员通过阅读
      程序代码或者通过使用开发工具中的单步调试来判断软件的质量,一般黑盒测试由项目经理
      在程序员开发中来实现。
      α测试:是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环
      境下进行的受控测试,Alpha 测试不能由程序员或测试员完成。
      β测试是:软件的多个用户在一个或多个用户的实际使用环境下进行的测试。开发者通常不在
      测试现场,Beta 测试不能由程序员或测试员完成。

    26. 软件产品质量特性是什么? ?
      功能性:适应性、准确性、互操作性、依从性、安全性。
      可靠性:成熟性、容错性、以恢复性。
      可使用性:易理解性、易学习性、易操作性。
      效率:时间特性、资源特性。
      可维护性:易分析性、易变更性、稳定性、易测试性。
      可移植性: 适应性、易安装性、遵循性、易替换性。

    27. 软件测试的策略是什么? 测试的策略有哪些?
      软件测试策略:在一定的软件测试标准、测试规范的指导下,依据测试项目的特定环境约束
      而规定的软件测试的原则、方式、方法的集合。
      测试策略有黑盒/白盒,静态/动态,手工/自动,冒烟测试,回归测试,公测(Beta测试的策略)。

    28. 软件测试分为几个阶段
      软件测试按阶段划分可以分为单元测试、集成测试、系统测试和验收测试4个阶段

    29. 测试人员在软件开发过程中的任务是什么?
      1、寻找 Bug;
      2、避免软件开发过程中的缺陷;
      3、衡量软件的品质;
      4、关注用户的需求。
      总的目标是:确保软件的质量。

    30. 黑盒测试和白盒测试是软件测试的两种基本方法,请分别说明各自的优点和缺点
      黑盒测试的优点有:
      1、比较简单,不需要了解程序内部的代码及实现;与软件的内部实现无关;
      2、从用户角度出发,能很容易的知道用户会用到哪些功能,会遇到哪些问题;
      3、基于软件开发文档,所以也能知道软件实现了文档中的哪些功能;
      4、在做软件自动化测试时较为方便。
      黑盒测试的缺点有:
      1、不可能覆盖所有的代码,覆盖率较低,大概只能达到总代码量的 30%;
      2、自动化测试的复用性较低。

    白盒测试的优点有:
    1、帮助软件测试人员增大代码的覆盖率,提高代码的质量,发现代码中隐藏的问题
    白盒测试的缺点有:
    1、程序运行会有很多不同的路径,不可能测试所有的运行路径;
    2、测试基于代码,只能测试开发人员做的对不对,而不能知道设计的正确与否,可能会漏掉一
    些功能需求;
    3、系统庞大时,测试开销会非常大。

    1. 如何测试一个纸杯?
      1、功能度:用水杯装水看漏不漏;水能不能被喝到;
      2、安全性:杯子有没有毒或细菌;
      3、可靠性:杯子从不同高度落下的损坏程度;
      4、可移植性:杯子在不同的地方、温度等环境下是否都可以正常使用;
      5、兼容性:杯子是否能够容纳果汁、白水、酒精、汽油等;
      6、易用性:杯子是否烫手、是否有防滑措施、是否方便饮用;
      7、用户文档:使用手册是否对杯子的用法、限制、使用条件等有详细描述;
      8、疲劳测试:将杯子盛上水(案例一)放 24 小时检查泄漏时间和情况;盛上汽油(案例二)放 24 小时检查泄漏时间和情况等
      9、压力测试:用根针并在针上面不断加重量,看压强多大时会穿透

    2. 测试计划工作的目的是什么?测试计划文档的内容应该包括什么?其中哪些是最重要的?
      答案:软件测试计划是指导测试过程的纲领性文件。
      包含了产品概述、测试策略、测试方法、测试区域、测试配置、测试周期、测试资源、测试
      交流、风险分析等内容。借助软件测试计划,参与测试的项目成员,尤其是测试管理人员,
      可以明确测试任务和测试方法,保持测试实施过程的顺畅沟通,跟踪和控制测试进度,应对
      测试过程中的各种变更。
      测试计划和测试详细规格、测试用例之间是战略和战术的关系,测试计划主要从宏观上规划
      测试活动的范围、方法和资源配置,而测试详细规格、测试用例是完成测试任务的具体战术。
      所以其中最重要的是测试测试策略和测试方法(最好是能先评审)。

    3. 黑盒测试的测试用例常见设计方法都有哪些?
      1) 等价类划分
      划分等价类: 等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类.
      2) 边界值分析法
      边界值分析方法是对等价类划分方法的补充。测试工作经验告诉我,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部.因此针对各种边界情况设计测试用例,可以查出更多的错误.使用边界值分析方法设计测试用例,首先应确定边界情况.通常输入和输出等价类的边界,就是应着重测试的边界情况.应当选取正好等于,刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据.
      3)错误猜测法
      基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法
      4)因果图方法
      前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件
      之间的联系, 相互组合等. 考虑输入条件之间的相互组合,可能会产生一些新的情况. 但要
      检查输入条件的组合不是一件容易的事情, 即使把所有输入条件划分成等价类,他们之间的
      组合情况也相当多. 因此必须考虑采用一种适合于描述对于多种条件的组合,相应产生多个
      动作的形式来考虑设计测试用例. 这就需要利用因果图(逻辑模型). 因果图方法最终生成
      的就是判定表. 它适合于检查程序输入条件的各种组合情况.
      5)正交表分析法
      有时候,可能因为大量的参数的组合而引起测试用例数量上的激增,同时,这些测试用例并
      没有明显的优先级上的差距,而测试人员又无法完成这么多数量的测试,就可以通过正交表
      来进行缩减一些用例,从而达到尽量少的用例覆盖尽量大的范围的可能性。
      6)场景分析方法
      指根据用户场景来模拟用户的操作步骤,这个比较类似因果图,但是可能执行的深度和可行
      性更好。
      7)状态图法
      通过输入条件和系统需求说明得到被测系统的所有状态,通过输入条件和状态得出输出条
      件;通过输入条件、输出条件和状态得出被测系统的测试用例。

    4. 详细的描述一个测试活动完整的过程。
      1、 项目经理通过和客户的交流,完成需求文档
      2、 开发人员和测试人员共同完成需求文档的评审,
      3、 项目经理通过综合开发人员,测试人员以及客户的意见,完成项目计划。
      4、 SQA 进入项目,开始进行统计和跟踪开发人员根据需求文档完成需求分析文档,测试人员进行评审,评审的主要内容包括是否有遗漏或者双方理解不同的地方。测试人员完成测试计划文档,测试计划包括的内容上面有描述。
      5、 写测试用例,同时开发人员完成概要设计文档,详细设计文档。此两份文档成为测试人员撰写测试用例的补充材料。
      6、 测试用例完成后,测试和开发需要进行评审。
      7、 测试人员搭建环境,开发人员提交第一个版本,可能存在未完成功能,需要说明。测试人员进行测试,发现 BUG后提交
      8、 开发提交第二个版本,测试人员进行测试。重复上面的工作,一般是 3-4 个版本后 BUG 数量减少,达到出货的要求。如果有客户反馈的问题,需要测试人员协助重现并重新测试。
      9、

    5. 软件验收测试包括 ___ 、 ___ 、 ____ 三种类型。
      软件验收测试包括正式验收测试、alpha 测试、beta 测试三种测试。

    6. 系统测试的策略有 _________等 15 种方法。(该题15 个空)
      性能测试、负载测试、强度测试、易用性测试、安全测试、配置测试、安装测试、文档测试、故障恢复测试、用户界面测试、恢复测试、分布测试、可用性测试。

    7. 设计系统测试计划需要参考的项目文档有 ___ 、 ___ 和 ____ 。
      软件测试计划、软件需求工件、和迭代计划。

    8. 软件测试项目从什么时候开始?为什么?
      软件测试应该在需求分析阶段就介入,因为测试的对象不仅仅是程序编码,应该对软件开发过程中产生的所有产品都测试,并且软件缺陷存在放大趋势.缺陷发现的越晚,修复它所花费的成本就越大.

    9. 什么是回归测试? ?
      回归测试: (regression testing): 回归测试有两类:用例回归和错误回归;
      1、 用例回归是过一段时间以后再回头对以前使用过的用例在重新进行测试,看看会重新发现问题。
      2、 错误回归,就是在新版本中,对以前版本中出现并修复的缺陷进行再次验证,并以缺陷为核心,对相关修改的部分进行测试的方法。

    10. 单元测试、集成测试、系统测试的侧重点是什么?
      1、单元测试:针对的是软件设计的最小单元–程序模块(面向过程中是函数、过程;面向对象中是类),进行正确性检验的测试工作,在于发现每个程序模块内部可能存在的差错.一般有两个步骤:人工静态检查\动态执行跟踪
      2、集成测试:针对的是通过了单元测试的各个模块所集成起来的组件进行检验,其主要内容是各个单元模块之间的接口,以及各个模块集成后所实现的功能.
      3、系统测试:针对的是集成好的软件系统,作为整个计算机系统的一个元素,与计算机硬件\外设\某些支持软件\数据和人员等其他系统元素结合在一起,要在实际的运行环境中,对计算机系统进行一系列的集成测试和确认测试.

    11. 设计用例的方法有哪些?
      1、 白盒测试用例设计有如下方法:逻辑覆盖、循环覆盖和基本路径覆盖。
      2、 黑盒测试用例设计方法:等价类划分、边界值分析、错误猜测、因果图、状态图、测试大纲、场景法、正交策略表。

    12. 一个测试工程师应具备那些素质?
      1、责任心
      2、沟通能力
      3、团队合作精神
      4、耐心、细心、信心
      5、时时保持怀疑态度,并且有缺陷预防的意识
      6、具备一定的编程经验

    13. 集成测试通常都有那些策略?
      基于分解的集成:大爆炸集成\自顶向下集成\自底向上集成\ 三明治集成\基于调用图的集成\基于路径的集成\分层集成\基于功能的集成\高频集成\基于进度的集成\基于风险集成\基于事件集成\基于使用的集成\C/S 集成

    14. 你所了解的的软件测试类型都有哪些,简单介绍一下。
      1、 按测试 策略分类:1、静态与动态测试 2、黑盒与白盒测试 3、手工和自动测试 4、冒烟测试 5、回归测试;
      2、 按测试阶段分类:单元测试、集成测试、系统测试;
      3、 其他常见测试方法:1、功能测试 2、性能测试 3、压力测试 4、负载测试 5、易用性测试 6、安装测试 7、界面测试 8、配置测试 9、文档测试 10、兼容性测试 11、安全性测试 12、恢复测试

    15. 分别概述创建测试计划与测试详细规格、测试用例
      应把详细的测试技术指标包含到独立创建的测试详细规格文档,把用于指导测试小组执行测试过程的测试用例放到独立创建的测试用例文档或测试用例管理数据库中。测试计划和测试详细规格、测试用例之间是战略和战术的关系,测试计划主要从宏观上规划测试活动的范围、方法和资源配置,而测试详细规格、测试用例是完成测试任务的具体战术。

    16. 您认为做好测试用例设计工作的关键是什么?
      白盒测试用例设计的关键是以较少的用例覆盖尽可能多的内部程序逻辑结果黑盒法用例设计的关键同样也是以较少的用例覆盖模块输出和输入接口。不可能做到完全测试,以最少的用例在合理的时间内发现最多的问题

    17. 性能测试工作的目的是什么?做好性能测试工作的关键是什么?
      性能测试的目的主要是发现在并发多用户和大数据量操作时是否会出现与需求有差异的地方。性能测试工作的关键是做好系统分析和功能分析,确定系统瓶颈所在

    18. 你的测试职业发展目标是什么?
      测试经验越多,测试能力越高。所以我的职业发展是需要时间累积的,一步步向着高级测试工程师奔去。而且我也有初步的职业规划,前 3 年累积测试经验,不断的更新自己改正自己,做好测试任务。

    19. 测试结束的标准是什么?
      从微观上来说,在测试计划中定义,比如系统在一定性能下平稳运行 72 小时,目前错误跟踪系统中,本版本中没有一般严重的 BUG,普通 BUG 的数量在 3 以下,BUG 修复率 90%以上等等参数,然后由开发经理,测试经理,项目经理共同签字认同版本 Release。如果说宏观的,则是当这个软件彻底的消失以后,测试就结束了。

    20. 软件测试分为黑盒和白盒,分别适合什么情况?
      1、 白盒测试又称为结构测试、逻辑驱动测试或基于程序本身的测试,它着重于程序的内部结构及算法,通常不关心功能与性能指标;
      2、 黑盒测试又被称为功能测试、数据驱动测试或基于规格说明的测试,它实际上是站在最终用户的立场,检验输入输出信息及系统性能指标是否符合规格说明书中有关功能需求及性能需求的规定。

    21. 一套完整的测试应该由哪些阶段组成?
      可行性分析、需求分析、概要设计、详细设计、编码、单元测试、集成测试、系统测试、验收测试

    22. 软件测试用例通常包括那些内容?
      软件测试用例的基本要素包括测试用例编号、测试标题、重要级别、测试输入、操作步骤、预期结果。

    23. 你的测试职业发展目标是什么?
      测试经验越多,测试能力越高。所以我的职业发展是需要时间累积的,一步步向着高级测试工程师奔去。而且我也有初步的职业规划,前 3 年累积测试经验,按如何做好测试工程师的要求自己,不断的更新自己改正自己,做好测试任务。

    24. 请试着比较一下黑盒测试、白盒测试、单元测试、集成测试、系统测试、验收测试的区别与联系。
      1、 黑盒测试:已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。
      这种方法是把测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。因此黑盒测试又叫功能测试或数据驱动测试。黑盒测试主要是为了发现以下几类错误:
      1、是否有不正确或遗漏的功能?
      2、在接口上,输入是否能正确的接受?能否输出正确的结果?
      3、是否有数据结构错误或外部信息(例如数据文件)访问错误?
      4、性能上是否能够满足要求?
      5、是否有初始化或终止性错误?

    2、 白盒测试:已知产品的内部工作过程,可以通过测试证明每种内部操作是否符合设计规格要求,所有内部成分是否以经过检查。软件的白盒测试是对软件的过程性细节做细致的检查。这种方法是把测试对象看做一个打开的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。通过在不同点检查程序状态,确定实际状态是否与预期的状态一致。因此白盒测试又称为结构测试或逻辑驱动测试。白盒测试主要是想对程序模块进行如下检查:
    1、对程序模块的所有独立的执行路径至少测试一遍。
    2、对所有的逻辑判定,取“真”与取“假”的两种情况都能至少测一遍。
    3、在循环的边界和运行的界限内执行循环体。
    4、测试内部数据结构的有效性,等等。

    3、 单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。单元测试是由程序员自己来完成,最终受益的也是程序员自己。可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。
    4、 集成测试(也叫组装测试,联合测试)是单元测试的逻辑扩展。它的最简单的形式是:两个已经测试过的单元组合成一个组件,并且测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合成程序的更大部分。方法是测试片段的组合,并最终扩展进程,将您的模块与其他组的模块一起测试。最后,将构成进程的所有模块一起测试。
    5、 系统测试是将经过测试的子系统装配成一个完整系统来测试。它是检验系统是否确实能提供系统方案说明书中指定功能的有效方法。(常见的联调测试)系统测试的目的是对最终软件系统进行全面的测试,确保最终软件系统满足产品需求并且遵循系统设计。
    6、 验收测试是部署软件之前的最后一个测试操作。验收测试的目的是确保软件准备就绪,并且可以让最终用户将其用于执行软件的既定功能和任务。验收测试是向未来的用户表明系统能够像预定要求那样工作。经集成测试后,已经按照设计把所有的模块组装成一个完整的软件系统,接口错误也已经基本排除了,接着就应该进一步验证软件的有效性,这就是验收测试的任务,即软件的功能和性能如同用户所合理期待的那样。
    55. 当开发人员说不是bug时,你如何应付?
    开发人员说不是 bug,有 2 种情况:
    一是需求没有确定,所以我可以这么做,这个时候可以找来产品经理进行确认,需不需要改动,3 方商量确定好后再看要不要改。
    二是这种情况不可能发生,所以不需要修改,这个时候,我可以先尽可能的说出是 BUG 的依据是什么,如果被用户发现或出了问题,会有什么不良结果,程序员可能会给你很多理由,你可以对他的解释进行反驳。
    56. 为什么要在一个团队中开展软件测试工作?
    因为没有经过测试的软件很难在发布之前知道该软件的质量,就好比 ISO 质量认证一样,测试同样也需要质量的保证,这个时候就需要在团队中开展软件测试的工作。在测试的过程发现软件中存在的问题,及时让开发人员得知并修改问题,在即将发布时,从测试报告中得出软件的质量情况。
    57. 如果有机会转成开发人员,你会去做开发工作吗?
    如果公司确实需要我可以从事开发,但我还是喜欢做测试,我认为我更适合做测试。
    58. 软件测试分哪些阶段?各阶段的含义?
    分为单元测试、集成测试、确认测试、系统测试、验收测试。单元测试是最小单位的测试,测试独立模块;集成测试主要测试模块之间的接口是否正常,确认测试类似于冒烟测试通常在大规模系统测试之前验证版本主要功能是否实现,版本的稳定性是否可以进入系统测试,系统测试是全面测试验证系统是否满足用户需求包括功能、性能、兼容性等等。验收测试是用户参与的测试。
    59. 一份测试计划应该包括哪些内容?
    背景、项目简介、目的、测试范围、测试策略、人员分工、资源要求、进度计划、参考文档、常用术语、提交文档、风险分析。
    60. 针对于软件的行业背景,你如何理解软件的业务?
    阅读用户手册了解软件的功能和操作流程;看一些业务的专业书籍补充业务知识;如果有用户实际的数据,可以拿实际的数据进行参考;参考以前的用例和 BUG 报告;在使用软件的过程中多思考;多与产品经理交流。
    61. 测试用例应包括哪些内容?
    编号、模块名称、编写人、日期、操作说明、输入数据、预期结果等。
    62. 什么是兼容性测试?兼容性测试侧重哪些方面。

     兼容测试主要是检查软件在不同的硬件平台、软件平台上是否可以正常的运行,即是通常说的软件的可移植性。
     兼容的类型,如果细分的话,有平台的兼容,网络兼容,数据库兼容,以及数据格式的兼容。
     兼容测试的重点是对兼容环境的分析。通常,是在运行软件的环境不是很确定的情况下,才需要做兼容。根据软件运行的需要,或者根据需求文档,一般都能够得出用户会在什么环境下使用该软件,把这些环境整理成表单,就得出做兼容测试的兼容环境了。
     兼容和配置测试的区别在于,做配置测试通常不是Clean OS下做测试,而兼容测试多是在Clean OS的环境下做的。。
    63. 对某软件进行测试,发现在 WIN98 上运行得很慢,怎么判别是该软件存在问题还是其软硬件运行环境存在问题?
    看软件的运行环境要求。如果符合要求则是程序存在问题,若不符合要求则是硬件系统存在问题
    64. 我现在有个程序,发现在Windows上运行得很慢,怎么判别是程序存在问题还是软硬件系统存在问题
    1、检查系统是否有中毒的特征;
    2、检查软件/硬件的配置是否符合软件的推荐标准;
    3、确认当前的系统是否是独立,即没有对外提供什么消耗CPU资源的服务;
    4、如果是C/S或者B/S结构的软件,需要检查是不是因为与服务器的连接有问题,或者访问有问题造成的;
    5、在系统没有任何负载的情况下,查看性能监视器,确认应用程序对CPU/内存的访问情况。
    65. 正交表测试用例设计方法的特点是什么?
    用最少的实验覆盖最多的操作,测试用例设计很少,效率高,但是很复杂;
    对于基本的验证功能,以及二次集成引起的缺陷,一般都能找出来;但是更深的缺陷,更复杂的缺陷,还是无能为力的;具体的环境下,正交表一般都很难做的。大多数,只在系统测试的时候使用此方法。
    66. 描述使用bugzilla缺陷管理工具对软件缺陷(BUG)跟踪的管理的流程?
    就是Bugzilla的状态转换图。
    67. 你觉得bugzilla在使用的过程中,有什么问题?
    界面不稳定;
    根据需要配置它的不同的部分,过程很烦琐。
    流程控制上,安全性不好界定,很容易对他人的Bug进行误操作;
    没有综合的评分指标,不好确认修复的优先级别。
    68. 描述测试用例设计的完整过程?
    需求分析 + 需求变更的维护工作;
    根据需求 得出测试需求;
    设计测试方案,评审测试方案;
    方案评审通过后,设计测试用例,再对测试用例进行评审;
    69. 单元测试的策略有哪些?
    逻辑覆盖、循环覆盖、同行评审、桌前检查、代码走查、代码评审、景泰数据流分析
    70. LoadRunner分哪三部分?
    用户动作设计;场景设计;测试数据分析;
    71. LoadRunner进行测试的流程?

    1. 测试测试
    2. 创建虚拟用户脚本
    3. 创建运行场景
    4. 运行测试脚本
    5. 监视场景
    6. 分析测试的结果
      以上,最好是结合一个案例,根据以上流程来介绍。
    7. 什么是并发?在LoadRunner中,如何进行并发的测试?集合点失败了会怎么样?
      在同一时间点,支持多个不同的操作。
      LoadRunner中提供IP伪装,集合点,配合虚拟用户的设计,以及在多台电脑上设置,可以比较好的模拟真实的并发。
      集合点,即是多个用户在某个时刻,某个特定的环境下同时进行虚拟用户的操作的。集合点失败,则集合点的才操作就会取消,测试就不能进行。
    8. 使用QTP做功能测试,录制脚本的时候,要验证多个用户的登录情况/查询情况,如何操作?
      分析用户登录的基本情况,得出一组数据,通过性测试/失败性测试的都有(根据TC来设计这些数据),然后录制登录的脚本,将关键的数据参数化,修改脚本,对代码进行加强,调试脚本。
    9. QTP中的Action有什么作用?有几种?
      Action的作用
       用Action可以对步骤集进行分组
       步骤重组,然后被整体调用
       拥有自己的sheet
       组合有相同需求的步骤,整体操作
       具有独立的对象仓库
      Action的种类
       可复用Action
       不可复用Action
       外部Action
    10. TestDirector有些什么功能,如何对软件测试过程进行管理?
      需求管理
       定义测试范围
       定义需求树
       描述需求树的功能点
      测试计划
       定义测试目标和测试策略。
       分解应用程序,建立测试计划树。
       确定每个功能点的测试方法。
       将每个功能点连接到需求上,使测试计划覆盖全部的测试需求。
       描述手工测试的测试步骤
       指明需要进行自动测试的功能点
      测试执行
       定义测试集合。
       为每个测试人员制定测试任务和测试日程安排。
       运行自动测试。
      缺陷跟踪
       记录缺陷
       查看新增缺陷,并确定哪些是需要修正的
       相关技术人员修改缺陷
       回归测试
       分析缺陷统计图表,分析应用程序的开发质量。
    11. 软件缺陷(或者叫Bug)记录都包含了哪些内容?如何提交高质量的软件缺陷(Bug)记录?
      5C标准
    12. Beta测试与Alpha测试有什么区别
      Beta testing(β测试),测试是软件的多个用户在一个或多个用户的实际使用环境下进行的测试。开发者通常不在测试现场
      Alpha testing (α测试),是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的受控测试
    13. 软件的评审一般由哪些人参加?其目的是什么
      在正式的会议上将软件项目的成果(包括各阶段的文档、产生的代码等)提交给用户、客户或有关部门人员对软件产品进行评审和批准。其目的是找出可能影响软件产品质量、开发过程、维护工作的适用性和环境方面的设计缺陷,并采取补救措施,以及找出在性能、安全性和经济方面的可能的改进。
      人员:用户、客户或有关部门开发人员,测试人员,需求分析师都可以,就看处于评审那个阶段
    14. 测试****活动中,如果发现需求文档不完善或者不准确,怎么处理
      测试需求分析 发现需求文档不完善或者不准确,应该立即和相关人员进行协调交流。
    15. 阶段评审与项目评审有什么区别
      阶段评审 对项目各阶段评审:对阶段成果和工作
      项目评审 对项目总体评审:对工作和产品
    16. 阐述工作版本的定义?
      构造号: BUILD
    17. 什么是桩模块?什么是驱动模块?
      桩模块:被测模块调用模块
      驱动模块 调用被测模块
    18. 什么是扇入?什么是扇出
      扇入:被调次数,扇出:调其它模块数目
    19. 你认为做好测试计划工作的关键是什么?
      软件测试计划就是在软件测试工作正式实施之前明确测试的对象,并且通过对资源、时间、风险、测试范围和预算等方面的综合分析和规划,保证有效的实施软件测试;
      做好测试计划工作的关键 :目的,管理,规范
    20. 明确测试的目标,增强测试计划的实用性
      编写软件测试计划得重要目的就是使测试过程能够发现更多的软件缺陷,因此软件测试计划的价值取决于它对帮助管理测试项目,并且找出软件潜在的缺陷。因此,软件测试计划中的测试范围必须高度覆盖功能需求,测试方法必须切实可行,测试工具并且具有较高的实用性,便于使用,生成的测试结果直观、准确
      2.坚持“5W”规则,明确内容与过程
      “5W”规则指的是“What(做什么)”、“Why(为什么做)”、“When(何时做)”、“Where(在哪里)”、“How(如何做)”。利用“5W”规则创建软件测试计划,可以帮助测试团队理解测试的目的(Why),明确测试的范围和内容(What),确定测试的开始和结束日期(When),指出测试的方法和工具(How),给出测试文档和软件的存放位置(Where)。
      3.采用评审和更新机制,保证测试计划满足实际需求
      测试计划写作完成后,如果没有经过评审,直接发送给测试团队,测试计划内容的可能不准确或遗漏测试内容,或者软件需求变更引起测试范围的增减,而测试计划的内容没有及时更新,误导测试执行人员。
    21. 分别创建测试计划与测试详细规格、测试用例
      应把详细的测试技术指标包含到独立创建的测试详细规格文档,把用于指导测试小组执行测试过程的测试用例放到独立创建的测试用例文档或测试用例管理数据库中。测试计划和测试详细规格、测试用例之间是战略和战术的关系,测试计划主要从宏观上规划测试活动的范围、方法和资源配置,而测试详细规格、测试用例是完成测试任务的具体战术。
    22. 你认为做好测试用例工作的关键是什么
      需求和设计文档的理解程度,对系统的熟悉程度
    23. 简述一下缺陷的生命周期?
      提交->确认->分配->修复->验证->关闭
    24. 软件的安全性应从哪几个方面去测试?
    25. 用户认证机制:如数据证书、智能卡、双重认证、安全电子交易协议
    26. 加密机制
    27. 安全防护策略:如安全日志、入侵检测、隔离防护、漏洞扫描
    28. 数据备份与恢复手段:存储设备、存储优化、存储保护、存储管理
    29. 防病毒系统
    30. 软件配置管理工作开展的情况和认识?
      软件配置管理贯穿于软件开发、测试活动的始终,覆盖了开发、测试活动的各个环节,它的重要作用之一就是要全面的管理保存各个配置项,监控各配置项的状态,并向项目经理及相关的人员报告,从而实现对软件过程的控制。
      软件测试配置管理包括4个最基本的活动:
      配置项标识
      配置项控制
      配置项状态报告
      配置审计
      软件配置管理通常借助工具来辅助,主要有MS SourceSafe、Rational ClearCase等
    31. 你觉得软件测试通过的标准应该是什么样的?
      缺陷密度值达到客户的要求
    32. 引入测试管理的含义
      风险分析,进度控制、角色分配、质量控制
    33. 一套完整的测试应该由哪些阶段组成
      测试计划、测试设计与开发、测试实施、测试评审与测试结论
    34. 单元测试的主要内容?
      模块接口测试、局部数据结构测试、路径测试、错误处理测试、边界测试
    35. 集成测试也叫组装测试或者联合测试,请简述集成测试的主要内容?
      (1)在把各个模块连接起来的时候,穿越模块接口的数据是否会丢失;
       (2)一个模块的功能是否会对另一个模块的功能产生不利的影响;
       (3)各个子功能组合起来,能否达到预期要求的父功能;
       (4)全局数据结构是否有问题;
       (5)单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。
    36. 简述集成测试与系统测试关系
       (1)集成测试的主要依据概要设计说明书,系统测试的主要依据是需求设计说明书;
       (2)集成测试是系统模块的测试,系统测试是对整个系统的测试,包括相关的软硬件平台、网络以及相关外设的测试。
    37. 软件测试的文档测试应当贯穿于软件生命周期的全过程,其中用户文档是文档测试的重点。那么软件系统的用户文档包括哪些
        用户手册
        安装和设置指导
        联机帮助
        指南、向导
        样例、示例和模板
        授权/注册登记表
      最终用户许可协议
    38. 软件系统中除用户文档之外,文档测试还应该关注哪些文档
      开发文档
      软件需求说明书
          数据库设计说明书
          概要设计说明书
          详细设计说明书
          可行性研究报告
      管理文档
          项目开发计划
          测试计划
          测试报告
          开发进度月报
          开发总结报告
    39. 简述软件系统中用户文档的测试要点
       (1)读者群。文档面向的读者定位要明确。对于初级用户、中级用户以及高级用户应该有不同的定位
       (2)术语。文档中用到的术语要适用与定位的读者群,用法一致,标准定义与业界规范相吻合。
       (3)正确性。测试中需检查所有信息是否真实正确,查找由于过期产品说明书和销售人员夸大事实而导致的错误。检查所有的目录、索引和章节引用是否已更新,尝试链接是否准确,产品支持电话、地址和邮政编码是否正确。
       (4)完整性。对照软件界面检查是否有重要的分支没有描述到,甚至是否有整个大模块没有描述到。
       (5)一致性。按照文档描述的操作执行后,检查软件返回的结果是否与文档描述的相同。
       (6)易用性。对关键步骤以粗体或背景色给用户以提示,合理的页面布局、适量的图表都可以给用户更高的易用性。需要注意的是文档要有助于用户排除错误。不但描述正确操作,也要描述错误处理办法。文档对于用户看到的错误信息应当有更详细的文档解释。
       (7)图表与界面截图。检查所有图表与界面截图是否与发行版本相同。
       (8)样例与示例。像用户一样载入和使用样例。如果是一段程序,就输入数据并执行它。以每一个模块制作文件,确认它们的正确性。
       (9)语言。不出现错别字,不要出现有二义性的说法。特别要注意的是屏幕截图或绘制图形中的文字。
       (10)印刷与包装。检查印刷质量;手册厚度与开本是否合适;包装盒的大小是否合适;有没有零碎易丢失的小部件等等。
    40. 如何理解强度测试
      强度测试是为了确定系统在最差工作环境的工作能力,也可能是用于验证在标准工作压力下的各种资源的最下限指标。
      它和压力测试的目标是不同的,压力测试是在标准工作环境下,不断增加系统负荷,最终测试出该系统能力达到的最大负荷(稳定和峰值),而强度测试则是在非标准工作环境下,甚至不断人为降低系统工作环境所需要的资源,如网络带宽,系统内存,数据锁等等,以测试系统在资源不足的情况下的工作状态,通过强度测试,可以确定本系统正常工作的最差环境.
      强度测试和压力测试的测试指标相近,大多都是与时间相关的指标,如并发量(吞吐量),延迟(最大\最小\平均)以及顺序指标等
      强度测试需要对系统的结构熟悉,针对系统的特征设计强度测试的方法
    41. 如何理解压力、负载、性能测试测试
    42. 性能测试是一个较大的范围,实际上性能测试本身包含了性能、强度、压力、负载等多方面的测试内容。
      压力测试是对服务器的稳定性以及负载能力等方面的测试,是一种很平常的测试。增大访问系统的用户数量、或者几个用户进行大数据量操作都是压力测试。
    43. 而负载测试是压力相对较大的测试,主要是测试系统在一种或者集中极限条件下的相应能力,是性能测试的重要部分。100个用户对系统进行连续半个小时的访问可以看作压力测试,那么连续访问8个小时就可以认为负载测试,1000个用户连续访问系统1个小时也可以看作是负载测试。
      实际上压力测试和负载测试没有明显的区分。测试人员应该站在关注整体性能的高度上来对系统进行测试。
    44. 么是系统瓶颈
      瓶颈主要是指整个软硬件构成的软件系统某一方面或者几个方面能力不能满足用户的特定业务要求,“特定”是指瓶颈会在某些条件下会出现,因为毕竟大多数系统在投入前。
      严格的从技术角度讲,所有的系统都会有瓶颈,因为大多数系统的资源配置不是协调的,例如CPU使用率刚好达到100%时,内存也正好耗尽的系统不是很多见。因此我们讨论系统瓶颈要从应用的角度讨论:关键是看系统能否满足用户需求。在用户极限使用系统的情况下,系统的响应仍然正常,我们可以认为改系统没有瓶颈或者瓶颈不会影响用户工作。
      因此我们测试系统瓶颈主要是实现下面两个目的:
      -发现“表面”的瓶颈。主要是模拟用户的操作,找出用户极限使用系统时的瓶颈,然后解决瓶颈,这是性能测试的基本目标。
      -发现潜在的瓶颈并解决,保证系统的长期稳定性。主要是考虑用户在将来扩展系统或者业务发生变化时,系统能够适应变化。满足用户目前需求的系统不是最好的,我们设计系统的目标是在保证系统整个软件生命周期能够不断适应用户的变化,或者通过简单扩展系统就可以适应新的变化。
    45. 文档测试主要包含什么内容
      在国内软件开发管理中,文档管理几乎是最弱的一项,因而在测试工作中特别容易忽略文档测试也就不足为奇了。要想给用户提供完整的产品,文档测试是必不可少的。文档测试一般注重下面几个方面:
      文档的完整性:主要是测试文档内容的全面性与完整性,从总体上把握文档的质量。例如用户手册应该包括软件的所有功能模块。
      描述与软件实际情况的一致性:主要测试软件文档与软件实际的一致程度。例如用户手册基本完整后,我们还要注意用户手册与实际功能描述是否一致。因为文档往往跟不上软件版本的更新速度。
      易理解性:主要是检查文档对关键、重要的操作有无图文说明,文字、图表是否易于理解。对于关键、重要的操作仅仅只有文字说明肯定是不够的,应该附有图表使说明更为直观和明了。
      文档中提供操作的实例:这项检查内容主要针对用户手册。对主要功能和关键操作提供的应用实例是否丰富,提供的实例描述是否详细。只有简单的图文说明,而无实例的用户手册看起来就像是软件界面的简单拷贝,对于用户来说,实际上没有什么帮助。
      印刷与包装质量:主要是检查软件文档的商品化程度。有些用户手册是简单打印、装订而成,过于粗糙,不易于用户保存。优秀的文档例如用户手册和技术白皮书,应提供商品化包装,并且印刷精美。
    46. 功能测试用例需要详细到什么程度才是合格的
      这个问题也是测试工程师经常问的问题。有人主张测试用例详细到每个步骤执行什么都要写出来,目的是即使一个不了解系统的新手都可以按照测试用例来执行工作。主张这类写法的人还可以举出例子:欧美、日本等软件外包文档都是这样做的。
      另外一种观点就是主张写的粗些,类似于编写测试大纲。主张这种观点的人是因为软件开发需求管理不规范,变动十分频繁,因而不能按照欧美的高标准来编写测试用例。这样的测试用例容易维护,可以让测试执行人员有更大的发挥空间。
      实际上,软件测试用例的详细程度首先要以覆盖到测试点为基本要求。举个例子:“用户登陆系统”的测试用例可以不写出具体的执行数据,但是至少要写出五种以上情况(),如果只用一句话覆盖了这个功能是不合格的测试用例。覆盖功能点不是指列出功能点,而是要写出功能点的各个方面(如果组合情况较多时可以采用等价划分)。
      另一个影响测试用例的就是组织的开发能力和测试对象特点。如果开发力量比较落后,编写较详细的测试用例是不现实的,因为根本没有那么大的资源投入,当然这种情况很随着团队的发展而逐渐有所改善。测试对象特点重点是指测试对象在进度、成本等方面的要求,如果进度较紧张的情况下,是根本没有时间写出高质量的测试用例的,甚至有些时候测试工作只是一种辅助工作,因而不编写测试用例。
      因此,测试用例的编写要根据测试对象特点、团队的执行能力等各个方面综合起来决定编写策略。最后要注意的是测试人员一定不能抱怨,力争在不断提高测试用例编写水平的同时,不断地提高自身能力。
    47. 配置和兼容性测试的区别是什么
      配置测试的目的是保证软件在其相关的硬件上能够正常运行,而兼容性测试主要是测试软件能否与不同的软件正确协作。
      配置测试的核心内容就是使用各种硬件来测试软件的运行情况,一般包括:
      (1)软件在不同的主机上的运行情况,例如Dell和Apple;
      (2)软件在不同的组件上的运行情况,例如开发的拨号程序要测试在不同厂商生产的Modem上的运行情况;
      (3)不同的外设;
      (4)不同的接口;
      (5)不同的可选项,例如不同的内存大小;
      兼容性测试的核心内容:
      (1)测试软件是否能在不同的操作系统平台上兼容;
      (2)测试软件是否能在同一操作系统平台的不同版本上兼容;
      (3)软件本身能否向前或者向后兼容;
      (4)测试软件能否与其它相关的软件兼容;
      (5)数据兼容性测试,主要是指数据能否共享;
      配置和兼容性测试通称对开发系统类软件比较重要,例如驱动程序、操作系统、数据库管理系统等。具体进行时仍然按照测试用例来执行。
    48. 软件文档测试主要包含什么
      随着软件文档系统日益庞大,文档测试已经成为软件测试的重要内容。文档测试对象主要如下:
      -包装文字和图形;
      -市场宣传材料、广告以及其它插页;
      -授权、注册登记表;
      -最终用户许可协议;
      -安装和设置向导;
      -用户手册;
      -联机帮助;
      -样例、示范例子和模板;
      -……
      文档测试的目的是提高易用性和可靠性,降低支持费用,因为用户通过文档就可以自己解决问题。因文档测试的检查内容主要如下:
      -读者对象——主要是文档的内容是否能让该级别的读者理解;
      -术语——主要是检查术语是否适合读者;
      -内容和主题——检查主题是否合适、是否丢失、格式是否规范等;
      -图标和屏幕抓图——检查图表的准确度和精确度;
      -样例和示例——是否与软件功能一致;
      -拼写和语法;
      -文档的关联性——是否与其它相关文档的内容一致,例如与广告信息是否一致;
      文档测试是相当重要的一项测试工作,不但要给予充分的重视,更要要认真的完成,象做功能测试一样来对待文档测试。
    49. 没有产品说明书和需求文档地情况下能够进行黑盒测试吗
      这个问题是国内测试工程师经常遇到的问题,根源就是国内软件开发文档管理不规范,对变更的管理方法就更不合理了。实际上没有任何文档的时候,测试人员是能够进行黑盒测试的,这种测试方式我们可以称之为探索测试,具体做法就是测试工程师根据自己的专业技能、领域知识等不断的深入了解测试对象、理解软件功能,进而发现缺陷。
      在这种做法基本上把软件当成了产品说明书,测试过程中要和开发人员不断的进行交流。尤其在作项目的时候,进度压力比较大,可以作为加急测试方案。最大的风险是不知道有些特性是否被遗漏。
    50. 测试中的“杀虫剂怪事”是指什么?
      “杀虫剂怪事”一词由BorisBeizer在其编著的《软件测试技术》第二版中提出。用于描述测试人员对同一测试对象进行的测试次数越多,发现的缺陷就会越来越少的现象。就像老用一种农药,害虫就会有免疫力,农药发挥不了效力。这种现象的根本原因就是测试人员对测试软件过于熟悉,形成思维定势。
      为了克服这种现象,测试人员需要不断编写新的测试程序或者测试用例,对程序的不同部分进行测试,以发现更多的缺陷。也可以引用新人来测试软件,刚刚进来的新手往往能发现一些意想不到的问题。
    51. 在配置测试中,如何判断发现的缺陷是普通问题还是特定的配置问题?
      在进行配置测试时,测试工程师仍然会发现一些普通的缺陷,也就是与配置环境无关的缺陷。因此判断新发现的问题,需要在不同的配置中重新执行发现软件缺陷的步骤,如果软件缺陷不出现了,就可能是配置缺陷;如果在所有的配置中都出现,就可能是普通缺陷。
      需要注意的是,配置问题可以在一大类配置中出现。例如,拨号程序可能在所有的外置Modem中都存在问题,而内置的Modem不会有任何问题。
    52. 为什么尽量不要让时间有富裕的员工去做一些测试?
      表面上看这体现了管理的效率和灵活性,但实际上也体现了管理者对测试的轻视。测试和测试的人有很大关系。测试工作人员应该是勤奋并富有耐心,善于学习、思考和发现问题,细心有条理,总结问题,如果具备这样的优点,做其它工作同样也会很出色,因此这里还有一个要求,就是要喜欢测试这项工作。如果他是专职的,那么肯定更有经验和信心。国内的小伙子好象都喜欢做程序员,两者工作性质不同,待遇不同,地位不同,对自我实现的价值的认识也不同,这是行业的一个需要改善的问题。如果只是为了完成任务而完成任务,或者发现了几个问题就觉得满意了,这在任何其它工作中都是不行的。
    53. 完全测试程序是可能的吗
      软件测试初学者可能认为拿到软件后需要进行完全测试,找到全部的软件缺陷,使软件“零缺陷”发布。实际上完全测试是不可能的。主要有以下一个原因:
      -完全测试比较耗时,时间上不允许;
      -完全测试通常意味着较多资源投入,这在现实中往往是行不通的;
      -输入量太大,不能一一进行测试;
      -输出结果太多,只能分类进行验证;
      -软件实现途径太多;
      -软件产品说明书没有客观标准,从不同的角度看,软件缺陷的标准不同;
      因此测试的程度要根据实际情况确定。
    54. 软件测试的风险主要体现在哪里?
      我们没有对软件进行完全测试,实际就是选择了风险,因为缺陷极有可能存在没有进行测试的部分。举个例子,程序员为了方便,在调试程序时会弹出一些提示信息框,而这些提示只在某种条件下会弹出,碰巧程序发布前这些代码中的一些没有被注释掉。在测试时测试工程师又没有对其进行测试。如果客户碰到它,这将是代价昂贵的缺陷,因为交付后才被客户发现。
      因此,我们要尽可能的选择最合适的测试量,把风险降低到最小。
    55. 发现的缺陷越多,说明软件缺陷越多吗?
      这是一个比较常见的现象。测试工程师在没有找到缺陷前会绞尽脑汁的思考,但是找到一个后,会接二连三的发现很多缺陷,颇有个人成就感。其中的原因主要如下:
      -代码复用、拷贝代码导致程序员容易犯相同的错误。类的继承导致所有的子类会包含基类的错误,反复拷贝同一代码意味可能也复制了缺陷。
      -程序员比较劳累是可以导致某些连续编写的功能缺陷较多。程序员加班是一种司空见惯的现象,因此体力不只时容易编写一些缺陷较多的程序。而这些连续潜伏缺陷恰恰时测试工程师大显身手的地方。
      “缺陷一个连着一个”不是一个客观规律,只是一个常见的现象。如果软件编写的比较好,这种现象就不常见了。测试人员只要严肃认真的测试程序就可以了。
    56. 所有的软件缺陷都能修复吗?所有的软件缺陷都要修复吗?
      从技术上讲,所有的软件缺陷都是能够修复的,但是没有必要修复所有的软件缺陷。测试人员要做的是能够正确判断什么时候不能追求软件的完美。对于整个项目团队,要做的是对每一个软件缺陷进行取舍,根据风险决定那些缺陷要修复。发生这种现象的主要原因如下:
      -没有足够的时间资源。在任何一个项目中,通常情况下开发人员和测试人员都是不够用的,而且在项目中没有预算足够的回归测试时间,再加上修改缺陷可能引入新的缺陷,因此在交付期限的强大压力下,必须放弃某些缺陷的修改。
      -有些缺陷只是特殊情况下出现,这种缺陷处于商业利益考虑,可以在以后升级中进行修复。
      -不是缺陷的缺陷。我们经常会碰到某些功能方面的问题被当成缺陷来处理,这类问题可以以后有时间时考虑再处理。
      最后要说的是,缺陷是否修改要由软件测试人员、项目经理、程序员共同讨论来决定是否修复,不同角色的人员从不同的角度来思考,以做出正确的决定。
    57. 软件测试人员就是QA吗?
      软件测试人员的职责是尽可能早的找出软件缺陷,确保得以修复。而质量保证人员(QA)主要职责是创建或者制定标准和方法,提高促进软件开发能力和减少软件缺陷。测试人员的主要工作是测试,质量保证人员日常工作重要内容是检查与评审,测试工作也是测试保证人员的工作对象。
      软件测试和质量是相辅相成的关系,都是为了提高软件质量而工作。
    58. 如何减少测试人员跳槽带来的损失?
      在IT行业里跳槽已经是一种司空见惯的现象,而且跳槽无论给公司还是给个人都会带来一定的损失。测试队伍也无疑会面临跳槽的威胁,作为测试经理管理者,只有从日常工作中开始做起,最能最大限度的减少损失。建议我们从以下两个方面做起:
      -加强部门内员工之间的互相学习,互相学习是建立学习型组织的基本要求,是知识互相转移的过程。在此基础上,可以把个人拥有的技术以知识的形式沉积下来,也就完成了隐性知识到显性知识的转化。
      -通常情况下,企业能为员工提供足够大的发展空间时,如果不是待遇特别低,员工都不会主动离开企业。因此我们要想留住员工,管理者就应该把员工的个人成长和企业的发展联系起来,为员工设定合理发展规划并付诸实现。不过这项要求做起来比较,要有比较好的企业文化为依托。
    59. 测试产品与测试项目的区别是什么?
      习惯上把开发完成后进行商业化、几乎不进行代码修改就可以售给用户使用的软件成为软件产品,也就是可以买“卖拷贝”的软件,例如Windows2000。而通常把针对一个或者几个特定的用户而开发的软件成为软件项目,软件项目是一种个性化的产品,可以是按照用户要求全部重新开发,也可以修改已有的软件产品来满足特定的用户需求。项目和产品的不同特点,决定我们测试产品和测试项目仍然会有很多不同的地方:
      -质量要求不同。通常产品的质量要高一些,修复发布后产品的缺陷成本较高,甚至会带来很多负面的影响。而做项目通常面向某一用户,虽然质量越高越好,但是一般只要满足用户要求就可以了。
      -测试资源投入多少不同。做软件产品通常是研发中心来开发,进度压力要小些。同时由于质量要求高,因此会投入较多的人力、物力资源。
      -项目最后要和用户共同验收测试,这是产品测试不具有的特点。
      此外,测试产品与测试项目在缺陷管理方面、测试策略制定都会有很大不同,测试管理者应该结合具体的环境,恰如其分的完成工作。
    60. 用户共同测试(UAT测试)的注意点有哪些
      软件产品在投产前,通常都会进行用户验收测试。如果用户验收测试没有通过,直接结果就是那不到“Money”,间接影响是损害了公司的形象,而后者的影响往往更严重。根据作者的经验,用户验收测试一定要让用户满意。
      实际上用户现场测试更趋于是一种演示。在不欺骗用户的前提下,我们向用户展示我们软件的优点,最后让“上帝”满意并欣然掏出“银子”才是我们的目标。因此用户测试要注意下面的事项:
      (1)用户现场测试不可能测试全部功能,因此要测试核心功能。这需要提前做好准备,这些核心功能一定要预先经过测试,证明没有问题才可以和用户共同进行测试。测试核心模块的目的是建立用户对软件的信心。当然如果这些模块如果问题较多,不应该进行演示。
      (2)如果某些模块确实有问题,我们可以演示其它重要的业务功能模块,必要时要向用户做成合理的解释。争得时间后,及时修改缺陷来弥补。
      (3)永远不能欺骗用户,蒙混过关。道理很简单,因为软件是要给用户用的,问题早晚会暴露出来,除非你可以马上修改。
      和用户进行测试还要注意各种交流技巧,争取不但短期利益得到了满足,还要为后面得合作打好基础。
    61. 如何编写提交给用户的测试报告
      随着测试工作越来越受重视,开发团队向客户提供测试文档是不可避免的事情。很多人会问:“我们可以把工作中的测试报告提供给客户吗?”答案是否定的。因为提供内部测试报告,可能会让客户失去信心,甚至否定项目。
      测试报告一般分为内部测试报告和外部测试报告。内部报告是我们在测试工作中的项目文档,反映了测试工作的实施情况,这里不过多讨论,读者可以参考相关教材。这里主要讨论一下外部测试报告的写法,一般外部测试报告要满足下面几个要求:
      -根据内部测试报告进行编写,一般可以摘录;
      -不可以向客户报告严重缺陷,即使是已经修改的缺陷,开发中的缺陷也没有必要让客户知道;
      -报告上可以列出一些缺陷,但必须是中级的缺陷,而且这些缺陷必须是修复的;
      -报告上面的内容尽量要真实可靠;
      -整个测试报告要仔细审阅,力争不给项目带来负面作用,尤其是性能测试报告。
      总之,外部测试报告要小心谨慎的编写。
    62. 测试工具在测试工作中是什么地位?
      国内的很多测试工程师对测试工具相当迷恋,尤其是一些新手,甚至期望测试工具可以取代手工测试。测试工具在测试工作中起的是辅助作用,一般用来提高测试效率。自动化测试弥补了手工测试的不足,减轻一定的工作量。实际上测试工具是无法替代大多数手工测试的,而一些诸如性能测试等自动化测试也是手工所不能完成的。
      对于自动测试技术,应当依据软件的不同情况来分别对待,一般自动技术会应用在引起大量重复性工作的地方、系统的压力点、以及任何适合使用程序解决大批量输入数据的地方。然后再寻找合适的自动测试工具,或者自己开发测试程序。一定不要为了使用测试工具而使用。
    63. 简述负载测试与压力测试的区别
      压力测试(Stress Testing)
      压力测试的主要任务就是获取系统正确运行的极限,检查系统在瞬间峰值负荷下正确执行的能力。例如,对服务器做压力测试时就可以增加并发操作的用户数量;或者不停地向服务器发送请求;或一次性向服务器发送特别大的数据等。看看服务器保持正常运行所能达到的最大状态。人们通常使用测试工具来完成压力测试,如模拟上万个用户从终端同时登录,这是压力测试中常常使用的方法。
      负载测试(Volume Testing)
      用于检查系统在使用大量数据的时候正确工作的能力,即检验系统的能力最高能达到什么程度。例如,对于信息检索系统,让它使用频率达到最大;对于多个终端的分时系统,让它所有的终端都开动。在使整个系统的全部资源达到“满负荷”的情形下,测试系统的承受能力。
    64. 写出bug报告流转的步骤,每步的责任人及主要完成的工作。
      (要结合自己实际的工作经验进行回答,不同公司略有区别)
      测试人员提交新的Bug入库,错误状态为New。
      高级测试员/测试经理验证错误,如果确认是错误,分配给开发组。设置状态为Open。如果不是错误,则拒绝,设置为Declined状态。
      开发经理分配bug至对应的模块开发人员。
      开发人员查询状态为Open的Bug,如果不是错误,则置状态为Declined;如果是Bug则修复并置状态为Fixed。不能解决的Bug,要留下文字说明及保持Bug为Open状态。
      对于不能解决和延期解决的Bug,不能由开发人员自己决定,一般要通过某种会议(评审会)通过才能认可。
      测试人员查询状态为Fixed的Bug,然后验证Bug是否已解决,如解决,置Bug的状态为Closed,如没有解决,置bug状态为Reopen。
    65. 出bug报告当中一些必备的内容。
      硬件平台和操作系统
      测试应用的硬件平台(Platform),通常选择“PC”。
      测试应用的操作系统平台(OS)。
      a) 版本
      提交缺陷报告时通过该字段标识此缺陷存在于被测试软件的哪个版本。
      b) Bug报告优先级
      c) Bug状态
      d) Bug的编号
      e) 发现人
      f) 提交人
      g) 指定处理人
      h) 概述
      i) 从属关系
      j) 详细描述
      k) 严重程度
      l) 所属模块
      m) 附件
      n) 提交日期
    66. 开发人员老是犯一些低级错误怎么解决?
      这种现象在开发流程不规范的团队里特别常见,尤其是一些“作坊式”的团队里。解决这种问题一般从两个方面入手:
      一方面从开发管理入手,也就是从根源来解决问题。可以制定规范的开发流程,甚至可以制定惩罚制度,还有就是软件开发前做好规划设计。
      另一方面就是加强测试,具体做法就是加强开发人员的自己测试,把这些问题“消灭”在开发阶段,这是比较好的做法,读者可以参考第13章试案例分析的“13.1.2缺陷反复出现,谁的责任”小节,13.1.2专门讨论了这类问题的方法。
      此外,还可以通过规范的缺陷管理来对开发人员进行控制,比如测试部门整理出常见的缺陷,让开发人员自己对照进行检查,以减少这类低级错误的发生。
      开发人员犯错误是正常的现象,作为测试人员一定不能抱怨,要认认真真的解决问题才是上策。
    1. 为什么要在一个团队中开展软件测试工作
      因为没有经过测试的软件很难在发布之前知道该软件的质量,就好比ISO质量认证一样,测试同样也需要质量的保证,这个时候就需要在团队中开展软件测试的工作。在测试的过程发现软件中存在的问题,及时让开发人员得知并修改问题,在即将发布时,从测试报告中得出软件的质量情况。
    2. 您在以往的测试工作中都曾经具体从事过哪些工作?其中最擅长哪部分工作?
      (根据项目经验不同,灵活回答即可)
      我曾经做过web测试,后台测试,客户端软件,其中包括功能测试,性能测试,用户体验测试。最擅长的是功能测试
    3. 您所熟悉的测试用例设计方法都有哪些?请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。
      1.等价类划分
        划分等价类: 等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类.
        2.边界值分析法
        边界值分析方法是对等价类划分方法的补充。测试工作经验告诉我,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部.因此针对各种边界情况设计测试用例,可以查出更多的错误.
        使用边界值分析方法设计测试用例,首先应确定边界情况.通常输入和输出等价类的边界,就是应着重测试的边界情况.应当选取正好等于,刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据.
      3.错误推测法
        基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法.
        错误推测方法的基本思想: 列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据他们选择测试用例. 例如, 在单元测试时曾列出的许多在模块中常见的错误. 以前产品测试中曾经发现的错误等, 这些就是经验的总结. 还有, 输入数据和输出数据为0的情况. 输入表格为空格或输入表格只有一行. 这些都是容易发生错误的情况. 可选择这些情况下的例子作为测试用例.
      4.因果图方法
        前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系, 相互组合等. 考虑输入条件之间的相互组合,可能会产生一些新的情况. 但要检查输入条件的组合不是一件容易的事情, 即使把所有输入条件划分成等价类,他们之间的组合情况也相当多. 因此必须考虑采用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例. 这就需要利用因果图(逻辑模型). 因果图方法最终生成的就是判定表. 它适合于检查程序输入条件的各种组合情况.
    4. 请以您以往的实际工作为例,详细的描述一次测试用例设计的完整的过程。
      就说最近的这次网站功能的测试吧

        首先:得到相关文档(需求文档和设计文档),理解需求和设计设计思想后,想好测试策略(测试计划简单点就OK了),考虑到测试环境,测试用例,测试时间等问题。
        第二步:设计测试用例,测试策略是:把网站部分的功能点测试完,然后在进行系统测试(另外个模块呢有另一个测试人员负责,可以进行联调测试),网站模块的测试基本是功能测试和界面测试(用户并发的可能性很小,所以不考虑):这次的网站的输入数据呢是使用数据库中的某张表记录,如果表中某一数据记录中新加进来的(还没有被处理的,有个标志位),网站启动后会立刻去刷那张表,得到多条数据,然后在进行处理。处理过程中,会经历3个步骤,网站才算完成了它的任务。有3个步骤呢,就可以分别对  这3个步骤进行测试用例的设计,尽量覆盖到各种输入情况(包括数据库中的数据,用户的输入等),得出了差不多50个用例。界面测试,也就是用户看的到的地方,包括发送的邮件和用户填写资料的页面展示。
        第三步:搭建测试环境(为什么这个时候考虑测试环境呢?因为我对网站环境已经很熟了,只有有机器能空于下来做该功能测试就可以做了),因为网站本身的环境搭建和其他的系统有点不同,它需要的测试环境比较麻烦,需要web服务器(Apache,tomcat),不过这次需求呢,网站部分只用到了tomcat,所以只要有tomcat即可
        第四步:执行测试
    5. 您以往是否曾经从事过性能测试工作?如果有,请尽可能的详细描述您以往的性能测试工作的完整过程。
      (以自己最熟悉的性能测试项目为例)
      是的,曾经做过网站方面的性能测试,虽然做的时间并不久(2个月吧),当时呢,是有位网站性能测试经验非常丰富的前辈带着我一起做。
      性能测试类型包括负载测试,强度测试,容量测试等
        负载测试:负载测试是一种性能测试指数据在超负荷环境中运行,程序是否能够承担。
        强度测试: 强度测试是一种性能测试,他在系统资源特别低的情况下软件系统运行情况
        容量测试:确定系统可处理同时在线的最大用户数
        在网站流量逐渐加大的情况下,开始考虑做性能测试了,首先要写好性能测试计划,根据运营数据得出流量最大的页面(如果是第一次的话,一般是首页,下载页,个人帐户页流量最大,而且以某种百分比),
        Web服务器指标指标:
        * Avg Rps: 平均每秒钟响应次数=总请求时间 / 秒数;
        * Successful Rounds:成功的请求;
        * Failed Rounds :失败的请求;
        * Successful Hits :成功的点击次数;
        * Failed Hits :失败的点击次数;
        * Hits Per Second :每秒点击次数;
        * Successful Hits Per Second :每秒成功的点击次数;
        * Failed Hits Per Second :每秒失败的点击次数;
        * Attempted Connections :尝试链接数;
    6. 你对测试最大的兴趣在哪里?为什么?
      最大的兴趣就是测试有难度,有挑战性!做测试越久越能感觉到做好测试有多难。曾经在无忧测试网上看到一篇文章,是关于如何做好一名测试工程师。一共罗列了11,12点,有部分是和人的性格有关,有部分需要后天的努力。但除了性格有关的1,2点我没有把握,其他点我都很有信心做好它。
    7. 你以前工作时的测试流程是什么?
      (灵活回答)
      公司对测试流程没有规定如何做,但每个测试人员都有自己的一套测试流程。我说下我1年来不断改正(自己总结,吸取同行的方法)后的流程吧。需求评审(有开发人员,产品经理,测试人员,项目经理)->需求确定(出一份确定的需求文档)->开发设计文档(开发人员在开始写代码前就能输出设计文档)->想好测试策略,写出测试用例->发给开发人员和测试经理看看(非正式的评审用例)->接到测试版本->执行测试用例(中间可能会补充用例)->提交bug(有些bug需要开发人员的确定(严重级别的,或突然发现的在测试用例范围之外的,难以重现的),有些可以直接录制进TD)->开发人员修改(可以在测试过程中快速的修改)->回归测试(可能又会发现新问题,再按流程开始跑)。
    8. 当开发人员说不是BUG时,你如何应付?
      开发人员说不是bug,有2种情况,一是需求没有确定,所以我可以这么做,这个时候可以找来产品经理进行确认,需不需要改动,3方商量确定好后再看要不要改。二是这种情况不可能发生,所以不需要修改,这个时候,我可以先尽可能的说出是BUG的依据是什么?如果被用户发现或出了问题,会有什么不良结果?程序员可能会给你很多理由,你可以对他的解释进行反驳。如果还是不行,那我可以给这个问题提出来,跟开发经理和测试经理进行确认,如果要修改就改,如果不要修改就不改。其实有些真的不是bug,我也只是建议的方式写进TD中,如果开发人员不修改也没有大问题。如果确定是bug的话,一定要坚持自己的立场,让问题得到最后的确认。
    9. 软件的构造号与版本号之间的区别?BVT(BuildVerificationTest)
      版本控制命名格式: 主版本号.子版本号[.修正版本号[.编译版本号 ]]
      Major.Minor [.Revision[.Build]]
      应根据下面的约定使用这些部分:
      Major :具有相同名称但不同主版本号的程序集不可互换。例如,这适用于对产品的大量重写,这些重写使得无法实现向后兼容性。
      Minor :如果两个程序集的名称和主版本号相同,而次版本号不同,这指示显著增强,但照顾到了向后兼容性。例如,这适用于产品的修正版或完全向后兼容的新版本。
      Build :内部版本号的不同表示对相同源所作的重新编译。这适合于更改处理器、平台或编译器的情况。
      Revision :名称、主版本号和次版本号都相同但修订号不同的程序集应是完全可互换的。这适用于修复以前发布的程序集中的安全漏洞。
      BVT(BuildVerificationTest):
      作为Build的一部分,主要是通过对基本功能、特别是关键功能的测试,保证新增代码没有导致功能失效,保证版本的持续稳定。实现BVT方式是有以下几种:1、测试人员手工验证关键功能实现的正确性。特点:这是传统开发方法中,通常采用的方式。无需维护测试脚本的成本,在测试人力资源充足,测试人员熟悉业务、并对系统操作熟练情况下效率很高,比较灵活快速。缺点:人力成本较高;对测试人员能力有一定要求;测试人员面对重复的工作,容易产生疲倦懈怠,从而影响测试质量。2、借助基于GUI的自动化功能测试工具来完成,将各基本功能操作录制成测试脚本,每次回放测试脚本验证功能实现的正确性。特点:能够模拟用户操作完成自动的测试,从UI入口到业务实现,每一层的代码实现都经过验证;节约人力成本;降低测试人员重复劳动的工作量,机器不会疲倦;缺点:对于UI变动比较频繁的系统来说,这种方式的维护成本很高,实施起来非常困难。另外,在项目周期较短且后续无延续性或继承的情况下,也不推荐使用此方式。3、由开发人员通过自动化测试工具完成业务层的BVT测试。特点:通过对业务层关键功能的持续集成测试,保证系统功能的持续稳定。可以结合DailyBuild,做为Build的一部分,自动实现并输入BVT报告。缺点:仅对业务规则实现的正确性进行了测试,对表现层无法测试到,对于诸如:前台页面控件各种事件响应、页面元素变化等方面的问题无法保证。

    加粗样式

    展开全文
  • 关注公众号:GitChat 技术杂谈,一本正经的讲技术 第十一章WebShell检测WebShell就是以ASP、PHP、JSP或者CGI等文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。黑客在入侵了一个网站后,通常会将...

    GitChat 作者:兜哥
    原文: 基于机器学习的 Webshell 发现技术探索
    关注公众号:GitChat 技术杂谈,一本正经的讲技术

    第十一章WebShell检测

    WebShell就是以ASP、PHP、JSP或者CGI等文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。黑客在入侵了一个网站后,通常会将ASP或PHP后门文件与网站服务器web目录下正常的网页文件混在一起,然后就可以使用浏览器来访问ASP或者PHP后门,得到一个命令执行环境,以达到控制网站服务器的目的。顾名思义,“web”的含义是显然需要服务器开放web服务,“shell”的含义是取得对服务器某种程度上操作权限。WebShell常常被称为入侵者通过网站端口对网站服务器的某种程度上操作的权限。由于WebShell其大多是以动态脚本的形式出现,也有人称之为网站的后门工具。

    在攻击链模型中,整个攻击过程分为以下几个步骤:

    • Reconnaissance(踩点)

    • Weaponization(组装)

    • Delivery(投送)

    • Exploitation(攻击)

    • Installation(植入)

    • C2(控制)

    • Actions (行动

    enter image description here

    攻击链模型

    在针对网站的攻击中,通常是利用上传漏洞,上传WebShell,然后通过WebShell进一步控制web服务器,对应攻击链模型是Install和C2环节。

    常见的WebShell检测方法主要有以下几种:

    静态检测,通过匹配特征码,特征值,危险函数函数来查找WebShell的方法,只能查找已知的WebShell,并且误报率漏报率会比较高,但是如果规则完善,可以减低误报率,但是漏报率必定会有所提高。

    动态检测,执行时刻表现出来的特征,比如数据库操作、敏感文件读取等。

    语法检测,根据PHP语言扫描编译的实现方式,进行剥离代码、注释,分析变量、函数、字符串、语言结构的分析方式,来实现关键危险函数的捕捉方式。这样可以完美解决漏报的情况。但误报上,仍存在问题。

    统计学检测,通过信息熵、最长单词、重合指数、压缩比等检测。

    本章主要以常见的WebShell数据集为例子介绍基于WebShell文件特征的检测技术。 介绍WebShell检测使用的数据集以及对应的特征提取方法,介绍使用的模型以及对应的验证结果,包括朴素贝叶斯和深度学习的MLP、CNN。基于WebShell文件访问特征的检测方法不在本章范围内。

    数据集

    数据集包含WebShell样本2616个,开源软件PHP文件9035个。

    WebShell数据来自互联网上常见的WebShell样本,数据来源来自github上相关项目,为了演示方便,全部使用了基于PHP的WebShell样本。

    enter image description here

    github上WebShell相关项目

    白样本主要使用常见的基于PHP的开源软件,主要包括以下几种。

    WordPress

    WordPress是一种使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站。也可以把 WordPress当作一个内容管理系统(CMS)来使用。

    WordPress是一款个人博客系统,并逐步演化成一款内容管理系统软件,它是使用PHP语言和MySQL数据库开发的。用户可以在支持 PHP 和 MySQL数据库的服务器上使用自己的博客。

    WordPress有许多第三方开发的免费模板,安装方式简单易用。不过要做一个自己的模板,则需要你有一定的专业知识。比如你至少要懂的标准通用标记语言下的一个应用HTML代码、CSS、PHP等相关知识。WordPress官方支持中文版,同时有爱好者开发的第三方中文语言包,如wopus中文语言包。WordPress拥有成千上万个各式插件和不计其数的主题模板样式。

    项目地址为:https://wordpress.org/

    enter image description here

    WordPress主页

    PHPCMS

    PHPCMS是一款网站管理软件。该软件采用模块化开发,支持多种分类方式,使用它可方便实现个性化网站的设计、开发与维护。它支持众多的程序组合,可轻松实现网站平台迁移,并可广泛满足各种规模的网站需求,可靠性高,是一款具备文章、下载、图片、分类信息、影视、商城、采集、财务等众多功能的强大、易用、可扩展的优秀网站管理软件。

    PHPCMS由国内80后知名创业者钟胜辉(网名:淡淡风)于2005年创办,是国内知名的站长建站工具。2009年,PHPCMS创办人钟胜辉离开PHPCMS,创办国内针对媒体领域的CMS产品CmsTop(思拓合众)。

    项目地址为:http://www.phpcms.cn/

    enter image description here

    phpcms主页

    phpMyAdmin

    phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,也就是于远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由phpMyAdmin建立常用的php语法,方便编写网页时所需要的sql语法正确性。

    项目地址为:https://www.phpMyAdmin.net/

    enter image description here

    phpMyAdmin主页

    Smarty

    Smarty是一个使用PHP写出来的模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目的就是要使PHP程序员同前端人员分离,使程序员改变程序的逻辑内容不会影响到前端人员的页面设计,前端人员重新修改页面不会影响到程序的程序逻辑,这在多人合作的项目中显的尤为重要。

    项目地址为:https://github.com/smarty-php/smarty

    Yii

    Yii是一个基于组件的高性能PHP框架,用于开发大型Web应用。Yii采用严格的OOP编写,并有着完善的库引用以及全面的教程。从 MVC,DAO/ActiveRecord,widgets,caching,等级式RBAC,Web服务,到主题化,I18N和L10N,Yii提供了今日Web 2.0应用开发所需要的几乎一切功能。事实上,Yii是最有效率的PHP框架之一。

    Yii是一个高性能的PHP5的web应用程序开发框架。通过一个简单的命令行工具 yiic 可以快速创建一个web应用程序的代码框架,开发者可以在生成的代码框架基础上添加业务逻辑,以快速完成应用程序的开发。

    项目地址为:http://www.yiiframework.com/

    enter image description here

    Yii主页

    特征提取

    方法一:词袋&TF-IDF模型

    我们使用最常见的词袋模型&TF-IDF提取文件特征。

    把一个PHP文件作为一个完整的字符串处理,定义函数load_one_file加载文件到一个字符串变量中返回。

    def load_one_file(filename):
    ​    x=""with open(filename) as f:
    ​        for line in f:
    ​            line = line.strip('\r')
    ​            x+=line
    ​    return x

    由于开源软件中包含大量图片、js等文件,所以遍历目录时需要排除非php文件。另外开源软件的目录结构相对复杂,不像前面章节的垃圾邮件、垃圾短信等是平面目录结构,所以要求我们递归访问指定目录并加载指定文件。

    def load_files_re(dir):
    ​    files_list = []
    ​    g = os.walk(dir)
    ​    for path, d, filelist in g:
    ​        for filename in filelist:
    ​            if filename.endswith('.php'):
    ​                fulepath =
    os.path.join(path, filename)
    ​                print "Load %s"
    % fulepath
    ​                t = load_file(fulepath)
    ​                files_list.append(t)
    ​    return files_list

    加载搜集到的WebShell样本,并统计样本个数,将WebShell样本标记为1。

    WebShell_files_list = load_files_re(WebShell_dir)
    y1=[1]*len(WebShell_files_list)
    black_count=len(WebShell_files_list)

    加载搜集到的开源软件样本,并统计样本个数,将开源软件样本标记为0。

    wp_files_list =load_files_re(whitefile_dir)
    y2=[0]*len(wp_files_list)
    white_count=len(wp_files_list)

    将WebShell样本和开源软件样本合并。

    x=WebShell_files_list+wp_files_list
    y=y1+y2

    使用2-gram提取词袋模型,并使用TF-IDF进行处理。

    CV = CountVectorizer(ngram_range=(2, 2),
    decode_error="ignore",max_features=max_features,
    token_pattern = r'\b\w+\b',min_df=1, max_df=1.0)
    x=CV.fit_transform(x).toarray()
    transformer = TfidfTransformer(smooth_idf=False)
    x_tfidf = transformer.fit_transform(x)
    x = x_tfidf.toarray()

    所谓的2-gram是词袋模型的一个细分类别,也有的机器学习书籍里面单独把2-gram或者说n-gram作为单独的模型介绍。n-gram基于这样一种假设,第n个单词只和它前面的n-1个词有关联,每n个单词作为一个处理单元。

    enter image description here

    2-gram举例

    通过设置CountVectorizer函数的ngram_range参数和token_pattern即可实现n-gram,其中ngram_range表明n-gram的n取值范围,如果是2-gram设置成(2,2)即可。token_pattern表明词切分的规则,通常设置为r'\b\w+\b'即可。

    划分训练集与测试集,测试集的比例为40%。

    x_train, x_test, y_train,y_test = train_test_split(x, y, test_size=0.4, random_state=0)

    方法二:opcode&n-gram模型

    opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定。除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数。这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等。通常opcode还有另一种称谓:字节码(byte codes)。 例如Java虚拟机(JVM),.NET的通用中间语言(CIL: Common Intermeditate Language)等等。PHP中的opcode则属于前面介绍中的后着,PHP是构建在Zend虚拟机(Zend VM)之上的。

    PHP的opcode就是Zend虚拟机中的指令,常见的opcode如下图所示。

    enter image description here

    PHP常见opcode

    通常可以通过PHP的VLD(Vulcan Logic Dumper,逻辑代码展现)是扩展来查看PHP文件对应的opcode。

    wget http://pecl.php.net/get/vld-0.13.0.tgz
    
    tar zxvf vld-0.13.0.tgz
    
    cd ./vld-0.13.0
    
    /configure--with-php-config=/usr/local/php/bin/php-config --enable-vld
    
    make && makeinstall

    然后在php.ini配置文件中添加extension=vld.so 用于激活VLD,其中php.ini默认位置位于lib目录中。VLD还可以从github上下载并安装,步骤为:

    git clone https://github.com/derickr/vld.git
    
    cd vld
    
    phpize
    
    ./configure
    
    make && makeinstall

    VLD项目的主页为:

    http://pecl.php.net/package/vld

    enter image description here

    VLD扩展下载主页

    以PHP文件hello.php为例:

     <?php
    
       echo"Hello World";
    
       $a = 1 +1;
    
       echo $a;
    
    ?>

    通过使用PHP的VLD扩展查看对应的opcode,其中vld.active=1表示激活VlD,vld.execute=0表示只解析不执行。

    php -dvld.active=1 -dvld.execute=0hello.php

    显示结果为:

    function name:  (null)
    
    number of ops:  5
    
    compiled vars:  !0 = $a
    
    line     #* E I O op                         fetch          ext  return  operands
    
    \-----------------------------------------------------------------------------
    
       2     0  E >  ECHO                                              'Hello+World'
    
       3     1       ADD                                            ~0      1, 12       ASSIGN                                                 !0, ~0
    
       4     3       ECHO                                                   !0
    
       6     4     > RETURN                                                 1
    
    
    
    branch: #  0; line:    2-    6; sop:     0; eop:     4; out1:  -2
    
    path #1: 0,

    对应的opcode为:

    ECHO     
    
    ADD       
    
    ASSIGN
    
    ECHO 

    以一个常见的一句话木马为例:

    <?phpecho $_GET['r'];
    
    ?>

    通过VLD查看的结果为:

    function name:  (null)
    
    number of ops:  5
    
    compiled vars:  none
    
    line     #* E I O op                         fetch          ext  return  operands
    
    \-------------------------------------------------------------------------------------
    
       2     0  E >  FETCH_R                     global              $0     '_GET'1       FETCH_DIM_R                                    $1      $0, 'r'2       ECHO                                                   $1
    
       4     3       ECHO                                                   '+%0A'4     > RETURN                                                 1
    
    
    
    branch: #  0; line:    2-    4; sop:     0; eop:     4; out1:  -2
    
    path #1: 0, 

    对应的opcode为:

    FETCH_R
    
    FETCH_DIM_R 
    
    ECHO 
    
    ECHO
    
    RETURN  

    使用2-gram对opcode进行分组,结果为:

    (FETCH_R, FETCH_DIM_R) (FETCH_DIM_R, ECHO) (ECHO, ECHO) (ECHO, RETURN)

    完整的处理流程为:

    enter image description here

    PHP代码处理流程图

    代码实现方面,首先使用VLD处理PHP文件,把处理的结果保存在字符串中。

    t=""
    cmd=php_bin+" -dvld.active=1 -dvld.execute=0 "+file_path
    output=commands.getoutput(cmd)

    PHP的opcode都是由大写字母和下划线组成的单词,使用findall函数从字符串中提取全部满足条件的opcode,并以空格连接成一个新字符串。

    t=output
    tokens=re.findall(r'\s(\b[A-Z_]+\b)\s',output)
    t=" ".join(tokens)

    遍历读取指定目录下全部PHP文件,保存其对应的opcode字符串。

    def
    load_files_opcode_re(dir):
    ​    files_list = []
    ​    g = os.walk(dir)
    ​    for path, d, filelist in g:for filename in filelist:if filename.endswith('.php')
    :
    ​                fulepath =
    os.path.join(path, filename)
    ​                print "Load %s
    opcode" % fulepath
    ​                t =
    load_file_opcode(fulepath)
    ​                files_list.append(t)
    ​    return files_list

    依次读取保存WebShell样本以及正常PHP文件的目录,加载对应的opcode字符串,其中标记WebShell为1,正常PHP文件为0。

    WebShell_files_list
    = load_files_re(WebShell_dir)
    y1=[1]*len(WebShell_files_list)
    black_count=len(WebShell_files_list)
    wp_files_list =load_files_re(whitefile_dir)
    y2=[0]*len(wp_files_list)
    white_count=len(wp_files_list)

    使用2-gram处理opcode字符串,其中通过设置ngram_range=(2, 2)就可以达到使用2-gram的目的,同理如果使用3-gram设置ngram_range=(3, 3)即可。

    CV
    = CountVectorizer(ngram_range=(2, 2), decode_error="ignore",max_features=max_features,
    token_pattern = r'\b\w+\b',min_df=1, max_df=1.0)
    x=CV.fit_transform(x).toarray()

    使用TF-IDF进一步处理。

    transformer
    = TfidfTransformer(smooth_idf=False)
    x_tfidf = transformer.fit_transform(x)
    x = x_tfidf.toarray()

    另外,开发调试阶段会频繁解析相同的PHP文件获取对应的opcode,可以使用PHP的opcode缓存技术提高效率。opcode缓存技术[6]可以有效减少不必要的编译步骤,减少cpu和内存的消耗。正常情况下PHP代码的执行过程会经历文本扫描、语法解析、创建opcode、执行opcode这几部。

    enter image description here

    未使用opcode缓存的情况下PHP代码执行过程

    使用了opcode缓存技术后,对于曾经解析过的PHP文件,opcode会缓存下来,遇到同样内容的PHP文件就可以直接进入opcode执行阶段。

    enter image description here

    使用opcode缓存的情况下PHP代码执行过程.

    开启opcode的缓存功能非常方便,PHP 5.5.0以后在编译PHP源码的时候开启–enable-opcache,编译选型为:

    ./configure--prefix=/opt/php --enable-opcache
    
    config.status:creating php5.spec
    
    config.status:creating main/build-defs.h
    
    config.status:creating scripts/phpize
    
    config.status:creating scripts/man1/phpize.1
    
    config.status:creating scripts/php-config
    
    config.status:creating scripts/man1/php-config.1
    
    config.status:creating sapi/cli/php.1
    
    config.status:creating sapi/cgi/php-cgi.1
    
    config.status:creating ext/phar/phar.1
    
    config.status:creating ext/phar/phar.phar.1
    
    config.status:creating main/php_config.h
    
    config.status:executing default commands

    编译安装

    make-j4 & make install

    修改配置文件php.ini,加载对应的动态库。

    zend_extension=/full/path/to/opcache.so

    配置opcode缓存对应的配置选项,典型的配置内容如下所示。

    engine= On
    
    zend_extension=/lib/php/extensions/no-debug-non-zts-20131226/opcache.so
    
    opcache.memory_consumption=128
    
    opcache.interned_strings_buffer=8
    
    opcache.max_accelerated_files=4000
    
    opcache.revalidate_freq=60
    
    opcache.fast_shutdown=1
    
    opcache.enable_cli=1
    
    opcache.enable=1

    方法三:opcode调用序列模型

    在opcode&n-gram模型中,我们假设第n个opcode之与前n-1个opcode有关联,现在我们以一个更加长的时间范围来看opcode的调用序列,把整个PHP的opcode当成一个调用序列来分析,为了便于程序处理,截取整个文件opcode的固定长度的opcode序列分析,超过固定长度的截断,不足的使用0补齐。以一个常见的一句话木马为例:

    <?phpecho $_GET['r'];
    
    ?>

    enter image description here

    图11-13 解析PHP文件获取opcode调用序列的过程

    该文件通过VLD处理获得对应的opcode为:

    FETCH_R
    
    FETCH_DIM_R 
    
    ECHO 
    
    ECHO
    
    RETURN  

    获得对应的opcode序列为:

    (FETCH_R,FETCH_DIM_R,ECHOECHORETURN

    模型训练与验证

    方法一:朴素贝叶斯算法

    使用朴素贝叶斯算法,特征提取使用词袋&TF-IDF模型,完整的处理流程为:

    1. 将WebShell样本以及常见PHP开源软件的文件提取词袋。

    2. 使用TF-IDF处理。

    3. 随机划分为训练集和测试集。

    4. 使用朴素贝叶斯算法在训练集上训练,获得模型数据。

    5. 使用模型数据在测试集上进行预测。

    6. 验证朴素贝叶斯算法预测效果。

    enter image description here

    特征提取使用词袋&TF-IDF模型算法使用朴素贝叶斯的流程图

    实例化朴素贝叶斯算法,并在训练集上训练数据,针对测试集进行预测。

    gnb = GaussianNB()
    gnb.fit(x_train,y_train)
    y_pred=gnb.predict(x_test)

    评估结果的准确度和TP、FP、TN、FN四个值。

    print metrics.accuracy_score(y_test, y_pred)
    print metrics.confusion_matrix(y_test, y_pred)

    在词袋最大特征数为15000的情况下,使用词袋&TF-IDF模型时,TP、FP、TN、FN矩阵如下表所示。

    表1-1 基于词袋&TF-IDF模型的朴素贝叶斯验证结果

    类型名称** 相关** 不相关**
    检索到 3566 52
    未检索到 71 972

    整个系统的准确率为94.92%,召回率为93.19%。

    完整输出结果为:

    metrics.accuracy_score:
    
    0.97361081313
    
    metrics.confusion_matrix:
    
    [[3566   52]
    
     [  71  972]]
    
    metrics.precision_score:
    
    0.94921875
    
    metrics.recall_score:
    
    0.931927133269
    
    metrics.f1_score:
    
    0.940493468795

    方法二:深度学习算法之MLP

    使用MLP算法,隐含层设计为2层,每次节点数分别为5和2。

    enter image description here
    MLP隐藏层设计

    使用MLP算法,特征提取使用词袋&TF-IDF模型,完整的处理流程为:

    1. 将WebShell样本以及常见PHP开源软件的文件提取词袋。

    2. 使用TF-IDF处理。

    3. 随机划分为训练集和测试集。

    4. 使用MLP算法在训练集上训练,获得模型数据。

    5. 使用模型数据在测试集上进行预测。

    6. 验证MLP算法预测效果。

    实例化MLP算法,并在训练集上训练数据,针对测试集进行预测。

    clf = MLPClassifier(solver='lbfgs',
    ​                    alpha=1e-5,
    ​                    hidden_layer_sizes =
    (5, 2),
    ​                    random_state = 1)
    print  clf
    clf.fit(x_train, y_train)
    y_pred = clf.predict(x_test)

    评估结果的TP、FP、TN、FN四个值。

    print metrics.accuracy_score(y_test, y_pred)
    print metrics.confusion_matrix(y_test, y_pred)

    评估结果的准确率与召回率以及F1分值。

    print "metrics.precision_score:"
    print metrics.precision_score(y_test, y_pred)
    print "metrics.recall_score:"
    print metrics.recall_score(y_test, y_pred)
    print "metrics.f1_score:"
    print metrics.f1_score(y_test,y_pred)

    在词袋最大特征数为15000且同时使用TF-IDF模型的情况下, TP、FP、TN、FN矩阵如下表所示。

    表1-2 基于词袋和TF-IDF模型的MLP验证结果

    类型名称** 相关** 不相关**
    检索到 3583 35
    未检索到 51 992

    准确率为96.59%,召回率为95.11%。

    完整输出结果为:

    metrics.confusion_matrix:
    
    [[3583   35]
    
     [  51  992]]
    
    metrics.precision_score:
    
    0.965920155794
    
    metrics.recall_score:
    
    0.951102588686
    
    metrics.f1_score:
    
    0.95845410628

    使用MLP算法,特征提取使用特征提取使用opcode&n-gram,完整的处理流程为:

    1. 将WebShell样本以及常见PHP开源软件的文件提取opcode.

    2. 使用n-gram处理。

    3. 随机划分为训练集和测试集。

    4. 使用MLP算法在训练集上训练,获得模型数据。

    5. 使用模型数据在测试集上进行预测。

    6. 验证MLP算法预测效果。

    特征提取使用opcode&n-gram,n取4,最大特征数取2000的情况下,TP、FP、TN、FN矩阵如下表所示。

    表1-3 基于opcode&n-gram模型的MLP验证结果

    类型名称** 相关** 不相关**
    检索到 2601 97
    未检索到 20 484

    准确率为83.30%,召回率为96.03%。

    完整输出结果为:

    0.963460337289
    
    metrics.confusion_matrix:
    
    [[2601   97]
    
     [  20 484]]
    
    metrics.precision_score:
    
    0.833046471601
    
    metrics.recall_score:
    
    0.960317460317
    
    metrics.f1_score:
    
    0.892165898618

    方法三:深度学习算法之CNN

    使用方法二中生成的opcode&n-gram数据,算法使用CNN,完整的处理流程为:

    1. 将WebShell样本以及常见PHP开源软件的文件提取opcode.

    2. 使用n-gram处理。

    3. 随机划分为训练集和测试集。

    4. 使用CNN算法在训练集上训练,获得模型数据。

    5. 使用模型数据在测试集上进行预测。

    6. 验证CNN算法预测效果。

    使用方法二中生成的opcode&n-gram数据,获得训练数据集和测试数据集。

    x, y = get_feature_by_opcode()
    
    x_train, x_test, y_train, y_test = train_test_split(x, y,test_size = 0.4, random_state = 0)

    将训练和测试数据进行填充和转换,不到最大长度的数据填充0,由于是二分类问题,把标记数据二值化。定义输入参数的最大长度为文档的最大长度。

    trainX = pad_sequences(trainX, maxlen=max_document_length,
    value=0.)
    testX = pad_sequences(testX, maxlen=max_document_length, value=0.)
    # Converting labels to binary vectors
    trainY = to_categorical(trainY, nb_classes=2)
    testY = to_categorical(testY, nb_classes=2)
    
    network = input_data(shape=[None,max_document_length],name='input')

    定义CNN模型,使用3个数量为128,长度分别为3、4、5的一维卷积函数处理数据。

    network = tflearn.embedding(network, input_dim=1000000,
    output_dim=128)
    branch1 = conv_1d(network, 128, 3, padding='valid', activation='relu',
    regularizer="L2")
    branch2 = conv_1d(network, 128, 4, padding='valid', activation='relu',
    regularizer="L2")
    branch3 = conv_1d(network, 128, 5, padding='valid', activation='relu',
    regularizer="L2")
    network = merge([branch1, branch2, branch3], mode='concat', axis=1)
    network = tf.expand_dims(network, 2)
    network = global_max_pool(network)
    network = dropout(network, 0.8)
    network = fully_connected(network, 2, activation='softmax')
    network = regression(network, optimizer='adam', learning_rate=0.001,
    loss='categorical_crossentropy', name='target')

    实例化CNN对象并进行训练数据,一共训练5轮。

    model = tflearn.DNN(network, tensorboard_verbose=0)
    model.fit(trainX, trainY,
    ​          n_epoch=5, shuffle=True,
    validation_set=0.1,
    ​          show_metric=True,
    batch_size=100,run_id="webshell")

    完整的CNN结构如下图所示。

    enter image description here

    用于识别WebShell的CNN结构图

    考核CNN对应的准确率、召回率,误报数和漏报数。

    print "metrics.accuracy_score:"
    print metrics.accuracy_score(y_test, y_pred)
    print "metrics.confusion_matrix:"
    print metrics.confusion_matrix(y_test, y_pred)
    print "metrics.precision_score:"
    print metrics.precision_score(y_test, y_pred)
    print "metrics.recall_score:"
    print metrics.recall_score(y_test, y_pred)
    print "metrics.f1_score:"
    print metrics.f1_score(y_test,y_pred)

    运行程序,经过5轮训练,在的情况下,使用opcode&n-gram模型时,n取4,TP、FP、TN、FN矩阵如下表所示。

    表1-4 基于opcode&n-gram模型的CNN验证结果

    类型名称** 相关** 不相关**
    检索到 2669 29
    未检索到 367 137

    整个系统的准确率为82.53%,召回率为27.18%。

    完整输出结果为:

    metrics.accuracy_score:
    
    0.87632729544
    
    metrics.confusion_matrix:
    
    [[2669   29]
    
     [ 367 137]]
    
    metrics.precision_score:
    
    0.825301204819
    
    metrics.recall_score:
    
    0.271825396825
    
    metrics.f1_score:
    
    0.408955223881

    使用方法三中生成的opcode序列数据,算法使用CNN,完整的处理流程为:

    1. 将WebShell样本以及常见PHP开源软件的文件提取opcode.

    2. 使用词袋处理,针对opcode进行编号,生成opcode序列。

    3. 随机划分为训练集和测试集。

    4. 使用CNN算法在训练集上训练,获得模型数据。

    5. 使用模型数据在测试集上进行预测。

    6. 验证CNN算法预测效果。

    使用方法三中opcode调用序列编码后的数据,获得训练数据集和测试数据集。

    x_train, x_test, y_train, y_test= get_feature_by_opcode ()

    运行程序,经过5轮训练,在opcode序列长度为3000的情况下,使用opcode序列模型时,TP、FP、TN、FN矩阵如下表所示。

    表1-5 基于opcode序列模型的CNN验证结果

    类型名称** 相关** 不相关**
    检索到 2685 13
    未检索到 89 415

    整个系统的准确率为96.96%,召回率为82.34%。

    完整输出结果为:

    metrics.accuracy_score:
    
    0.968144909432
    
    metrics.confusion_matrix:
    
    [[2685   13]
    
     [  89 415]]
    
    metrics.precision_score:
    
    0.969626168224
    
    metrics.recall_score:
    
    0.823412698413
    
    metrics.f1_score:
    
    0.890557939914

    本章小结

    本章基于搜集的PHP的WebShell数据集介绍了WebShell的识别方法。针对PHP的WebShell数据集,特征提取方法有词袋&TF-IDFopcode&n-gram以及opcode序列三种方法。训练模型介绍了朴素贝叶斯以及深度学习的MLP和CNN算法,其中基于基于词袋和TF-IDF模型的MLP准确率和召回率综合表现最佳,基于opcode序列模型的CNN准确率较高。



    实录:《刘焱: 基于机器学习发现 Webshell 实战解析》


    彩蛋

    重磅 Chat 分享:《一场 Chat 让你搞清 BAT 程序员的技术职级》

    分享人:
    胜洪宇,一线互联网公司前端技术组长,掘金签约作者,前端博客博主,所讲课程帮助超过20万前端小伙伴学习。
    Chat简介:
    很多程序员向往进入 BAT 这样的大型互联网公司,但是又不知道他们如何评定技术职级。
    - 阿里集团薪资职级如何划分?让你快速得到马云的青睐。
    - 在百度明白这些,你将快速晋升。
    - 腾讯职级里的小秘密,这样工作你会更强。
    一场 Chat 让你搞清 BAT 的技术评价体系,为您进入超级互联网公司指明技术方向,时刻做好准备!如果您希望您的技术团队也像这些互联网巨头一样强大,本场 Chat 我将帮您马上模仿建立有效的技术职级体系。

    想要免费参与本场 Chat ?很简单,「GitChat技术杂谈」公众号后台回复「BAT」

    这里写图片描述

    展开全文
  • 常用电脑硬件技术术语集锦

    千次阅读 2006-08-16 14:19:00
    比如微星新的815主板就可以在Internet上直接升级,只要你连上网络,系统将自动检测你的BIOS版本,如果发现你所使用的产品有新的BIOS文件,将会自动下载并更新,大大减少了用户的操作。使BIOS更加简单。    c....
  • 大数据技术常用的12个工具总结

    千次阅读 2019-05-25 16:20:04
    在大数据技术作为概念和业务战略出现的十年中,涌现了执行各种任务和流程的数千种工具。而推出这些工具的提供商都承诺可以为企业节省时间和成本,并发现能够让企业获利的商业洞察力。显然,大数据分析工具的市场正在...
  • 数据挖掘和知识发现技术方法及应用 一幅凝固的油画数据挖掘和知识发现技术方法及应用一幅凝固的油画 Keywords概念技术 统计分析statistical analysis决策树decision tree关联规则correlation rules基于...
  • NAT(地址转换技术)详解

    万次阅读 多人点赞 2018-03-17 16:31:35
    NAT技术的工作原理和特点 静态NAT 动态NAT NAT重载(经常应用到实际中) NAT技术的优缺点 优点 缺点 NAT穿越技术 应用层网关(ALG) ALG的实际应用 NAT技术的未来 参考文献 NAT产生背景 今天,无数...
  • 本文是我最近读书笔记的一篇文章,主要是阅读《淘宝技术这十年》的第一部分,主要包括淘宝网的技术流程和基础介绍,希望文章对大家有所帮助,同时记录自己最近学习的内容。我似乎是2007年初中看《赢在中国》的时候...
  • 物联网开发技术

    万次阅读 多人点赞 2018-04-12 10:44:17
    作为互联网技术的进化,物联网开发并非孤立的技术栈,而是向上承接了互联网,向下统领了嵌入式硬件开发的一个承上启下的全栈开发技术。 虽然我们并不能预测物联网技术栈最终的样子:统一的开发语言是 JavaScript ...
  • 计算机科学与技术专业:主要学什么? 本文主要包括如下内容: 程序员职位要求 CS 专业课程列表 怎样寻找资源学习? 程序员高薪排行榜 程序员职位要求 看课程之前,我们先来看看 BAT 的招聘岗位 JD: 新...
  • 常用数据科学方法总结梳理笔记

    千次阅读 2019-05-10 16:27:06
    常用数据科学方法 【未经允许,不得转载】 ...
  • 程序员的自我进化:技术的广度与深度怎么权衡 ...我们都希望自己的技术既有广度又有深度,但事实上,鱼与熊掌不可兼得,在有限的时间和精力里,我们不可能掌握所有的技术,而且技术的更新速度很快。因此,我们需要有...
  • 下面根据常用技术选型套路,来说明如何进行技术选型。文中以工作流引擎技术选型为例详细说明。(一)了解内部情况,确定问题范围不确定“问题”就无所谓“解”。我们分析了解到电子政务领域的各种活动中,工作流程...
  • Android开发常用开源框架

    万次阅读 多人点赞 2018-08-22 11:37:41
    Android开发常用开源框架2 Android开发常用开源框架3 GitHub上最火的Android开源项目,所有开源项目都有详细资料和配套视频 2017年伊始,你需要尝试的25个Android第三方库 Android开发常用第三...
  • 常用的推荐算法解析

    万次阅读 多人点赞 2016-04-28 15:40:24
    传统的搜索技术已经不能满足用户对信息发现的需求,原因有多种,可能是用户很难用合适的关键词来描述自己的需求,也可能用户需要更加符合他们兴趣和喜好的结果,又或是用户无法对自己未知而又可能感兴趣的信息做出...
  • , 我升级以后, 发现我的代码编译都通不过了, 原来mysql 把MysqlConnectionImpl 这个类名改成了 MysqlConnectionJDBC4Impl , 你看看, 你整天吹嘘着 要面向接口编程, 不要面向实现编程 , 但是你自己设计的东西...
  • 一、安全扫描技术1.1 安全扫描技术概念1、安全扫描技术指手工或使用特定的软件工具(安全扫描器),对系统脆弱性进行评估,寻找可能对系统造成损害的安全漏洞。2、安全扫描技术分为系统扫描和网络扫描两大类。 (1)...
  • 技术博客那点事

    千次阅读 多人点赞 2019-02-16 18:57:18
    前言 写文章是一个短期收益少,长期收益...在IT行业内,技术博客是了解一个开发者最好的方式之一,特别是当你没有一张足够分量的文凭或者一段出彩的工作经历时,你就应该沉下心来好好打磨自己技术,打造自己的博客。...
  • 机器学习简介及常用算法

    万次阅读 2016-12-15 10:02:09
    类比学习在人类科学技术发展史上起着重要作用,许多科学发现就是通过类比得到的。例如著名的卢瑟福类比就是通过将原子结构(目标域)同太阳系(源域)作类比,揭示了原子结构的奥秘。 5)基于解释的学习 ...
  • 谷歌三大核心技术

    万次阅读 2017-03-27 10:52:43
    转自:http://blog.csdn.net/hguisu/article/details/7244798 转自:http://blog.csdn.net/hguisu/article/details/7244981 转自:... 本文转载了Google的三大核心技术,作为学习的记录需要的时候及
  • 高效存储技术研究

    万次阅读 热门讨论 2010-12-08 21:29:00
    数据压缩、重复数据删除、自动精简配置、自动分层存储、存储虚拟化等高效存储技术有效解决或缓解了这些难题。然而,目前还没有从根本上解决,挑战和压力依然很巨大,我们期待高密度、超低能耗、高可靠的存储硬件技术...
  • 技术加速隐私暴露,如何应对?

    千次阅读 2020-09-17 10:52:10
    技术加速隐私暴露,如何应对?(一) 原创数据玩家一个数据玩家的自我修养2019-10-09 收录于话题 #新技术与隐私保护 8个 点击上方蓝字关注数据玩家 正文约4000字,读完需11分钟 序 最近的大数据...
  • 全面深入学习OLE技术

    千次阅读 2009-11-03 10:51:00
    全面深入学习OLE技术引言(问题的提出)1.如何将同步软件的联系人/日历/任务/邮件等信息导入到微软的OutLook软件中为了解决此问题,就需要用到微软的OLE技术。涉及相关技术有:OLE,OLE Automation,ActiveX,COM等技术...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,956
精华内容 33,582
关键字:

常用的事实发现技术