常用SQL语句

SQL搜索语句

SELECT——从表中选取数据

  • SELECT 列名 FROM 表名——选取表中某一列
  • SELECT * FROM 表名——选取整个
  • SELECT DISTINCT 列名 FROM 表名——选取表中某一列,并且列内容不重复

WHERE——有条件地从表中选取数据

  • SELECT 列名 FROM 表名 WHERE 列名 运算符 值——按照where条件筛选(注意:文本值需要用单引号,而数值不需要)

AND/OR——在 WHERE 子语句中把两个或多个条件结合起来

  • AND前后的筛选条件都符合,则显示记录
  • OR前后的筛选条件有一个符合,则显示记录
  • 也可以把多个 AND和OR结合起来,使用()组成复杂表达式

ORDER BY——对结果集进行排序

  • 默认按照升序(ASC)对记录进行排序
  • 降序排序,可以使用DESC关键字
  • 例:筛选结果按照列名1升序显示,列名1相同时,按列名2升序显示
    SELECT 列名1, 列名2 FROM 表名 ORDER BY 列名1,列名2

INSERT INTO——向表格中插入新的行

  • INSERT INTO 表名 VALUES (值1, 值2,….)
  • INSERT INTO table_name (列1, 列2,…) VALUES (值1, 值2,….)

UPDATE——修改表中的数据

  • UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值

DELETE——删除表中的行

  • DELETE FROM 表名 WHERE 列名 = 值
  • 删除所有行:DELETE * FROM 表名
  • 删除所有行:DELETE FROM 表名

冒烟测试和回归测试的区别

冒烟and回归测试

由于刚接触测试不久,总是会听到“冒烟测试”和“回归测试”这两个词,一直不清楚它们的具体区别是什么,所以特地去了解了一下:

先来说一说什么是冒烟测试:它又名smoke test,是自由测试的一种。我们测试人员在测试中发现软件的问题,即找到了一个bug,然后开发人员会来修复这个bug。那么当修复完成后,想知道这次修复是否真的解决了程序的bug,或者是否会对其它模块造成影响,就需要针对此问题进行专门测试,这个过程就被称为冒烟测试。这样的话,只针对某些个特定的问题,就以节省大量的时间成本和人力成本。

那么,修改了旧代码后,我们就需要重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误,这就是所谓的回归测试。它是软件生命周期的一个组成部分,在整个软件测试过程中占有很大的工作量比重,软件开发的各个阶段都会进行多次回归测试。

所以我感觉,当一个新版本开发好后,先是要冒烟测试通过,此时再用上一个版本的测试用例对新版本进行测试,看是否有bug,也就是做回归测试。

 

Python爬虫基础课(一)

对于网络爬虫来说,其本质就是发送http请求,然后提取网页的内容信息进行入库分析等操作。C#、C++、Java、Swift、Golang、Python等语言都可以来编写爬虫应用,而市面上较流行的语言就是Python了。今天听完基础课的第一课,于是做个Python爬虫入门的笔记:

我这边用的编辑器是PyCharm,原生编辑器、Sublime 、Text等都是可以写代码的,看个人习惯,一般非原生编辑器用的比较多,更加智能。

首先,我们先来过一遍HTTP协议,该协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。它是一种短连接的协议,基于TCP。

HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。我们主要使用的是Get和Post这两个:

  • GET的信息存储在URL中;
  • POST的信息则把信息存储在form中,比如说我们在输入登陆用户名密码的时候,不会在网址中看到这些隐私信息。

爬虫最主要的处理对象就是URL。比如你在浏览器的地址栏中输入一个URL,打开网页的过程其实就是浏览器作为一个浏览的“客户端”,向服务器端发送了一次请求,把服务器端的文件“抓”到本地,再进行解释、展现。而爬虫就是模拟这个过程,通过URL地址取得所需要的文件内容,然后对它进行进一步的处理。

