灌水 记一次面试经历

测试老菜 · 2018年12月22日 · 3152 次阅读

背景

2018 年的冬天很冷,整个行业都不景气,很多公司面临裁员、倒闭。我们公司也没能逃过此劫,公司融资不到位欠薪 2 个月,实在没有办法,楼主也开始加入找工作的大军。在招聘网站上投了好几个自己感兴趣的公司,也仅仅收到一个面试邀请,面试结果也不理想,被刷了。在这里给大家分享下面试题。

面试题

面试主要考察了以下几个方面:

  • 对敏捷开发的理解
  • 测试流程
  • BUG 管理
  • 用例设计
  • UI 自动化,接口自动化
  • 持续集成
  • 算法题
  • Linux 命令
  • 性能测试

回答

1. 对敏捷开发的理解

虽然目前公司处于敏捷开发的模式中,但平时自己也只是服从公司的流程,没有仔细去思考过敏捷开发。所以这个问题回答的也不好。

维基百科: 敏捷软件开发(英语:Agile software development),又称敏捷开发,是一种从 1990 年代开始逐渐引起广泛关注的一些新型软件开发方法,是一种应对快速变化的需求的一种软件开发能力。它们的具体名称、理念、过程、术语都不尽相同,相对于 “非敏捷”,更强调程序员团队与业务专家之间的紧密协作、面对面的沟通(认为比书面的文档更有效)、频繁交付新的软件版本、紧凑而自我组织型的团队、能够很好地适应需求变化的代码编写和团队组织方法,也更注重软件开发过程中人的作用。

个人理解:

  • 实施敏捷开发的流程:要去所有人参加需求评审,功能分卡,估点,每日站会,迭代回顾

  • 为了能够响应快速变化的需求或频繁的交付,必须依赖完善的自动化工具链,从单元测试 --- 接口自动化---UI 自动化 --- 部署 --- 线上监控 整套的流程实现自动化

  • 测试驱动开发,在编写功能实现代码前编写单元测试代码(实施上来讲比较困难,开发能够完成单元测试就不错了)

  • 持续集成,原则是尽量使用 master 分支进行开发,频繁地集成,即使编译报错也能够迅速定位修复。杜绝多分支的开发方式,合并分支是一个繁琐的工作,容易产生众多冲突问题,对测试也增加了工作量

  • 注重面对面的沟通,减少冗余的文档

  • 重构贯穿整个开发流程,每次 check 代码时对代码进行重构,使代码尽量简单,优美,可扩展,完善的单元测试是你重构的保障

  • 定时进行 Code Review

2. 测试流程和 BUG 管理

根据自己公司实际情况回答

3. UI 自动化和接口自动化

  • 简单的问了下框架的架构

  • UI 自动化怎么处理界面展示延迟的问题?
    Robotium 查找元素默认 20s 等待时间

  • HTTP 常见状态码

  • 接口自动化中怎么测试重定向的接口?(记不清了)
    不懂。这个没答上来

4. 持续集成

  • 自动化测试多久构建一次?如何搭建 jenkins?代码管理使用的是什么?jenkins 上如何配置 ssh 的方式从 git 拉取代码?

5. 算法题

题目:完成一个函数,实现功能为判断一个字符串是否是一个合法的 ip 地址
输入:任意字符串
输出:如果是一个合法 ip 地址,返回 true;否则,返回 false
举例:输入 10.0.0.1,输出 true;输入 aaaa,输出 false
要求:
1.可以用 c/c++/java/php/python 等任意熟悉语言,但不能使用正则表达式等已有算法;
2.根据等价类和边界值划分等测试方法,对写好的代码罗列出测试点并完成单元测试用例的代码部分

分析:此题考察了基本网络知识,代码能力,用例设计能力

合法 IP 地址当时写的是 0.0.0.0~255.255.255.255 其实错了,应该是 1.0.0.0~255.255.255.255

0.0.0.0 表示的是所有 IP 的一个集合,不算真正意义上的 IP 地址


import unittest

# 举例:输入10.0.0.1,输出true;输入aaaa,输出false
# 1.0.0.0 ~ 255.255.255.255

