面试准备

2019-08-01  本文已影响0人  小眼睛的露鹿酱

要求: java+Selenium
Maven, BitBucket(跟github一样的, 都是项目仓库), TestNG
Jira(https://www.guru99.com/jira-tutorial-a-complete-guide-for-beginners.html)

面试:三轮

1. 现场写(笔试题)

XSS攻击, SQL注入, 连接池

SQL注入:

使用简单的JDBC调用SQL语句时, 会很容易进行SQL语句的拼接, 从而是的那些包含对数据库有害的特殊符号或者语句被包含其中, 从而带来其他问题, 需要从以下考虑:
1.1 过滤用户的输入
1.2 禁止SQL语句的字符串拼接,使用参数绑定传人的SQL语句
1.3 使用数据库访问框架

XSS攻击

HTTP请求中包含了黑客插入的恶意JS文件或恶意url, 还是要注意:
对用户输入的字符串进行过滤或者转义 , 借助安全的框架;

CSRF: 跨站请求伪造

登陆网银的时候 点击了恶意的网址, 使得账户被恶意访问

Java的类

java类中了解的有父类 子类 抽象类 接口 枚举
类包含成员变量与方法, 先定义变量 构造函数 其他逻辑函数 使用生成器 生成相关的get set方法, 然后看项目 后续添加其他方法

抽象类与接口

共同点: 不能被实力化
不同: 一个是abstract class一个是interface
抽象类能添加具体的方法的实现, 接口只有方法定义 没有具体的实现
抽象类只能单继承, 但是接口可以被多继承

*** 手写代码排序;

参考: https://www.cnblogs.com/guoyaohua/p/8600214.html
1.1 冒泡排序

/**
     * 冒泡排序
     *
     * @param array
     * @return
     */
    public static int[] bubbleSort(int[] array) {
        if (array.length == 0)
            return array;
        for (int i = 0; i < array.length; i++)
            for (int j = 0; j < array.length - 1 - i; j++)
                if (array[j + 1] < array[j]) {
                    int temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                }
        return array;
    }

1.2 选择排序(Selection Sort)


/**
     * 选择排序
     * @param array
     * @return
     */
    public static int[] selectionSort(int[] array) {
        if (array.length == 0)
            return array;
        for (int i = 0; i < array.length; i++) {
            int minIndex = i;
            for (int j = i; j < array.length; j++) {
                if (array[j] < array[minIndex]) //找到最小的数
                    minIndex = j; //将最小数的索引保存
            }
            int temp = array[minIndex];
            array[minIndex] = array[i];
            array[i] = temp;
        }
        return array;
    }

1.3 插入排序(Insertion Sort)
插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
算法描述

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

从第一个元素开始,该元素可以认为已经被排序;
取出下一个元素,在已经排序的元素序列中从后向前扫描;
如果该元素(已排序)大于新元素,将该元素移到下一位置;
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
将新元素插入到该位置后;
重复步骤2~5。
/**
     * 插入排序
     * @param array
     * @return
     */
    public static int[] insertionSort(int[] array) {
        if (array.length == 0)
            return array;
        int current;
        for (int i = 0; i < array.length - 1; i++) {
            current = array[i + 1];
            int preIndex = i;
            while (preIndex >= 0 && current < array[preIndex]) {
                array[preIndex + 1] = array[preIndex];
                preIndex--;
            }
            array[preIndex + 1] = current;
        }
        return array;
    }

1.4 快速排序
快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
算法描述

快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

从数列中挑出一个元素,称为 “基准”(pivot);
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
图片.png
/**
     * 快速排序方法
     * @param array
     * @param start
     * @param end
     * @return
     */
    public static int[] QuickSort(int[] array, int start, int end) {
        if (array.length < 1 || start < 0 || end >= array.length || start > end) return null;
        int smallIndex = partition(array, start, end);
        if (smallIndex > start)
            QuickSort(array, start, smallIndex - 1);
        if (smallIndex < end)
            QuickSort(array, smallIndex + 1, end);
        return array;
    }
    /**
     * 快速排序算法——partition
     * @param array
     * @param start
     * @param end
     * @return
     */
    public static int partition(int[] array, int start, int end) {
        int pivot = (int) (start + Math.random() * (end - start + 1));
        int smallIndex = start - 1;
        swap(array, pivot, end);
        for (int i = start; i <= end; i++)
            if (array[i] <= array[end]) {
                smallIndex++;
                if (i > smallIndex)
                    swap(array, i, smallIndex);
            }
        return smallIndex;
    }

    /**
     * 交换数组内两个元素
     * @param array
     * @param i
     * @param j
     */
    public static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

*** 手写代码数据库: 查询并排序

SELECT DISTINCT Company FROM Orders

SELECT * FROM Persons WHERE City='Beijing'
SELECT * FROM Persons WHERE FirstName='Thomas' AND LastName='Carter'
SELECT * FROM Persons WHERE (FirstName='Thomas' OR FirstName='William')
AND LastName='Carter'

SELECT Company, OrderNumber FROM Orders ORDER BY Company
SELECT Company, OrderNumber FROM Orders ORDER BY Company DESC, OrderNumber ASC
第一个order相同的情况下, 会使用第二个进行排序

INSERT INTO Persons VALUES ('Gates', 'Bill', 'Xuanwumen 10', 'Beijing')
INSERT INTO Persons (LastName, Address) VALUES ('Wilson', 'Champs-Elysees')
UPDATE Person SET FirstName = 'Fred' WHERE LastName = 'Wilson' 
DELETE FROM Person WHERE LastName = 'Wilson' 
DELETE * FROM table_name。删除内容 表不会被删除

SELECT TOP 2 * FROM Persons
SELECT * FROM Persons
WHERE City LIKE 'N%'

SELECT * FROM Persons
WHERE LastName IN ('Adams','Carter')

SELECT * FROM Persons
WHERE LastName
BETWEEN 'Adams' AND 'Carter'



SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons, Orders
WHERE Persons.Id_P = Orders.Id_P 


SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName



现在,我们希望列出所有的人,以及他们的定购 - 如果有的话。

您可以使用下面的 SELECT 语句:

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
FULL JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName

SELECT COUNT(count) AS nums FROM access_log
WHERE site_id=3; 

重载;

java多承载

java 不支持那种一个类有两个父类, 但是可以用A继承与B, C继承与A。那么 最后C继承了A和B
或者使用接口 来帮助继承

面向对象

面向对象三大特性: 封装 继承 多态
封装是对对象功能内聚的形式表现,是的模块之间耦合变低,易维护; 避免敏感数据暴露
继承: 模块复用
多态: 复用性的基础上进行扩展, override(覆盖) overload(重载)
高内聚低耦合

  1. 测试类型: 功能测试, 性能测试, 按照测试的阶段: 单元测试, 接口测试, 集成测试, 系统测试
    按照测试的目的: 冒烟测试 回归测试, 安全测试等
  2. 没有冗余 覆盖面广, 边界也考虑清楚
  3. 单元测试的话: eclipse包含Coverage 插件 颜色来高亮度显示
    功能测试: 讲不同页面中的模块进行全组合
  4. select Employee.name, Salary.Salary from Emplyee inner Join Salary on emplyee.ID = Salary.EID where Salary.Salary >=2000
  5. select AVG(Salary.salary) from Emplyee inner Join Salary on emplyee.ID = Salary.EID where EMPLOYEE.BITTH like '199%'
  6. 假设已经成功登陆的前提下: 选择商品 点击加入购物车 》 测试购物车是否有数字的更改, 形状显示等
    添加到购物车
    购物车中删除
    购物车列表历史记录
    购物车页面的 颜色 数量 布局
public class Accumulation {
    public static void main(String[] args) {
        int start = 1;
        int end = 100;
        System.out.println((start + end) * (end - start + 1) / 2);
        int result = 0;
        for (int i = start; i <= end; i++) {
            result += i;
        }
        System.out.println(result);
    }
}
String key = "webdriver.firefox.bin";//selenium定义的driver
String value = "C:/Program Files (x86)/Mozilla Firefox/firefox.exe";//该地址指的是浏览器在本地的安装地址
System.setProperty(key, value);//系统自动配置相应的参数
dr = new FirefoxDriver();//实例化浏览器
dr.manage().window().maximize();
dr.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  1. SQL中group by, 选出所有成绩大于80的人
    select * from 成绩表 where 姓名 in (select 姓名 from 成绩表 group by 姓名 having min(分数) >=80)

10.什么是事务

在执行SQL语句的时候,某些业务要求,一系列操作必须全部执行,而不能仅执行一部分。例如,一个转账操作:

-- 从id=1的账户给id=2的账户转账100元
-- 第一步:将id=1的A账户余额减去100
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- 第二步:将id=2的B账户余额加上100
UPDATE accounts SET balance = balance + 100 WHERE id = 2;

这两条SQL语句必须全部执行,或者,由于某些原因,如果第一条语句成功,第二条语句失败,就必须全部撤销。

这种把多条语句作为一个整体进行操作的功能,被称为数据库事务。数据库事务可以确保该事务范围内的所有操作都可以全部成功或者全部失败。如果事务失败,那么效果就和没有执行这些SQL一样,不会对数据库数据有任何改动。

可见,数据库事务具有ACID这4个特性:

    A:Atomic,原子性,将所有SQL作为原子工作单元执行,要么全部执行,要么全部不执行;
    C:Consistent,一致性,事务完成后,所有数据的状态都是一致的,即A账户只要减去了100,B账户则必定加上了100;
    I:Isolation,隔离性,如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离;
    D:Duration,持久性,即事务完成后,对数据库数据的修改被持久化存储。

对于单条SQL语句,数据库系统自动将其作为一个事务执行,这种事务被称为隐式事务。

要手动把多条SQL语句作为一个事务执行,使用BEGIN开启一个事务,使用COMMIT提交一个事务,这种事务被称为显式事务,例如,把上述的转账操作作为一个显式事务:
  1. 说说多线程

  2. 什么是关键字驱动
    将测试用例的每个步骤单独封装成一个函数,以这个函数名作为关键字,将函数名及传参写入文件中,每个步骤映射一行文件。通过解析文件的每行内容,将内容经过eval函数拼成一个函数调用,调用封装好的步骤函数,就可以一步步执行测试案例。
    比如登录邮箱:步骤分为,打开浏览器,访问邮箱地址,输入用户名、密码、点击登录、断言这几个步骤,
    现将这个几个步骤写入到文件中,开头是步骤名,后面是参数。并且将每个步骤名封装成一个函数。
    读取写有测试步骤的配置文件,根据参数值的不同,拼装成不同的函数调用字符串,利用eval执行字符串,就可以调用已经封装好的关键字函数,进而一步步执行测试步骤

  3. python合并 [(1,2,3),(2,3,4)]---(3,5,7)

Selenuim 源代码 整理

Selenuim Grid 再看看

TestNG的XML文件再看一下

java 正则表达式

java中的各种流 以及文档处理: JASON XML 相关的API

1.DOM方式解析XML
Dom解析是将xml文件全部载入到内存,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件,与平台无关,java提供的一种基础的解析XML文件的API,理解较简单,但是由于整个文档都需要载入内存,不适用于文档较大时。

2.SAX方式解析XML
基于事件驱动,逐条解析,适用于只处理xml数据,不易编码,而且很难同时访问同一个文档中的多处不同数据

3.JDOM方式解析XML
简化与XML的交互并且比使用DOM实现更快,仅使用具体类而不使用接口因此简化了API,并且易于使用

4.DOM4j方式解析XML
JDOM的一种智能分支,功能较强大,建议熟练使用

设计模式
对微信发红包写测试用例
https://blog.csdn.net/qq_40955824/article/details/89407525
英文面试: 为什么来

  1. 闲聊: 计划+和英文自我介绍, 简单的case写测试用例

  2. 哪里人, 学校, 做测试的原因, 职业规划, 讲英文: 自我介绍, 工作经验

上一篇 下一篇

猜你喜欢

热点阅读