这里再补充一下URL(统一资源定位符的组成形式:

protocol :// hostname[:port] / path / [;parameters][?query]#fragment(以https://www.baidu.com/index.php?tn=87048150_dg&ch=1为例:

  1. 第一部分是协议(或称为服务方式):https
  2. 第二部分是存有该资源的主机IP地址(有时也包括端口号):www.baidu.com
  3. 第三部分是主机资源的具体地址,如目录和文件名等:index.php?tn=87048150_dg&ch=1
  • 第一部分和第二部分用“://”符号隔开,
  • 第二部分和第三部分用“/”符号隔开。
  • 第一部分和第二部分是不可缺少的,第三部分有时可以省略。

接下来我们开始元素查看:

http://weibo.com/tv/v/FaOp9o8Ct先通过Chrome浏览器下载一个微博上的小视频,来学习如何用Chrome浏览器抓取网络请求。首先打开这个连接,按下F12(或者右键“检查”):

在这个Dock窗口中,有很多个选项卡,主要使用到Elements和NetWork这两个,一个负责审查Html元素,一个负责记录网络请求。目前需要使用网络抓取功能,所以先跳到Network这个选项卡中。

那么多的记录中,如何准确找到视频的URL呢?Network->media

点击这条记录,然后在Headers下有着请求相关的信息,可以看到请求的真实链接地址,这个地址中还带了个mp4,当我们把URL复制后在新的页面打开,可以把视频下载到了本地。

  • 首先,requests.get最基础的用法就是去获取某个网页,如百度首页
r = requests.get('https://www.baidu.com/')

当然我们要保证自己的Python已经安装了requests库,没有的话就pip安装一下

  • 对于带参数的URL,传入一个dict作为params参数
r = requests.get('https://www.douban.com/search', params={'q': 'python', 'cat': '1001'})
  • 传入data参数作为POST请求的数据
requests.post('https://accounts.douban.com/login', data={'form_email': 'abc@example.com', 'form_password': '123456'})

那么接下来我们就来可以用Python来试着下载视频啦(这里我们主要用到get这个请求,requests这个库中自带这个函数,具体用法可以看详细文档):

import requests
response = requests.get('https://us.sinaimg.cn/002ADWB0jx07cnlEmv60010f0100GOzs0k01.mp4?label=mp4_hd&template=template_6&Expires=1534316818&ssig=SLa215YjQw&KID=unistore,video')
with open('E:/video.mp4','wb') as f:
    f.write(response.content)

视频在传输过程中是以二进制流的形式传输的,wb:以二进制写模式打开

(待续……登录案例待补充)

Anaconda+Pycharm

前段时间由于要用Python2的一个已经在3废弃了的第三方库,在配置方面出了错,懒得找冲突的我把Python3相关的东西都卸了,现在重新装回来。

我的电脑是win10的,所以去官网下载最新的64位安装程:

双击开始安装:

如果系统只有一个用户选择默认的第一个即可,如果有多个用户而且都要用到 Anaconda ,则可以选择第二个选项,一般我们都是个人使用的。

默认是安装在C盘的,但一般我们都选择其它盘,不然C盘太容易满了。

其中有两个选项框,网上说最好将第一个选项Add Anaconda to my PATH environment variable选上,虽然是建议不选的。第一个是加入环境变量,第二个是默认使用 Python 3.5。

注:我一开始是两个都选了,然后安装后只有一个anaconda prompt,其他都没有(连anaconda navigator也没有,据说这是非第一次安装可能会碰到的问题,所以第一次装的人就不用怕啦),修改环境变量啥的也都没成功,所以我卸掉后重新装了一遍,并且不勾选第一个选项。

之后就是开始安装了,需要等待一段时间。

注:对于出现我刚刚上面勾选了两个选项并且没成功的孩子,如我这样的结果:

在不勾选第一个选项重新安装后,包括本来就成功的,开始菜单会出现(py27那个是我老版本python所需的,不用管),而由于没勾选第一个选项,所以我们要手动添加环境变量,给Path路径添加两条记录(Anaconda的安装路径):

  • F:\Anaconda\Anaconda3
  • F:\Anaconda\Anaconda3\Scripts

接下来我们去PyCharm官网下载PyCharm,由于社区版(Community)已经包含了我们所需要的基本功能,所以我下的是社区版本。专业版(Professional)需要激活,也可以去网上找激活码。下载完成后双击安装程序,开始安装:

选择你要安装的路径:

按照自己电脑操作系统的位数(64位 或者32位):

默认Install即可:

安装成功后Finish关掉即可:

然后我们打开PyCharm,选择Do not import settings然后OK即可:

跳过几个默认操作,然后我在这个界面选择“+Create New Project”

图中的Location是选择你创建python工程的位置及工程名字,因为Anconada已经装了Python了,所以要选择Existing Interpreter,并找到安装Python解释器的路径,目录为Anaconda的安装目录下的python.exe文件。

选择好后点击“Create”创建项目:

并创建对应的Python File,就可以开始正常使用啦。

OK,以上就是整个安装步骤,还是比较简单易懂的。

 

WordPress:Error establishing a database connection

今天登陆博客时出现了Error establishing a database connection这个报错。

网上对这个的问题可能出现的原因有很读,主要的一个是由于你修改了密码,而配置文件没有配置正确,无法正常调用 Mysql,这个时候就要配置wordpress目录下的wp-config.php文件

当然,由于我根本没有任何改密码啥的操作,所以不可能是这个问题,这里我就做下记录,以便我下次遇到时有个参考。

为了比较清晰的看到报错状况,我先将wp-config.php中的define(‘WP_ALLOW_REPAIR’, false);改成了define(‘WP_ALLOW_REPAIR’, true);

之后我的报错是这样的,发现好像就是连不上数据库:

于是我检查了我的MySQL是否在运行service mysql status

提示我MySQL is not running……这时重启一下就好了service mysql start(注:有的人可能是service mysqld status)

这次我碰到的是最简单的连接问题,仅做个记录而已。

补:之后发布后还出现了Warning: scandir() has been disabled for security reasons in…的问题,我猜可能是WordPress更新以后的后遗症,这个的话只要找到/usr/local/php/etc目录下的php.ini中disable_functions = scandir,passthru,exec,system……并去掉对应的函数,如这里的scandir,保存并重起php-fpm即可。/etc/init.d/php-fpm restart

分层测试

今天上午上了一堂有关分层测试的课,下面记录一下相关内容及简单理解:

主管以一个登陆界面为例,倘若客户的基本需求如下:

  • 需要输入的是用户名和密码
  • 用户名为2-12个大写或者小写字母或者数字
  • 密码为6-12个大写或者小写字母或者数字
  • 用户名或者密码任意一个不正确就登陆失败
  • 用户名和密码同时正确则登录成功,进入主界面

在分析这个问题具体怎么实现之前,我们可以先考虑一个功能(不管是登录也好,还是其它这些类型的功能也罢)整个架构是怎样设计的,新入手的人或许就简单的考虑单层结构,当数据量增大时再思考要不要加入数据库,最后再把前后端划分开来:

但是为了长远发展以及行业趋势使然,三层架构越来越成为首先被考虑的方案,在此基础上再进一步实施拓展。而简单的从字面上来说,所谓分层就是将功能就行拆分,是界限更加清晰,可以更好的将任务分配下去:

有了上述架构上的分层,我们就可以引出对应的分层测试概念:针对有明确分层设计的软件系统,采用白盒/黑盒测试的技术,在各个层面有侧重的验证软件的正确性。

从上图我们可以看到,在展示层,我们可以做界面测试;在服务层,我们可以做接口和单元测试;而在数据持有层,我们可以做数据库测试。

有人会问,这里为什么服务层对应了接口测试和单元测试两个呢?主要是因为很多时候,我们在内部可能写了很多的函数,而对外开放的可能只有一两个接口,这个时候就需要单元测试来更详尽的测试内部的单元。

由此我们不难得出分层测试的这些优点:

  • 覆概率高:自底向上,暴露的功能与逻辑越来越少;
  • 精准:离问题产生的地方越近,就越容易触发问题;
  • 尽早测试:尽早测试,降低修复成本;逐层测试,需要等待系统全部完成开发;
  • 高效:用例设计工作量的精简、质量更高;测试执行可自动化程度高。

这时我们再回到登录界面的思考,按照分层架构的思想,不难想到可以将整个登录过程设计为如下这个样子:

在有了比较明确的功能划分后,我们设计功能案例将更加方便与清晰(这个时候,我get到的另一点是,哪怕是登录页面,不考虑后台的情况下我们的测试也需要考虑到用户使用场景部分和UI控件部分的划分):

  • 模拟真实客户场景。客户/用户可以看得懂的案例

  • 无论什么类型的项目、相同的控件,测试点总是相同的

以上就是我这节课主要学习的内容啦~

win10安装Oracle连接PL/SQL

Oracle安装:

首先因为不想在官网注册,所以用了百度网盘来下载Oracle,下面是我找的连接:

http://pan.baidu.com/s/1hrvQyS8

需要下载的是oracle11grl-win64.iso和instantclient-basic-win-x86-64-11.1.0.7.0.zip(后一个我是别的地方下的,这个网盘的内容我下下来打开失败了

下载后解压,得到database文件夹:

进入文件夹,双击文件夹内的setup.exe开始安装:

目录路径不要含有中文或其它的特殊字符。全局数据库名字可以默认。需要记住的是数据库口令,也就是密码,密码输入时如果不按照Oracle建议的(也就是大小写字母加数字,8位以上)会有警告提示,当然这个不要紧,按自己的习惯来,密码简单一点也可以。我这里全局数据库名的下划线是不能有的,忘记重新截图了。当然这里创建启动数据库设置不设置问题不大,用于访问服务器数据库内容时不需要这些设置信息。

电子邮件可填可不填,我这边默认不填,直接下一步。

然后会碰到经常碰到的一些安装报错:

①正在检查操作系统要求…

要求的结果: 5.0,5.1,5.2,6.0,6.1 之一

实际结果: 6.2

检查完成。此次检查的总体结果为: 失败 <<<<

问题: Oracle Database 11g 未在当前操作系统中经过认证。

建议案: 确保在正确的平台上安装软件。

—————————————————————————————

需要修改oracle11g\stage\prereq\db\refhost.xml 文件,在原有内容后新增所需要的版本内容:

关闭重新安装后,到同样的页面显示:

详细解决方案http://blog.itpub.net/30260000/viewspace-1819714/

由于我win10没有Microsoft LoopBack Adapter这个网络适配器,所以百度上的方法一直没有配置网卡成功,也不知道具体怎么解决,所以就直接安装了。最后好像也没出什么问题,所以我很想知道win10的配置问题是怎么解决的,好多电脑甚至不会出现这个问题,一直下一步即可。

安装完成后,会列出相关数据库配置清单,最好保存一下,这里“口令管理”需要有需要的话也可以设置保存一下:

连接PL/SQL:
安装一个破解版的PLSQL Developer,过程比较简单,无脑操作即可:

然后安装instant oracle(可以去网上下载这个Instant Client):

在..\Oracle Client\Instant Client\network\admin目录下(缺少的文件夹自己新建)创建一个tnsnames.ora文件和sqlnet.ora文件。前者是ORACLE的配置文件,
客户机为了和服务器连接,必须先和服务器上的监听进程联络。ORACLE通过tnsnames.ora文件中的连接描述符来说明连接信息。一般tnsnames.ora 是建立在客户机上的。如果是客户机/服务器结构,整个网络上只有一台机器安装了ORACLE数据库服务器,那么只需在每个要访问ORACLE服务器的客户机上定义该文件,在服务器上无需定义。下面是tnsnames.ora的文件样式,主要要设置的就是数据库名(第一行)和HOST(IP地址)以及PORT(端口),对每一行不是很理解的也可以具体百度一下:

后内内容为

# This file is actually generated by netca. But if customers choose to
# install "Software Only", this file wont exist and without the native
# authentication, they will not be able to connect to the database on NT.
SQLNET.AUTHENTICATION_SERVICES = (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)

接下来,我们需要配置一下PL/SQL Developer,先添加电脑的系统环境变量:

变量名为TNS_ADMIN,路径为上述两个.ora的目录。

打开PL/SQL Developer,首次无需登录,在菜单中找到“工具”->“首选项”,

主要是要手动添加一下两个目录,第一个是上述两个.ora的目录(同上),第二个是oci.dll的整个路径包括文件名,我这里是f:\plsql\instantclient-basic-nt-11.2.0.2.0\instantclient_11_2\oci.dll(就是一开始下载个那个压缩包解压后里面的一个oci.dll路径)

设置好这些后,重新打开PL/SQL就可以连接数据库啦:

Android使用讯飞实现语音转文本

Android Studio+讯飞实现语音转文本详细步骤

进入讯飞开放平台注册账号https://passport.xfyun.cn/register

注册完毕后登陆账号,点击右上角“控制台”选项,进入后创建一个应用:

创建完成后,点击右边的“SDK下载”:

添加自己想要的功能:

选择“语音听写”选项,当然如果你想要语音播报功能的话,可以一并下载“在线语音合成”:

选择SDK打包下载:

解压下载后的压缩包,将libs目录下的jar包放到Android Studio工程文件app/libs中:

由于本Demo中会用到json的东西,所以还得自己去网上下一个json的jar包,一并引进去(以及加入你在项目完善过程中所需要的jar包,我这里多余的是为了完成我除了语言转文本之外的功能):

这里需要注意的是!!你可以重新build一下gradle,但为了以防万一,可以现在gradle的配置文件中写明你添加的jar包以便编译:

改过后记得刷新一下:

之后在main目录下新建一个jniLibs目录,将 SDK中 libs 目录下的armeabi 拷进去,如下图所示:

讯飞为我们提供了一套语音听写时的UI,这个需要我们先将 SDK 资源包 assets 路径下的资源文件拷贝至 Android 工程asstes 目录下(没有的话自己新建,但是一般项目都是有的):

接下来开始添加代码,首先在AndroidManifest中添加一下权限(AndroidManifest在app/src/main目录下):

<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET" />
<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<!--SD卡读写的权限(如果需要保存音频文件到本地的话)-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

然后开始编写或者在原有的基础上更改你的MainActivity:

下面我放一个比较官方的Demo代码


package zhaoq_qiang.xunfeidemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_click;
private EditText mResultText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_click = (Button) findViewById(R.id.btn_click);
mResultText = ((EditText) findViewById(R.id.result));
SpeechUtility.createUtility(this, SpeechConstant.APPID + "= 此处需要填写你所申请的appId");
btn_click.setOnClickListener(this);
}
@Override
public void onClick(View v) {
btnVoice();
}
//TODO 开始说话:
private void btnVoice() {
RecognizerDialog dialog = new RecognizerDialog(this,null);
dialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
dialog.setParameter(SpeechConstant.ACCENT, "mandarin");
dialog.setListener(new RecognizerDialogListener() {
@Override
public void onResult(RecognizerResult recognizerResult, boolean b) {
printResult(recognizerResult);
}
@Override
public void onError(SpeechError speechError) {
}
});
dialog.show();
Toast.makeText(this, "请开始说话", Toast.LENGTH_SHORT).show();
}
//回调结果:
private void printResult(RecognizerResult results) {
String text = parseIatResult(results.getResultString());
// 自动填写地址
mResultText.append(text);
}
public static String parseIatResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
// 转写结果词,默认使用第一个结果
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
JSONObject obj = items.getJSONObject(0);
ret.append(obj.getString("w"));
}
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
}

 