def assert_ip(ip_str):

    # 字符串切割
    ip_list = ip_str.strip().split('.')
    if len(ip_list) != 4:
        print('列表元素不等于4')
        return False
    try:
        # 0开始的IP不合法
        if int(ip_list[0]) == 0:
            print('以0开始不合法')
            return False
        for ip in ip_list:
            if len(ip) > 1 and ip.startswith('0'):
                print('长度大于1不能以0开始')
                return False
            if 0 <= int(ip) <= 255:
                pass
            else:
                print('大小不在0-255')
                return False
    except Exception as e:
        print(e)
        return False
    return True


class TestIp(unittest.TestCase):

    def test_01(self):
        ip1 = '10.0.0.1'
        self.assertTrue(assert_ip(ip1))

    def test_02(self):
        ip2 = '0.0.0.0'
        self.assertFalse(assert_ip(ip2))

    def test_03(self):
        ip3 = '255.255.255.255'
        self.assertTrue(assert_ip(ip3))

    def test_04(self):
        ip4 = '255.255.255.256'
        self.assertFalse(assert_ip(ip4))

    def test_05(self):
        ip5 = '0.0.0.1'
        self.assertFalse(assert_ip(ip5))

    def test_06(self):
        ip6 = '-1.2.3.4'
        self.assertFalse(assert_ip(ip6))

    def test_07(self):
        ip7 = ''
        self.assertFalse(assert_ip(ip7))

    def test_08(self):
        ip8 = '0.2.11'
        self.assertFalse(assert_ip(ip8))

    def test_09(self):
        ip9 = '10.0.0.0.1'
        self.assertFalse(assert_ip(ip9))

    def test_10(self):
        ip10 = 'aa.bb.cc.dd'
        self.assertFalse(assert_ip(ip10))

    def test_11(self):
        ip11 = '1 192.168.1.1 '
        self.assertFalse(assert_ip(ip11))

    def test_12(self):
        ip12 = '1.00.0.0'
        self.assertFalse(assert_ip(ip12))

    def test_13(self):
        ip13 = 'aaaaa'
        self.assertFalse(assert_ip(ip13))

if __name__ == '__main__':

    unittest.main()

单元测试点:

  1. IP 不含字符’ . ’
  2. IP 切割字符串后列表大小 =4 < 4 >4 的三种情况
  3. 字符串中包含空格(左右空格,中间空格)
  4. 输入字符串为空
  5. 输入合法 IP 10.0.0.1
  6. 输入合法 IP 1.0.0.0
  7. 输入合法 IP 255.255.255.255
  8. 输入非法 IP 0.0.0.1
  9. 输入非法 IP 255.255.255.256
  10. 输入非法 IP -1.2.3.4
  11. 输入字符串中包含非数字 aa.10.11.dd
  12. 输入特殊字符串 .@ddj.%&111.1.
  13. 输入非法 IP 172.16.01.06

面试官又让我分析 unittest 源码...我表示没看过...GG(我简历可没写精通 unittest~~~)

于是又让我用正则表达来写,心中一群草泥马飘过,虽说平时会使用正则,但都是百度现成的,真要自己写都点难度。。。

网上找的:

^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$


import re

def assert_ip_by_re(ip_str):
    pattern = '^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.' \
         '(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.' \
         '(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.' \
         '(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$'
    re_compile = re.compile(pattern)
    if re_compile.match(ip_str):
        return True
    else:
        return False
  • 拓展 使用第三方库 IPy

注意:IPy 不会处理 0.0.0.0 这种 IP,认为是合法的。类似 198.01.003.001 这种输入,会自动舍去前面的 0,也认为是合法的。


import IPy 

def assert_ip(address): 
  try: 
    IPy.IP(address) 
    return True
  except Exception as e: 
    return False

6. Linux 命令

  • 打印日志文件所有有 username 的行

cat xxx.log | gerp 'username' 忽略大小写cat xxx.log | gerp -i 'username'

  • 获取当前目录下占用磁盘空间最大的 3 个文件或目录

当时没写出来,只知道可以用ls head命令,平时用sort命令太少了

ls -al | sort -rnk 5 | head -3

sort -n 是按照数字大小排序,-r 是以相反顺序,-k 是指定需要排序的栏位,-t 指定栏位分隔符 (不写默认是空格和\t)

  • 查看 CPU 内存占用命令

top

  • adb 常用命令

7. 性能测试

没做过,略

8. 用例设计

对客户端重构登录模块进行用例设计,只有用户名,密码和登录。不考虑其他功能。

