精华内容
下载资源
问答
  • 前言:此前,微软发布的wsl不支持运行docker,启动服务时会报错“Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?”虽然当时网上有一些解决办法,但都需要搭配...

    前言:

    此前,微软发布的wsl不支持运行docker,启动服务时会报错“Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?”虽然当时网上有一些解决办法,但都需要搭配Docker for Windows运行。我认为这样的话为何不直接使用Docker for Windows,所以这并不是一个令人满意的解决方案。

    Win10创意者更新后,在WSL中原生运行Docker Engine成为可能,不再需要安装多余的Docker for Windows,这显然是一个令人振奋的消息。新发布的wsl2也可以使用docker,不过wsl2使用的是Hyper-V虚拟化技术,带来真正内核的同时也带来了一些不便。例如wsl2不再跟宿主机共用同一个ip地址,而且启用wsl2后其他虚拟化工具无法使用(Wmware和Virtual Box),好在微软正在尝试解决这些问题。不过目前为止wsl1在使用上仍然占据一席之地。

    虽然现在的wsl1可以成功运行docker,但并不会跟随windows系统启动,每次开机都需要手动开启,十分麻烦。本教程旨在以最简便的方式实现docker服务跟随系统自动启动。

    前提条件:在本机的WSL中已成功安装和运行docker。

    安装docker:https://www.lance.moe/post-330.html

    开启ssh服务(可选):https://www.jianshu.com/p/cd4d604e0b44

    PS:若开启ssh服务请修改默认端口以免跟windows系统冲突。

    由于脚本需要以管理员身份运行,所以本教程使用任务计划而不是直接将脚本拖到启动文件夹。

    正式开始:

    1、首先在任意目录下新建一个vbs脚本,里面定义了要启动的服务,内容为:

    set ws=wscript.createobject("wscript.shell")
    ws.run "wsl -d ubuntu -u root /etc/init.d/ssh start",vbhide
    ws.run "wsl -d ubuntu -u root /etc/init.d/cgroupfs-mount start",vbhide
    ws.run "wsl -d ubuntu -u root /etc/init.d/docker start",vbhide

    c58f6d94198abba7099ad58f2ace8e73.png
    1

    2、然后打开“任务计划程序”,在控制面板→管理工具→任务计划程序。

    或者直接按下win+s搜索程序名称(推荐)。

    3、创建一个任务:

    3.1、在任务里设置新建一个触发器,规则为在系统启动时触发。

    d7c423585a486ed56374e72ea712ab4a.png
    3.1

    3.2、然后新建一个操作,里面填入脚本的路径。

    fe6fcab12f9bf36da41dae14534f022d.png
    3.2

    3.3、在条件里关闭电源选项。

    17c65b067d3cddae16626943bc31ec49.png
    3.3

    3.4、在常规中给当前任务命名、勾选“不管用户是否登录都要运行”和“使用最高权限运行”。

    bd20c8c6dd3090b14ed3d51bdd299060.png
    3.4

    3.5、确定并保存,这样在下次系统启动时,脚本就会被自动运行。

    需要注意的是,若要让容器跟随docker服务启动,请在创建容器时添加--restart=always--restart=on-failure 参数,已创建的容器可以使用 docker update 修改参数。

    展开全文
  • 大部分人作为电脑小白,如果遇到病毒入侵,蓝屏,黑屏,系统卡顿等情况,只能束手无策,送到电脑维修店,如果修不好,他们就会要求你重装系统,并你支付20~50元不等的费用。确实,电脑系统出现问题,没有什么是重...

    在信息化时代,计算机已经成为生活中不可或缺的一部分,但是大部分电脑所安装的Windows系统并不总是那么安全,稳定;大部分人作为电脑小白,如果遇到病毒入侵,蓝屏,黑屏,系统卡顿等情况,只能束手无策,送到电脑维修店,如果修不好,他们就会要求你重装系统,并让你支付20~50元不等的费用。

    确实,电脑系统出现问题,没有什么是重装系统解决不了的,但你完全可以省下去维修店这笔费用;

    废话不多说,接下来教你几种重装系统的方法,只需要一个U盘,甚至不需要U盘;教程我会写的很详细,即使你是小白也没关系。

    注意:按我写的步骤安装系统基本都会成功,至于里面涉及到的专业名词,不知道完全没有关系,想深入探究的可以去百度关键词。


    方法一:使用U盘安装

    工具:U盘(最好大于8G),操作系统镜像,U盘启动盘制作工具(推荐微PE工具箱)

    操作系统镜像可以去MSDN下载,里面有各版本Windows系统,选择你想要安装的版本用迅雷下载即可;

    d5b11397ba9781366cd2627b5da75402.png

    百度搜索:MSDN,或输入地址栏网址;

    U盘我就不用说了,随便去网上买一个,这里推荐几个(这里可不是广告,我可没收一分钱广告费......)

    96df43831d77444fdf665422d4d7dda4.png

    接着我们下载U盘启动盘的制作工具,这里以我推荐的微PE工具箱为例。

    说一下为什么选择微PE工具箱,据我了解使用其它启动盘制作工具制作的PE启动盘,在安装完系统后或多或少都有篡改主页,强制安装流氓软件的嫌疑,具体是哪个我就不点名了,而开发微PE工具箱的这些人是很有情怀的一帮人,可以说是目前市面上最纯净的PE制作工具了。

    百度搜索“WePE”,找到这个网站;

    e16dc73bedfb230288847e0b8cde5eee.png

    点击下载,根据你自己的电脑是多少位的就选择多少位的,不知道的右击桌面“此电脑”图标->点击“属性”;即可查看系统类型,我的电脑是64位的,所以我就选择64位版本下载。

    52451699545c4a1cf451470e55ea60fd.png

    可以先保存到网盘再进行下载

    afb5ad9696d3c36548cab83fd58b19d2.png

    下载完成后,找到下载好的文件,双击打开,然后点击右下角的U盘形状的小图标(鼠标放上去会显示“安装PE进U盘”)

    521b888df18e7060d0358af54e335855.png

    下一步:

    a6b48f3939a97e6dd61f94cf32f96859.png

    • 安装方法使用推荐的设置即可

    • 待写入U盘:选择你要制作成系统重装启动盘的U盘(推荐:至少8GB )

    • 格式化为:exFAT 和 USB-ZIP

    • U盘卷标:你U盘名字

    立即安装进U盘,点击开始制作等待即可;

    cc01673fb855a1285475f365d7743312.png


    制作完成接下来可以安装系统了,将你下载好的系统GHO(或者是ISO,ESD文件)镜像复制到U盘里

    然后将U盘插入你要重装系统的电脑上,然后开机狂按F12(不同的机型快捷键可能不同,下面给出市面大部分机型的快捷键)

    248c2825a654b5529b87008469377dd8.png

    如果出现类似如下界面就行了,选择从U盘启动,没出现的百度一下:设置BIOS从U盘启动;

    9b1b4265aebc9b4ad86d3fc5785afe53.png

    接下来就是进入PE的过程,选择微PE工具箱之后回车;

    6f2130a2414ebff66fab669543348e53.png

    然后就可以看到操作界面了,双击GHOST备份还原;

    注意:这里先写GHO文件的安装方法,如果你下载的镜像是ISO或者ESD文件的话,使用左下角的Windows安装器进行安装,跳过下面步骤,直接看ISO,ESD文件安装方法。

    8fbc2b4c70af04fa4d755f62c10e1913.png

    在弹出的界面中选择浏览,然后定位自己存放GHO镜像文件的地址,然后选择镜像文件。

    762aac4d84ad716fd966a874ea955c24.png

    下面的框核对一下,如果是自己的C盘确认无误的话就选择恢复选择的分区,然后点确认。

    acd58148b9be59e6634037bda6cf95e0.png

    点击“是”;

    3892a359f1a382dce5668ec2595a110c.png

    接下来就是重装系统的过程了,在进度条走完之后,将退出界面。将优盘拔掉之后,选择重启电脑。

    834c35b0cb0cc7b60e0746446da6d280.png

    接下来的过程不需要进行任何操作,系统将会自动完成安装过程。

    39d55dd9bfd14362f10c040d6dc040b2.png

    接下来就是一些语言,输入法设置了,相信这不会难到你吧。

    >>下面说说ISO和ESD文件安装办法

    打开Windows安装器:

    选择U盘里的esd(iso)文件,引导驱动器和安装磁盘的位置都选择“C:”(系统分区),点开始安装,再点确定。

    注意:我这里是用虚拟机进行演示,所以“选择引导驱动器”和“安装磁盘的位置”都是“D:”,但是你一定一定一定要选择“C:”!

    b75631cc3aeeaccbfe662c882120cb3e.png

    同样当下面的进度条走完后,即可关机,拔掉U盘,再开启电脑,熟悉的画面再次扑面而来。

    9c911f963aad4f349bd9f0c0229e6feb.png

    方法二:无需U盘,使用Dism++还原系统

    工具:Dism++

    优点:较第一种方法更为快速便捷,这种方法针对的是你电脑还能开机,但是电脑卡顿,中病毒,或者蓝屏想重装系统;如果你还原的是自己之前备份过的系统,还能保留你电脑之前安装的软件和环境,对于程序员来说是一大福音。

    工具下载,直接百度Dism++(或者直接输入地址栏的URL)

    点击箭头所指的下载即可

    a32cc3c37bf55dc295a412b9aa6580bd.png

    PS:Dism++是一款只有不到4MB的软件,它不止局限于系统的备份还原,功能非常非常强大,后续我会介绍它的使用教程;

    找到下载好的文件,双击打开,找到工具箱;

    fd229145fe96e9c8ecdacefdfca99de1.png

    PS:若你的系统目前没有任何问题,你可以用该工具箱里的“系统备份”备份自己的系统,以备不时之需。

    >>点击"系统还原",点击第一个浏览,选择要安装的WIM镜像文件,点击第二个浏览,选择C:盘;

    若C盘没有重要文件,可直接勾选格式化复选框;

    167906ad4bf0d5525727c280d161d8b3.png

    >>点击确定,即可安装


    这两种方法可大致满足多数场景的系统安装,如果我发现还有更好的安装方法,会在以后的文章当中分享。

    如果觉得这篇文章对你有帮助,你可以点击“好看“,或者转发给更多的朋友,你的鼓励是对我创作最大的支持!

    关注本订阅号,未来会更新更多的有趣又有用的软件使用体验文章!还有更多科技或IT界趣闻!

    展开全文
  • 在使用计算机语言进行项目开发的过程中,即使程序员把代码写的尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是考代码就能避免的,比如:客户输入数据的格式,读取文件是否存在,网络是否始终保持...

    异常概述

    在使用计算机语言进行项目开发的过程中,即使程序员把代码写的尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是考代码就能避免的,比如:客户输入数据的格式,读取文件是否存在,网络是否始终保持通畅等。

    异常:在Java语言中,将程序执行中发生的不正常的情况称为“异常”(开发过程中的语法错误与逻辑错误不叫异常)。

    Java程序在执行中出现的异常分两类:

    • Error:Java虚拟机无法解决的严重问题,例如:JVM内部错误,资源耗尽等严重情况。一般不编写针对性的代码进行修复

      • 举两个例子
        • java.lang.StackOverflowError:栈溢出
        • java.lang.OutOfMemoryError:堆溢出
    • Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:空指针访问,视图读取不存在的文件,网络连接中断,越界等等。

    异常举例

    import java.util.Date;
    
    import org.junit.Test;
    
    import java.util.Scanner;
    
    /**
     * java.lang.Throwable:
     *      |
     *      |------java.lang.Error:一般不编写针对性的代码进行处理
     *      |
     *      |------java.lang.Exception:可以进行异常的处理
     *              |
     *              |------编译时异常(checked)
     *              |       |   
     *              |       |------IOException  :IO异常
     *              |               |
     *              |               |------FileNotFoundException:文件或目录不存在
     *              |
     *              |------运行时异常(unchecked)
     *                      |
     *                      |------NullPointerException : 空指针异常
     *                      |
     *                      |------ArrayIndexOutOfBoundsException:数组越界
     *                      |
     *                      |------ClassCastException   : 类型转换异常
     *                      |
     *                      |------NumberFormatException:数字格式化异常
     *                      |
     *                      |------InputMismatchException: 输入异常
     *                      |
     *                      |------ArithmeticException : 算数异常
     * 
     */ 
    public class ExceptionTest {
        // 空指针异常
        @Test
        public void test1(){
            int[] arr = null;
            System.out.println(arr[0]);
    
        }
    
        // 越界
        @Test
        public void test2(){
            int[] arr = new int[3];
            System.out.println(arr[4]);
        }
    
        // 类型转换异常
        @Test
        public void test3(){
            Object obj = new Date();
            String str = (String) obj;
            System.out.println(str);
        }
    
        // 数字格式化异常
        @Test
        public void test4(){
            String str = "abc";
            int num = Integer.parseInt(str);
            System.out.println(num);
        }
    
        // 输入异常
        @Test
        public void test5(){
            Scanner scanner = new Scanner(System.in);
            int a = scanner.nextInt();
            // 如果这里输入一个非int就会报异常
            System.out.println(a);
            scanner.close();
        }
    
        // 算数异常
        @Test
        public void test6(){
            int a = 10;
            int b = 0;
            System.out.println(a / b);
        }
    }
    

    异常处理

    Java提供的异常处理是抓抛模型。

    Java程序的执行过程中如出现异常,会生成一个异常类对象,该异常对象将被提交给Java运行系统,这个过程叫做抛出异常。

    异常对象的生成分为两种,第一种是虚拟机自动生成,在程序运行过程中,虚拟机检测到程序发生问题,如果在当前代码中没有找到对应的处理程序,就由后台自动创建一个对应异常的实例对象抛出;第二种是由开发人员手动创建,如果不抛出则对程序没有任何影响。

    try-catch-finally

    语法:

    try{
    	// 可能出现异常的代码
    }catch(异常类型1 变量名1){
    	// 处理异常1
    }catch(异常类型2 变量名2){
    	// 处理异常2
    }finally{
    	// 一定会执行的代码
    }
    

    例子:

    public class TryTest {
        public static void main(String[] args) {
            /**
             * finally 是可选的
             * 
             * 使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应的异常对象,
             * 然后去catch中匹配异常,如果匹配成功就执行catch块中的代码,如果匹配失败则抛出异常。
             * 
             * try-catch-finally结构运行完成后,继续执行后面的代码,如果catch中报错,只能执行finally中的代码
             * 
             * 优先度高的异常应该在优先度低的异常的后面(子类异常必须在父类异常之前)
             * 
             * 常用的异常对象处理方式:①String getMessage()     ②printStackTrace()
             * 
             * try-catch-finally结构内的变量是局部变量
             * 
             * finally中的代码一定执行
             * 
             * 一般会将数据库连接、输入输出流、socket等资源的释放操作放到finally中
             * 
             * try-catch-finally结构可以相互嵌套
             */
            try{
                String str = "abc";
                int num = Integer.parseInt(str);
                System.out.println(num);
            }catch(NumberFormatException e){
                System.out.println(e.getMessage());
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                System.out.println("执行成功");
            }
        }
    }
    

    体会1:使用try-catch-finally结构处理编译时异常,使得程序在编译时就不再报错,但是运行时仍可能报错,相当于我们使用try-catch-finally结构将一个编译时出现的异常延迟到运行时出现。

    体会2:开发时,因为运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally结构,针对编译时异常,一定要考虑异常的处理。

    throws

    throws一般用于方法的定义中,表示抛出异常,谁调用这个方法就让谁来解决这个异常。

    
    
    public class ThrowsTest {
        // 这里调用了test方法,所以他接收异常来处理,而且他是main方法,必须处理异常。
        public static void main(String[] args) {
            try{
                test();
            }catch(ArithmeticException e){
                e.printStackTrace();
            }
            
            
            // 因为test2内已经处理了异常,所以main可以直接调用
            test2();
            
            // 方法重写的抛出异常
            test3(new SubClass());
    
        }
    
        public static void test3(SuperClass s){
            try{
                // 如果subclass的method方法抛出的异常比superclass抛出的异常还大,有可能造成子类的异常无法被处理
                s.method();
            }catch(ArithmeticException e){
                e.printStackTrace();
            }
        }
    
        public static void test2(){
            try{
                test();
            }catch(ArithmeticException e){
                e.printStackTrace();
            }
        }
    
    
        // 报异常后不自己处理,抛出异常
        public static void test() throws ArithmeticException{
            int a = 10;
            int b = 0;
            System.out.println(a / b);
        }
    }
    
    class SuperClass {
        public void method() throws ArithmeticException{
            
        }
    }
    
    class SubClass extends SuperClass{
        @Override
        // 可以声明 ArithmeticException 同级别的异常,但是不能声明他的父类级别的异常  例如 Exception
        public void method() throws ArithmeticException{
            
        }
    }
    
    手动抛出异常
    public class StudentTest {
        public static void main(String[] args) {
            Student s = new Student();
            try{
                // 传入负数,程序抛出自定义异常。
                // 传入正数,无异常
                s.regist(-100); 
                System.out.println(s);
            }catch(Exception e){
                // 处理异常
                System.out.println(e.getMessage());
            }
        }
    }
    
    
    class Student{
        private int id;
        
        public void regist(int id){
            if(id > 0){
                this.id = id;
            }else{
                // 手动抛出异常
                throw new RuntimeException("输入的数据非法");
            }
        }
    
        @Override
        public String toString() {
            return "Student [id=" + id + "]";
        }
    }
    
    自定义异常

    我们使用的异常,哪怕是手动抛出的异常,都是Java为我们提供好的,那么我们能不能自定义异常呢?

    /**
     * 首先继承与现有的异常结构
     * 必须提供全局变量serialVersionUID
     * 提供重载的构造器
     */
    
    public class MyException extends RuntimeException{
        // 自动导入的一个静态属性
        private static final long serialVersionUID = -7034897196939L;
    
        public MyException(){
    
        }
    
        public MyException(String msg){
            super(msg);
        }
    }
    

    这样就算自定义了一个异常,然后把他放到上一个例子里。

    public class StudentTest {
        public static void main(String[] args) {
            Student s = new Student();
            try{
                s.regist(-100); 
                System.out.println(s);
            }catch(RuntimeException e){
                // 处理异常
                System.out.println(e.getMessage());
            }
        }
    }
    
    
    class Student{
        private int id;
        
        public void regist(int id) throws Exception{
            if(id > 0){
                this.id = id;
            }else{
                // 手动抛出异常
                throw new MyException("输入的数据非法");
            }
        }
    
        @Override
        public String toString() {
            return "Student [id=" + id + "]";
        }
    }
    

    练习

    判断运行结果

    public class ReturnExceptionDemo {
    	static void methodA() {
    		try {
    			System.out.println("进入方法A");
    			throw new RuntimeException("制造异常");
    		}finally {
    			System.out.println("用A方法的finally");
    		} 
    	}
    	
    	static void methodB() {
    		try {
    			System.out.println("进入方法B");
    			return;
    		} finally {
    			System.out.println("调用B方法的finally");
    		}
    	}
    
    	public static void main(String[] args) {
    		try {
    			methodA();
    		} catch (Exception e) {
    			System.out.println(e.getMessage());
    		}
    		methodB();
    	}
    }
    
    ----------
    进入方法A
    用A方法的finally
    制造异常
    进入方法B
    调用B方法的finally
    

    编写应用程序EcmDef.java,接收命令行的两个参数,要求不能输入负数,计算
    两数相除。
    对 数 据 类 型 不 一 致 (NumberFormatException)
    缺 少 命 令 行 参 数(ArrayIndexOutOfBoundsException)
    除0(ArithmeticException)
    输入负数(EcDef 自定义的异常)进行异常处理。


    提示:
    (1)在主类(EcmDef)中定义异常方法(ecm)完成两数相除功能。
    (2)在main()方法中使用异常处理语句进行异常处理。
    (3)在程序中,自定义对应输入负数的异常类(EcDef)。
    (4)运行时接受参数 java EcmDef 20 10 //args[0]=“20” args[1]=“10”
    (5)Interger类的static方法parseInt(String s)将s转换成对应的int值。 如:int a=Interger.parseInt(“314”); //a=314;

    /**
     * 编写应用程序EcmDef.java,接收命令行的两个参数,要求不能输入负数,计算
     * 两数相除。
     * 对数据类型不一致(NumberFormatException) 
     * 缺少命令行参数(ArrayIndexOutOfBoundsException)
     * 除0(ArithmeticException)
     * 输入负数(EcDef 自定义的异常)进行异常处理。
     * 提示:
     * (1)在主类(EcmDef)中定义异常方法(ecm)完成两数相除功能。 
     * (2)在main()方法中使用异常处理语句进行异常处理。 
     * (3)在程序中,自定义对应输入负数的异常类(EcDef)。 
     * (4)运行时接受参数 java EcmDef 20 10 //args[0]=“20” args[1]=“10”
     * (5)Interger类的static方法parseInt(String s)将s转换成对应的int值。 如:int a=Interger.parseInt(“314”); //a=314;
     */
    
    public class EcmDef {
        public static void main(final String[] args) {
            try{
                final int i = Integer.parseInt(args[0]);
                final int j = Integer.parseInt(args[1]);
        
                final int result = ecm(i, j);
                System.out.println(result);
            }catch(NumberFormatException e){
                System.out.println("数据类型不一致");
            }catch(ArrayIndexOutOfBoundsException e){
                System.out.println("缺少命令行参数");
            }catch(ArithmeticException e){
                System.out.println("除0");
            }catch(EcDef e){
                System.out.print(e.getMessage());
            }
        }
    
        public static int ecm(int i, int j) throws EcDef {
            if(i < 0 || j < 0){
                throw new EcDef("分子或分母是负数了");
            }
            return i / j ;
        }
    }
    
    
    class EcDef extends Exception {
    
        private static final long serialVersionUID =  -3387516993124229948L;
    
        public EcDef(){
    
        }
    
        public EcDef(String msg){
            super(msg);
        }
    }
    
    
    展开全文
  • 3、前端和后端工作内容的差别前端主要是考虑怎样能用户觉得用起来更舒服,考虑界面布局、交互效果、页面加载速度等。后端更多的是与数据库进行交互以处理相应的业务逻辑。需要考虑的是如何...

    1、如何区分前端和后端

    通俗讲,用户看到的部分都叫前端。

    而用户看不到的部分可以统称为后端。

    2、前端和后端的呈现形式

    前端的呈现形式有web端、移动端(ios、安卓)、小程序等。

    后端系统一般只有一个,收集不同前端反馈回来的数据。

    3、前端和后端工作内容的差别

    前端主要是考虑怎样能让用户觉得用起来更舒服,考虑界面布局、交互效果、页面加载速度等。

    后端更多的是与数据库进行交互以处理相应的业务逻辑。需要考虑的是如何实现功能、数据的存取、平台的稳定性与性能等。

    4、如何分析bug(bug类型)

    当bug出现时,一般来说分大致3种情况:

    (1)数据库层面的:

    可能少某个字段,或者字段值为空等等,这些可能在设计数据库时就埋下了错误的种子,导致程序调用数据库错误的数据产生bug,这一类问题不算普遍,但也是最容易忽视的一种情况,有时候从数据库入手定位bug说不定还能发现数据库的设计缺陷。

    (2)网络层面的:

    通常这种都是网络情况较差的时候产生的,比如手机的移动网络信号不好,又或是公司网络不稳定,导致js/css未加载完全或者请求超时等等,这种问题其实非程序bug造成的,可以不用提交bug,也不用让开发毫无头绪的去查代码的问题。当然如果可以的话也可以当优化建议提给开发,让他优化代码,比如压缩js/css,增加超时时间,超时后的重试机制。

    (3)代码层面的:

    普遍的bug基本都是代码有问题造成的,排除掉1和2剩下后就可以确定是程序bug了。对于了解网络架构的人来说,其实程序也分前端和后端的,一般对于界面显示有问题直接可以判断是前端的问题,比如系统兼容性,浏览器兼容性。

    而对于数据或者逻辑上的问题,则需要(检查接口)前端和后台之间是通过接口文件相互联系的,通过抓包工具来进行分析 :

    1)请求未返回数据,可能是client(客户端)请求数据错误,可能是server端(服务器端)处理错误。

    2)请求返回错误的数据,那就是server端处理错误。

    5、如何区分前端问题和后端问题

    前台的bug通常是功能、界面和兼容性等有关;

    后台的bug与逻辑、性能和安全性有关。

    与数据相关的错误、排序问题大多是后台问题;

    对于APP页面toast提示可能是后台给的,可能是APP给的。

    (1)检查接口

    前端和后台之间是通过接口文件相互联系的,测试人员可以通过查看接口文件,来区分前端和后台bug。

    (2)情况分析

    a、检查请求的数据是什么?反馈的数据又是什么?

    通过抓包工具来进行抓包分析。

    大多数的浏览器都有自带的抓包插件,如 FireFox 的 FireBug 插件,Chrome、360急速模式、搜狗高速模式自带的 DevelopTools 插件(F12开启),在 NetWork 中可以看到当前页面发送的每一个http请求。请求接口、传参、响应三部分来判断Bug,另外,也可以在浏览器的控制台进行js代码调试定位。

    1)请求接口URL是否正确

    如果请求接口URL不正确,为前端Bug;

    2)http请求中的参数是否正确

    如果http请求中的参数不正确,为前端Bug;

    3)如果接口URL和参数都正确,查看响应内容是否正确

    如果这种情况下响应内容不正确,则为后端Bug。

    4)如果JS基础比较好的话,也可以在浏览器的控制台中输入JS代码进行调试。

    b、根据接口的文件,检查数据是否正确。

    如果发送的数据是正确的,但是后台反馈的数据是不符合需求的,那就是后台的问题。

    如果前端没有请求接口,或者请求的时候发送数据与需求不符,那这个时候就是前端的问题了。

    6、如何精准的定位前台bug并且描述bug?

    (1)按F12在 console(控制台)中查看报错信息,对于出错的 js 可以在 Sources 下查看对应报错的资源文件,截图放入bug单,bug定位策略:

    1)网站前台的权限控制:没有权限的用户是不能直接输入url的方式来进行访问的,必须进行登录。涉及到权限的测试,一定不能漏掉url的方式也需要验证一下。而在单个页面进行W3C测试时则需要去掉该权限控制。

    2)网站前台的title,对于这个也很容易忽视。进入到不同的功能页面,title显示应该是有,并且要和你进入的页面一致。title就是在浏览器最左上角看到的那些文字

    3)http和https的注意点:https是一种安全链接,它是需要证书的,而http就是普通链接,所以在你的系统中客户会要求某些关键的地方加上这种安全连接,那么此时你需要注意的是,对于不需要安全链接的地方也要去重点测试,有些开发会很容易忽略这一点。要打开HTTPS开头的网站,前提是该网站安装了SSL证书,只有安装了SSL证书的网站,并且开启了 443 端口,你才可以通过HTTPS加密协议无访问。如果没有则不能访问。

    (2)前端bug主要分为3个类别:HTML,CSS,Javascript 三类问题:

    一)出现文本的问题基本都是html的bug

    二)出现样式的问题基本都是CSS的bug

    三)出现交互类的问题基本都是Javascript的bug

    一)HTML

    最常见的HTML的问题—就是标签的问题了,最常见的排查和解决办法就是查看页面源代码,然后通过检查标签的工具,现在暂时提供 idea.exe 进行检查,有其他更好的工具再进行推荐。

    常见问题类别:

    1.标签闭合—>>> 表象,页面中出现大范围的混乱,就是少了标签的情况,导致标签未闭合。

    2.标签浮出—>>> 例如鼠标移动到文本位置,浮出全名的这种浮出形式都属于标签浮出的问题。

    3.标签在不同的浏览器的一种解析方式的不同导致的前端bug,例如如下结构:

    该部分可以看做为一个大的框即是标签 内嵌标题的标签

    ,里面再有这些个内容,那么在不同的浏览器中,可能ie和FF的解析会产生不同,假设IE解析为

    的一种形式,但在FF下可能解析为

    的两行的形式从而导致前端在 ing 里面的格式产生混乱。

    4.页面定点的问题->>> 最明显的前端功能,在于点击某个链接将页面位置定位到对应的位置。

    我们可以通过右键,查看元素的工具进行定位到毛点所定位到的位置,如果出现问题这种问题很直观,并且能通过这种方法直接定位到问题。

    5.页面的跳转,也属于html的问题,大家在出现点击未跳转或者跳转方式不正确的问题,直接可以定位到跳转属性的问题,找到对应的跳转对应的块提供给开发人员即可。

    二)CSS,产生样式问题。例如:排版,布局,颜色,背景等,分:

    1.兼容型bug

    a) 表现:仅在少数几个浏览器上出现

    b) 原因:浏览器的解析不一致

    c) 解决:根据实际情况进行前端代码的通用性

    d) 类别:

    脚本兼容型bug:在出现对应交互的问题就基本可以定位到脚本兼容型bug,例如 DIV 的显示和层结构。实际可以参考聚划算的几个商品鼠标移动到小图的时候,对应大图展示的功能。

    页面样式兼容型bug:直接表象在样式上,都是基于框架的页面展示错误,很容易定位

    2.业务性bug

    a) 表现:在所有浏览器下都有该问题

    b) 原因:对业务不熟悉

    c) 解决:根据需求进行修改达到业务要求

    d) 总结:该类型的定位,主要在和实现的要求不一致,最直接表现在页面的友好型,用户的可用性的bug,可以定位为该类型

    3.内容型bug

    a) 表现: 前端自测正确,但在填入内容后,出现的错误,内容消失等

    b) 原因: 扩展性未考虑周全

    c) 解决: 进行overflow test

    d) 总结: 输入内容的长度限制等功能可定位为内容型bug

    三)Javascript

    a) 最直接的判断方法,刷新页面,出现滞后显示的一些模块基本都为脚本的输出块。该部分的一些问题可以参照兼容型 bug 中类别的 脚本兼容型bug。

    b) 有产生交互类的问题,大多数都可以定位到是属于javascript产生的问题,该部分大多不会报错

    c) 有如下错误提示类的都属于javascript的bug:

    页面左下方有出现javascript的错误提示;

    有弹出错误信息提示的bug;

    浏览器返回的一些错误弹出框。

    7、如何精准的定位后端bug并且描述bug?

    (1)根据后台日志文件定位:

    1)查看报错日志

    查看报错日志,通过日志分析,有利于帮助开发更好地定位问题,初期 bug单 可以携带日志一起发送指给开发。

    2)查看数据库的数据

    了解所测功能的数据表结构,测试过程中,查看数据库的数据,确认数据的正确性。

    3)查看缓存(如 Memcache、apc、redis 等缓存)是否正确

    (2)后端部署在liunx系统使用secureCRT进行日志获取,常见问题分类:

    1)编码问题:tomcat是新的,需要改编码 修改tomcat的server.xml文件,特别是windows下的项目重新部署到linux系统下。

    2)空指针:程序问题,一般没有考虑到为空情况,或者主外键约束的数据为空,或者删除关联数据,导致为空。

    3)长度过长:超过最大长度,测试环境修改数据库字段长度后生产环境未修改,导致报错。

    4)非法数据:特殊字符,是否对特殊字符进行容错处理。

    5)内存溢出:重启。

    重启的一般情况:

    1)热部署 (新增部分功能,或者修改部分bug)

    2)发布新版本 (整个系统)

    3)内存溢出,此时重启服务器即可

    4)由于项目中有线程程序,./shutdown脚本关闭tomcat程序,不能把启动的线程全部关闭,造成服务器启动线程未关闭的错误。

    Linux系统中重启Tomcat的一般步骤:(一般是先关闭进程,然后进行重启 ,如果 /要删除某个文件:rm 文件名,或者不为空的文件夹:rm -rf 文件夹名)

    cd usr/local/   //测试服务器名称/bin

    ps -exf         //看测试服务器下运行的项目的主进程(最前面的数字为PID进程号)

    kill -9 PID     //强制关闭某一项目的主进程

    ./startup.sh    // ./**.sh 即执行重启shell脚本文件 ,此时在测试服务器的bin下面,直接执行即可,其余的加上 chmod a+x shell脚本文件,也可用./执行

    ps aux 和 ps -ef命令区别:

    ps aux 是用BSD的格式来显示java这个进程

    显示的项目有:USER,PID,%CPU,%MEM,VSZ,RSS,TTY,STAT,START,TIME,COMMAND

    ps -ef 是用标准的格式显示java这个进程

    显示的项目有:UID,PID,PPID,C,STIME,TTY,TIME,CMD

    (3)一般的问题原因总结:

    1)程序:为空判断,增删改查,不同公众号调用的接口也不一样

    2)数据初始化:数据库表结构和数据初始化,权限配置,特别注意生产环境上的用户数据修改,此时用户在使用,很重要!!!

    3)故障无法重现时:

    a)看日志,根据日志定位原因,则在测试环境中按照日志提示构造条件相同的测试案例测试,尝试在测试环境中将问题重现。

    b)测试环境和配置与实际的工程环境和配置有哪些差异等等。同时主动与开发负责人、工程实施人员以及有经验的项目经理讨论,分析可能导致的原因。

    c)测试环境ok,生产环境新增时保存失败,查看后台日志报长度溢出,数据库内容字段要求和生产环境不一致。

    (4)如何查看日志(tail -f)?

    一台服务器可以部署多个应用:

    cd usr/local/测试服务器名称/logs//查看先进入到服务器的logs目录下

    tail -f catalina.out//监视catalina.out 文件的尾部内容(默认10行)

    (5)辅助工具:linux和SQL

    linux查看日志

    SQL用来筛选数据或直接进行数据修改状态,多用于集成测试过程中前后流程相连接

    8、浏览器兼容性和网页规范标准测试

    浏览器兼容性测试(偏主流浏览器,如谷歌,火狐,IE8以上):

    https://dev.windows.com/en-us/microsoft-edge/tools/staticscan/

    W3C网页验证:(判断网页书写是否符合规范,记住此处必须去掉权限控制,单个单元页面url需要跟参数)

    https://validator.w3.org/

    W3C手机端页面检测(如手机微信菜单下的页面):

    https://validator.w3.org/mobile-alpha/

    9、互联网与传统测试互联网测试与传统测试的区别

    (1)最大的不同:互联网产品需要自己部署和运营,用户使用瘦客户端(浏览器,app或一个需要安装的client),核心的数据和业务逻辑在互联网公司的机房,在IDC,在云端。

    如:我们做的系统用户只需一个浏览器,服务器用的阿里云,部署和运营只需要一个运维人员即可。

    考虑现网(生产环境)存在下面两个问题:

    1)如何发布功能到现网?

    互联网测试完一般可直接发布,测试周期短,有时候需要进行灰度发布,先让部分用户用起来,发布完做生产验证。

    2)如何保证测试环境和生产环境同步?

    测试环境比较难搞,牵扯的系统平台比较多,用到很多微信平台的接口,这个很难自己搭建或者用mock。

    另外保证测试环境和到生产环境都是好的,需要代码和数据库,以及环境配置都要保持一致,这需要相应的机制和工具来验证和同步。

    (2)互联网产品节奏很快

    有的软件公司,基本是进行二次开发,周期长,每次都需要经过下面几个完整的测试流程:

    客户提出需求>>>BA和客户沟通,确定出需求和解决方案>>>测试人员根据需求说明书和解决方案编写测试用例>>>进行概要评审>>>进行详细设计评审>>>开始测试>>>回归测试>>>生产验证。

    现在的互联网产品测试基本为:

    产品经理确定好测试需求>>>开发人员写详设>>>(此阶段可以进行设计bug检查)>>>开发人员开发>>>测试人员测试,上线

    弊端:来不及测试设计,来不及自动化,短时间内如何保证测试的覆盖率和质量?>>>(探索式测试应势而生)

    (3)更多的人参与到测试中

    互联网公司有专门的测试团队的比较少,一般开发和测试比例: 7:1,如何保证质量?

    1)开发人员的自测

    开发人员进行单元测试,测试用例的通过率,同一个版本拉代码的次数

    2)产品或运营人员的体验

    在这里基本我就相当于用户,进行产品体验,或者根据免费试用者反馈的意见进行优化

    3)发布之前的评审

    注意环境,配置,数据方面的问题

    (4)有一些是免测试的

    并不是所有发布到生产环境的东西都需要在测试环境检验,如:图片样式改动,小bug修复,但是哪些免测是个复杂的问题

    (5)海量用户带来的挑战

    1)性能方面

    如何做轻量级的性能测试

    2)浏览器的兼容性

    现在的系统大多基于主流的火狐,谷歌,IE8以上,放弃浏览器兼容就等于放弃一部分客户。

    (6)测试工具和技术方面

    传统的企业花钱购买商业软件,如QTP,loadrunner,或者自己开发的项目管理工具

    大部分的互联网公司使用开源或自主研发的,如 selenium,appium,robotium,monkeyrunner,jmeter

    相同点:

    1.都需要非常熟悉产品和业务

    2.都需要了解产品的技术(深度测试方面性能分析,内存泄露,web服务器,cache,代理)

    3.具体的测试技术

    4.测试设计的方法

    5.测试人员的技术体系

    展开全文
  • 但是当应用程序用离开这个阶段,被推送到生产环境时,会有成吨的意外因素你的代码不稳定。这些因素包括高可扩展性、大量的用户数据库查询、高并发使用量、不可预测的状态或系统行为等等。因此,可能会发生各种疯狂...
  • 如何让定时任务单独执行一个sql语句报错在linux or Unix系统中有一个叫crontag的东西。 你可以设定执行的时间,它就是每天循环执行了。 格式:(second hour date month week) 00 10 * * * /u01/app/cronjob/exe_select...
  • 相信很多对于3dmax软件的脚本插件的好用与便捷度是非常喜欢的,但是如果安装了很多脚本插件,也会出现一些错误和冲突,尤其是每次打开3dmax都会出错,真的人头疼那么如果插件每次打开都报错的话,我们如何解决下面...
  • 相信很多对于3dmax软件的脚本插件的好用与便捷度是非常喜欢的,但是如果安装了很多脚本插件,也会出现一些错误和冲突,尤其是每次打开3dmax都会出错,真的人头疼那么如果插件每次打开都报错的话,我们如何解决下面...
  • 当我在lambda表达式中涉及递归时, vscode会提醒语法错误, 虽然不影响程序运行, 但是如何让系统继续提醒此处的错误? 这是否是用lambda表达式写递归问题时一定会发生的语法"错误"? 2. 用lambda表达式写: ``...
  • 我看过很多刚入门的程序员,要么是自学编程的,没有系统地学过算法,连二分查找都不知道;要么是本科念完,算法都还给老师了,总之就没有这样一种基础意识。看他们定位问题,从第一行代码开始加断点或者是打印上下文...
  • 公司有购买的监控软件北塔系统监控,由于购买的版权中只包含了有限台数据库服务器的监控,所以只监控了比较重要的几台服务器。 后边出现过没有监控的数据库服务器表空间爆满导致生产业务出现问题,后续手工处理数据...
  • 今天有个同事我帮忙看一张报表, 这张报表是一个开源的系统产生出来的,后台数据库用的是MySQL.问题是一张报表的数据是错误的,当时另外一张报表是对的,所以希望能够找出后台逻辑,这样可以对报表进行修改。 这是...
  • XX系统,通过FTP给客户实时传送文件,正常逻辑是客户收到文件后,自动删除FTP服务器上的本地文件,但经常出现文件已经推送了,客户没删除文件的情况。每个文件其实是很小的,可能几K,但是量很大,1天几万个,以至于...
  • vs很多带“_s”后缀的函数是为了原版函数更安全,传入一个和参数有关的大小值,避免引用到不存在的元素,有时黑客可以利用原版的不安全性黑掉系统。比如:char d[20];写成scanf_s("%s",d,20);才是正确的,有这个...
  • 解决navicat连接mysql失败报错2059

    千次阅读 2020-03-04 10:36:22
    大家好我是你们的朋友JamesBin,MySQL 是最流行的关系型数据库管理系统,但是今天在装的时候发现无法进行与Navicat进行连接并且报错2059,下面看一下我是如何处理的吧,网上的好多昂发都无效。 问题引入 报上面的...
  • ,作为一个PHP程序员,装完系统的第一件事就是安装PHP的环境了,下面PHP程序员雷雪松就详细的和大家分享下如何解决WAMP启动报错”无法启动此程序,因为计算机中丢失 MSVCR110.dll。尝试重新安装该程序以解决
  • 当然,这些问题并非不能克服,我们来一起看看如何去监控并定位线上的问题吧。背景:市面上的前端监控系统有很多,功能齐全,种类繁多,不管你用或是不用,它都在那里,密密麻麻。往往我需要的功能都在别人家的...
  • Linux虽然没有蓝屏现象,不过Kernel报错有时也会人头疼。有时重启后正常,linux系统运行一段时间后又down了,总不能出现问题就reboot啊。我从网上搜集一下资料,整理了出来,希望大家能在评论与我交流您的看法与...
  • 1背景1.1讲一个故事以前我们公司招了一个自称非常熟练loadrunner的员工,有一次分配给他测试sso单点登录系统的性能测试。登录一个网站A,需要输入用户名密码,然后在访问另一个网站B,因为在网站A已经登录过,所以B...
  • 如何停止系统广播Windows系统 电脑资料 我有两台4100装5.1a原来各配两个电源现在都只剩下一个了 我有两台4100 装5.1a 原来各配两个电源现在都只剩下一个了系统不停的在报电源错误很是烦人 前两两天不知怎么都不报错...
  • 根据微软给出的数据,win10是目前普及最快的操作系统,目前已有超过4亿台设备运行该系统。...这次跟大家分享下如何通过系统简单设置,wind10运行更加流畅的几个小技巧。解决方法:1.关闭视觉效果右击开始...
  • Apache安装使用apt安装(如果刚装系统没有换源,建议先换源,mysql安装文章有写如何换源)sudo apt-get install apache21.1 配置没有什么特殊的配置,我觉得不要apache占用我们的80端口就好它的配置文件可能跟我们以前...
  • ubuntu系统如何让php支持GD

    千次阅读 2013-04-18 15:20:47
    php程序中,增加了一个图形缩放的函数,发现调用function_exists("imagecreatefromjpeg")时,会报错。 检查php的配置,显示如下   发现上述问题是php中没有包含GD配置所致。   可以通过apt-get install ...
  • 有些人在使用TerraExplorer Pro 7版本进行web二次开发的时候,常会遇到下面截图中这样的问题, ...Win7 64位系统,IE11,如何让IE的Tab强制运行64位内核呢? 我的机器之前IE新打开的Tab,总是运行32位的,...
  • 在运行python代码时,经常因为python安装路径的原因出现各种各样的问题。...设置编码格式为utf-8,防止脚本里面注释出现中文报错。 #! /usr/bin/python #表示调用 /usr/bin 下的python解释器运行...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 178
精华内容 71
关键字:

如何让系统报错