最后大概就是这个样子的(我对按钮等做了改动,所以看上去会不一样,最基础的只要在activity_main.xml文件里设置一个按钮(Button)和一个文本框(TextView)即可):

Python turtle库入门学习笔记(一)

Python 海龟绘图——命令尝试

为了方便运用,可以先将引入的turtle命名为tu或者自己习惯的名字。
import turtle as tu

1、朝着画笔方向画直线——tu.forward(距离)

2、转换画笔朝向(左转或者右转)——tu.left(角度)/tu.right(角度)

3、朝着画笔反方向画直线——tu.backward(距离)

4、抬起画笔,可移动但不绘制——tu.penup()

5、放下画笔(默认开始是就是放下的)——tu.pendown()

6、去指定的位置——tu.goto(x,y)

7、指定去往x轴/y轴的位置——tu.setx(数值)/tu.sety(数值)

8、画圆(半径的正负表示圆心在画笔的左右)——tu.circle(半径)

9、直接设置画笔的角度(以水平向右为基准)——tu.setheading(角度)

10、回归起始状态(画笔回到起点,朝向右)——tu.home()

Linux虚拟机(Ubuntu)快速配置SSH

SSH登录虚拟机

1.安装SSH:

sudo apt-get install ssh

或者使用:sudo apt-get install openssh-client

2.启动服务:sudo service ssh start

(停止服务:sudo service ssh stop)

(重启服务:sudo service ssh restart)

3.用SSH登录本机验证是否安装成功

博主可以说是两步搞定,如果出现的问题有提示,可以按照提示的输入,若是一直报错,那就只能再针对问题寻求答案喽。