这个题虽然简单,但我答得没条理,上来就开始陈述我的测试用例,只考虑了功能方面,没有养成多维度系统得用例设计习惯,估计也是这个原因面试挂了。。。
重新整理用例:

  • 功能性
    输入框的字符长度限制、特殊字符处理、密码输入显示 *、不输入用户名和密码点击登录是否调用接口?只输入用户名、只输入密码?错误用户名、错误密码?登录成功后是否有其他配置项拉取?登录按钮防重按?

  • 安全性
    密码是否加密传输?SQL 注入?

  • 易用性
    错误提示是否友好?UI 界面风格?

  • 兼容性
    app 升级后老用户是否能登录成功?新用户登录?

总结

从最近找工作发现测试的要求是越来越高了,需要会的技能也越来越多,功能、自动化、性能、安全、写测试工具、测试平台...甚至运维的活也要测试来干 - -! 只能说路漫漫其修远兮~ 继续找窝。

共收到 19 条回复 时间 点赞

这找的是测试开发吗?测试重定向接口没理解什么意思。

最近也在面试,心累啊。难道测试面试也得造火箭了吗😂

Ribosome 回复

不排除有些公司面试造火箭,入职拧螺丝😂

测试老菜 回复

嗯不过我面试的问题倒和你还挺相似的,共勉~

实话说,相比 java 开发的面试题,你遇到的面试题真的没什么难度,尤其页面等待这块,你去看看 macaca 源码就可以了

整体思路:

.分割放进字符串数组,判断每一位是否大于 0-255,

如果有一位不满足,全局变量 isTrue 置假

把符合每一位放入 newStr 字符串

最终 newStr 与 0.0.0.0 比较

package com.domoyun.day02;

import java.util.Scanner;

public class IsIpaddress {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String inputStr =in.nextLine();
         System.out.println(isrightful(inputStr));
    }

    public static boolean isrightful(String inputStr){
        String[] arryW = inputStr.split("\\.", -1);
        if (arryW.length==4) {
            boolean isTrue=true;
            String newStr="";
            for (int i = 0; i < arryW.length; i++) {
                try {
                    if (Integer.parseInt(arryW[i])>=0 && Integer.parseInt(arryW[i])<=255 ) {
                        if (i == 3) {
                            newStr=newStr+arryW[i];
                        }else {
                            newStr=newStr+arryW[i]+".";
                        }

                        System.out.println(newStr);
                    }else{
                        isTrue=false;
                    }
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
            }
            if (newStr.equals("0.0.0.0")) {
                isTrue=false;
            }
            System.out.println(isTrue);
            if (isTrue==true) {

                return true;
            }
        }else{
            System.out.println("不符合的IP地址");
        }
        return false;
    }
}

感谢分享!

Pangluo 回复

试下 0.0.0.1 这种非法 IP 呢

22 行

if (i == 3 ) {
    newStr=newStr+arryW[i]; 
}else {
    newStr=newStr+arryW[i]+".";
}

新增一个判断,第一位 0 开头,即为非法,
因为第一位 1 开头的 IP,后面都是真实的 IP 地址,即使 1.0.0.0 也是符合的 IP 地址

if (i == 3 ) {
    newStr=newStr+arryW[i]; 
    if (arryW[0].equals("0")) {
        newStr="0.0.0.0";
    }
}else {
    newStr=newStr+arryW[i]+".";
}

方法有点多,可以了解一下 from functools import partial
可以就写一个方法 断言下面的 ip

什么公司啊

天,测试找工作现在要懂的也太多了吧。算法、代码能力。。。。。。。。。

这种要求的岗位,月薪得给上万吧,好怕怕

槽神 回复

水平低啊,让大佬见笑了,但也实在没必要这样冷嘲热讽的😀

测试老菜 回复

1、我在说岗位要求,不知道跟你的水平怎么扯到一块了~
2、不知道你哪里看出来冷嘲热讽了,未免玻璃心了吧……

听说 * 安的功能测试面试都要手写排序算法之类的。
现在又是寒冬,公司想找个全栈的薪资要求低测试,这样问题也不奇怪。
加油!能不换工作,尽量先别换

槽神 回复

好吧,算我玻璃心吧,但月薪上万真的也不多啊。。

这个要求是得上万啊,完全没毛病

匿名 #19 · 2019年04月18日

接口重定向那里可以用 jmeter 实现哈,把重定向的接口参数用正则表达式传递进来

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册