Java之MVC模式实现注册登录功能

文章目录 一、描述源码结构图 二、需要的jar包三、分层源码3.1 bean下的Users类,代码入下3.2 DAO层里面的接口类、实现类,代码如下接口类代码如下实现类代码如下: 3.3 framework框架下有Action接口,和该接口的实现类Action接口类代码如下Action实现类Login登录实现类Action实现类register登录实现类实现Action的servlet 3.4 controller层控制的源码Login的servlet源码如下:Register的servlet源码如下: 3.5 web.xml配置文件 一、描述 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据。 Servlet+JSP+JavaBean模式程序各个模块之间层次清晰,web开发推荐采用此种模式。 这里以一个最常用的用户登录注册程序来讲解Servlet+JSP+JavaBean开发模式,通过这个用户登录注册程序综合案例,把之前的学过的XML、Xpath、Servlet、jsp的知识点都串联起来。 源码结构图 二、需要的jar包 dom4j-1.6.1.jar dom4j用于操作XML文件 jaxen-1.1-beta-6.jar 用于解析XPath表达式 commons-beanutils-1.8.0.jar 工具类,用于处理bean对象 commons-logging.jar commons-beanutils-1.8.0.jar的依赖jar包 jstl.jar jstl标签库和EL表达式依赖包 standard.jar jstl标签库和EL表达式依赖包 三、分层源码 3.1 bean下的Users类,代码入下 package com.bean; /** * @Author: pomelo * @Create: 2020-03-25 12:15 * @ProjectName: MVC * @Package: com.bean * @ClassName: Users * @Description: 用户实体类 * @Version: 1.0 */ public class Users { private int id; private String name; private String password; private String tel; public Users(){}; public Users(String name, String password) { this.

深入理解Binder机制4-bindService过程分析

一、概述 1.1 Binder架构 Android内核基于Linux系统,而Linux系统进程间通信方式有很多,如管道,共g享内存,信号,信号量,消息队列,套接字。而Android为什么要用binder进行进程间的通信,这里引用gityuan在知乎上的回答: (1)从性能的角度数据拷贝次数 Binder数据拷贝只需要一次,而管道,消息队列,Socket都需要二次,但共享内存连一次拷贝都不需要;从性能角度看,Binder性能仅次于共享内存。 (2)从稳定性的角度 Binder基于C/S架构,Server端和Client端相对独立,稳定性较好,而共享内存实现方式复杂,需要考虑到同步并发的问题。从稳定性方面,Binder架构优于共享内存。 (3)从安全的角度 传统Linux进程间通信无法获取对方进程可靠的UID/PID,无法鉴别对方身份;而Android为每个应用程序分配UID,Android系统中对外只暴露Client端,Client端将任务发送给Server端,Server端会根据权限控制策略,判断UID/PID是佛满足访问权限。 (4)从语言层面的角度 Linux是基于C语言,而Android是基于Java语言,Binder符合面向对象的思想,Binder将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法。Binder对象作为一个可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却可以在系统的每个进程之中。 (5)从公司战略的角度 Linux内核源码许可基于GPL协议,为了避免遵循GPL协议,就不能在应用层调用底层kernel,Binder基于开源的OpenBinder实现,作者在Google工作,OpenBinder用Apache-2.0协议保护。 Binder架构采用分层架构设计,每一层都有不同的功能。 分层的架构设计主要特点如下: 层与层具有独立性;设计灵活,层与层之间都定义好接口,接口不变就不会有影响;结构的解耦合,让每一层可以用适合自己的技术方案和语言;方便维护,可分层调试和定位问题 Binder架构分成四层,应用层,Framework层,Native层和内核层 应用层:Java应用层通过调用IActivityManager.bindService,经过层层调用到AMS.bindService; Framework层:Jave IPC Binder通信采用C/S架构,在Framework层实现BinderProxy和Binder; Native层:Native IPC,在Native层的C/S架构,实现了BpBinder和BBinder(JavaBBinder); Kernel层:Binder驱动,运行在内核空间,可共享。其它三层是在用户空间,不可共享。 1.2 Binder IPC原理 Binder通信采用C/S架构,包含Client,Server,ServiceManager以及binder驱动,其中ServiceManager用于管理系统中的各种服务,下面是以AMS服务为例的架构图: 无论是注册服务还是获取服务的过程都需要ServiceManager,此处的ServiceManager是指Native层的ServiceManager(C++),并非指framework层的ServiceManager(Java)。ServiceManager是整个Binder通信机制的大管家,是Android进程间通信机制Binder的守护进程。Client端和Server端通信时都需要先获取ServiceManager接口,才能开始通信服务,查找到目标信息可以缓存起来则不需要每次都向ServiceManager请求。 图中Client/Server/ServiceManager之间的相互通信都是基于Binder机制,其主要分为三个过程: 1.注册服务:AMS注册到ServiceManager。这个过程AMS所在的进程(system_server)是客户端,ServiceManager是服务端。 2.获取服务:Client进程使用AMS前,必须向ServiceManager中获取AMS的代理类。这个过程:AMS的代理类是客户端,ServiceManager是服务端。 3.使用服务:app进程根据得到的代理类,便可以直接与AMS所在进程交互。这个过程:代理类所在进程是客户端,AMS所在进程(system_server)是服务端。 Client,Server,ServiceManager之间不是直接交互的,都是通过与Binder Driver进行交互的,从而实现IPC通信方式。Binder驱动位于内核层,Client,Server,ServiceManager位于用户空间。Binder驱动和ServiceManager可以看做是Android平台的基础架构,而Client和Server是Android应用层。 前面已经分析过第一第二个过程注册服务和获取服务,本文主要介绍第三个过程使用服务,以bindService过程为例。 1.3 bindService流程 bindService流程如下图,从客户端调用bindService到服务器端通过ServiceConnected对象返回代理类给客户端,下面将从源码的角度分析这个过程。 二、客户端进程 2.1 CL.bindService [->ContextImpl.java] @Override public boolean bindService(Intent service, ServiceConnection conn, int flags) { warnIfCallingFromSystemProcess(); return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser()); } 2.2 CL.bindServiceCommon [->ContextImpl.java] private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) { // Keep this in sync with DevicePolicyManager.

SpringBoot学习(二)——环境配置

Tomcat默认的端口是8080,但是有的时候我们需要启动两个Tomcat,那么8080端口被一个占用,另一个工程肯定没法启动。还有就是在实际开发中,我们的环境是有多种的,比如开发环境,测试环境。如何灵活的切换的工程发布的环境将是讨论的内容。 在src/main/resources新建dev和test环境的properties a. application_dev.properties b. application_test.properties 在application.properties中配置选择环境 启动工程 开发环境8081端口 测试环境8080 启动两个工程 两个工程分别启动在8080端口和8081端口。

SpringBoot学习(一)——Spring Initializr

前言 因为毕业在前,困于论文许久,已经停更了太长时间。疫情期间,论文已完成七八,六七月份也要入职工作了。之前的Java基础也丢的差不多了,现在准备重新捡起来开始学习。之前忘得差不多了,重新开始时各种坑。那就大家一起一步步来,今天先是简单的springboot开始一个web工程。 配置环境 环境是商业版IntelliJ IDEA 2018.3.5、spring 2.2.5.RELEASE、maven 3.6.0 工程初始化 商业版的IDEA可以直接在New Project,社区版的IDEA需要在spring官网Spring Initialzr下载压缩包解压开始。推荐使用商业版的IDEA,功能比较全。 工程打开后注意看一下是不是自己配置的maven工程 到现在已经完成springboot工程的初始化了,这边遇到的几个坑,springbootApplication的注解没法引入,这边可能是maven的版本过高,自己的3.6.3不行,换成3.6.0就可以使用了。 测试 添加@RestController使成为Controller使用@RequestMapping路由地址 3. 启动工程 4. IDEA的Terminal测试或者浏览器测试 通过观看Terminal或者浏览器可以发现工程成功了。

单链表之尾插法

1、前言: 尾插法,借助尾指针r,相当于媒婆,将原节点与新增节点P相连接,相比于头插法的好处是输入与输出顺序一致,如输入12345,输出也是12345 2、实现代码: #include<stdio.h> #include <stdlib.h> //define a struct //定义一个结构体,也就是节点 typedef struct Node { int data; // 存储链表数据 struct Node *next; // 存储结点的地址 }LNode,*LinkList; //链表尾插法 LNode* List_TailInsert(LNode *L,int a[],int n){ //尾插法 LNode* rear; L = new LNode; rear = L; for(int i=0;i<n;i++){ LNode* p= new LNode; p->data = a[i]; rear->next = p; rear = rear->next; } rear->next = NULL; return L->next; } //主函数,给链表赋值并打印出链表 int main(){ int arr[] = {1,2,3,4,5}; int n = 5; LNode *L = NULL; L = List_TailInsert(L,arr,n); while(L!

vue的生命周期

生命周期是什么 Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、销毁等一系列过程,我们称这是Vue的生命周期。 各个生命周期的作用 生命周期描述beforeCreate组件实例被创建之初,组件的属性生效之前created组件实例已经完全创建,属性也绑定,但真实dom还没有生成,$el还不可用beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用mountedel 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子beforeUpdate组件数据更新之前调用,发生在虚拟 DOM 打补丁之前update组件数据更新之后activatedkeep-alive专属,组件被激活时调用deactivatedkeep-alive专属,组件被销毁时调用beforeDestory组件销毁前调用destoryed组件销毁后调用 生命周期示意图

什么是DrawCall?如何减少DrawCall?

1.什么是DrawCall CPU调用图像编程接口。 在Shader渲染流水线的应用阶段,当CPU准备好场景数据,设置好渲染状态,就会调用DrawCall命令,开启一个渲染过程 2.为什么DrawCall多了会影响帧率 CPU每次调用DrawCall,都需要向GPU发送许多数据、状态,在发送前CPU需要从硬盘读取到显存的数据、设置的渲染状态以及调用DrawCall命令操作。一旦CPU执行完应用阶段,GPU即开始执行本次渲染。GPU渲染的速度比CPU提交命令的速度快的多。所以性能就会被CPU的提交速度所影响,如果DrawCall数量过多,CPU就会在提交命令上花费大量时间 3.如何减少DrawCall 批处理:我们可以把众多小的DrawCall合并成一个DrawCall,减少CPU提交DrawCall次数和时间,但并不是所有的情况都能合并。但是合并网格时也会比较消耗时间,因此批处理比较适合静态的网格,项目中Static被选中的物体 合并需要注意: 避免使用大量小的网格,若不可避免的话,可以考虑合并 避免使用过多的材质,相同的材质会方便我们合并

.git 文件过大 - 减小 .git 文件体积

综述 最近发现github上项目.git文件已经达到了2个G,整理了减小.git文件的方法。 .git文件是什么 一个管理git仓库的文件夹,这里包含所有git操作所需要的东西 方法 简单有效,减小体积 运行 gc ,生成 pack 文件(后面的 --prune=now 表示对之前的所有提交做修剪,有的时候仅仅 gc 一下.git 文件就会小很多) git gc --prune=now 克隆时只克隆一层 git clone --depth=1 使用git-lfs管理文件 项目中有大量的图片文件,音频文件,二进制文件时,推荐使用第三方扩展插件git-lfs。 它将你所标记的大文件保存至另外的仓库,而在主仓库仅保留其轻量级指针 why? 二进制内容比较难压缩, 会导致整个仓库占用的空间飞速增长. 没多久你可能就会发现,10M的文件,100M的.git文件。也就是不能版本比较。 Getting Started 安装完成后在git bash中运行如下指令 git lfs install 添加你要管理的文件 git lfs track "*.png" git lfs track "*.jpg" git lfs track "*.mp3" git lfs track "*.pyc" 添加.gitattributes 该文件保存了文件的追踪记录 git add .gitattributes 愉快的使用 进行完上述处理,后面就和正常git一样了。不会再有多余的步骤,正常add,commit,push,pull,clone即可 git add file.psd git commit -m "Add design file"

数据中台对企业意义和作用有哪些

随着数据浪潮席卷全球,数数据中台应运而生。众所周知,数据中台的主要功能是统一标准和口径后对数据进行存储和处理,使企业能够提供更高效的服务。总之,数据中台的目标是节约企业成本,实现精细化运营。那么数据中台对企业到底有哪些具体意义和作用呢?下面我们来具体看一下。 1、了解客户的观念和行为 在以客户为中心的时代,客户的观念和行为正在从根本上改变企业的经营方式以及企业与客户的互动方式。数据中台建设的核心目标就是以客户为中心的持续规模化创新,而数据中台的出现,将会极大提升数据的应用能力,将海量数据转化为高质量数据资产,为企业提供更深层的客户洞察,从而为客户提供更具个性化和智能化的产品和服务。譬如,数据中台能够汇聚全渠道的数据,在标签管理、营销圈人、效果分析等应用上实现全域的闭环,优化对客户全生命周期的理解。此外,以数据中台为基础,通过数据化运营提升客户留存、复购和忠诚度,也得到诸多企业的认可。 2、为商业模式的创新提供数据基础 只有依托数据和算法,将由海量数据提炼的洞察转化为行动,才能推动大规模的商业创新。数据中台在通过算法将洞察直接转化为行动、实现大规模商业创新方面的能力,令人瞩目。另一方面,数据无法被业务用起来的一个原因是数据没办法变得可阅读、易理解。信息技术人员不够懂业务,而业务人员不够懂数据,导致数据应用到业务变得很困难,数据中台需要考虑将信息技术人员与业务人员之间的障碍打破,信息技术人员将数据变成业务人员可阅读、易理解的内容,业务人员看到内容后能够很快结合到业务中去,这样才能更好地支撑商业模式的创新。此外,数据中台提供标准的数据访问能力,简化集成复杂性、促进互操作性等特性也非常受企业CIO们的青睐。同时,在快速构建服务能力、加快商业创新、提升业务适配等方面,数据中台也将会发挥重要的作用。 3、打破数据孤岛 面对纷繁复杂而又分散割裂的海量数据,数据中台的突出作用和意义在于能充分利用内外部数据,打破数据孤岛的现状,打造持续增值的数据资产,在此基础上,能够降低使用数据服务的门槛,繁荣数据服务的生态,实现数据“越用越多”的价值闭环,牢牢抓住客户,确保竞争优势。这些服务跟企业的业务有较强的关联性,是这个企业独有的且能复用的,它是企业业务和数据的沉淀,其不仅能降低重复建设、减少烟囱式协作的成本,也是差异化竞争优势的所在。 数据中台的意义和作用是将数据作为生产资料转化为数据生产力。在全球数据化时代,企业只有了解用户,在数据支撑的条件下不断创新,打破数据孤岛,才能在日益激烈的竞争中长期保持优势。

下载文件plus.downloader.createDownload

function download(){ console.log('开始下载') var url = 'http://soutugo.com/Upload/Images/2020/3/12_s/1a7f9e535f898fa071c65e82967d1cc.JPG'; //文件名称可以在上传时进行保存,下载时取出,当文件名称中存在单双引号时,要做好处理,否则会报错 var name = 'z.jpg'; var dtask = plus.downloader.createDownload(url,{ filename:"_downloads/"+name //利用保存路径,实现下载文件的重命名 },function(d,status){ //d为下载的文件对象 if(status==200){ //下载成功,d.filename是文件在保存在本地的相对路径,使用下面的API可转为平台绝对路径 var fileSaveUrl = plus.io.convertLocalFileSystemURL(d.filename); console.log(fileSaveUrl) //进行DOM操作 $("#downloadImg").attr('src',fileSaveUrl); // plus.runtime.openFile(d.filename); //选择软件打开文件 }else{ //下载失败 plus.downloader.clear(); //清除下载任务 } }) dtask.start();//执行下载 }

解决部分手机读取obb失败的问题

最近发现,有很小一部分海外的玩家在谷歌商店下载游戏之后,进游戏黑屏。从bugly上面查看报错日志,发现是读取obb文件失败了。谷歌商店规定超过100m的apk,需要分离obb上传。所以这种情况只会出现在谷歌商店的游戏包里面。 我的项目里面读取obb是分成2种情况的,第一种,是unity本身的api读取,比如Resources.Load()方法。另一种,是通过java原始方法,找到obb文件的路径,然后通过getInputStream方法,把obb文件当作是zip包一样读取。 经过多方面的排除,发现是某些特定的机型,在READ_EXTERNAL_STORAGE(读取外部存储)的权限禁止的情况下,会出现一个外部存储没挂载的情况,从Environment.getExternalStorageState()方法返回了"unmounted"。 在这种情况下,getObbDir()得到的路径会访问不了,所以导致了obb文件加载不到。很神奇的是,如果不用obb,单纯用unity本身的Application.persistentDataPath,获取的路径是可操作的,这个路径按正常的理解,是在data/storage/emulated/0/Android/data/com.xxx.xxx/files下,而obb的路径一般是在data/storage/emulated/0/Android/obb/com.xxx.xxx下,难道是Android/data/不需要权限,而Android/obb/需要权限? 带着这个疑问,我尝试着把Application.persistentDataPath在unity里面用OnGUI显示出来,然后分别打开和禁用READ_EXTERNAL_STORAGE权限。终于发现了问题的所在。 当有读权限的时候,应用默认访问的路径是data/storage/emulated/0/Android/文件夹 当读写权限被禁止的时候,storage目录被禁止访问,就是所谓的没有挂载,所以会分配了另外一个目录作为程序的默认访问目录:data/user/0/ 其中0是用户序号,据说安卓6.0之后支持多用户,所以有这个文件夹。 Unity的api对obb读取方式应该是独立于正常资源的,persistentDataPath可以正常的获取到路径,但obb的路径估计还是通过getObbDir之类的方法得到的,所以导致了路径不能访问,加载obb失败了。 我们一直讨论的都是某部分特殊的手机,正常的手机不会这样,正常手机在禁用了READ_EXTERNAL_STORAGE权限之后,还是能正常访问data/storage/emulated/0/Android/文件夹的,Environment.getExternalStorageState()获取也是"mounted"的。然后,这种问题当然只会出现在安卓6.0及以上的手机,因为6.0以下的手机不存在动态申请权限的操作。 于是尝试获取权限去解决这个问题。正常的思路很简单,只需要在游戏启动的时候,判断一下是否拥有这个权限,如果没有权限就弹出动态权限申请的弹窗,让用户同意授权就行了。 然而实际操作中,发现这部分的手机,在设置里面的权限授权状态如果是禁止的,那么他就根本不会弹出授权窗口,直接就返回了拒绝。这个情况,我个人的猜测是,安卓6.0以后的系统,对于权限一般会有允许,询问,禁止三种,然后在禁止的时候,一般会有个小选项,“禁止后不再提示”。但在出问题的手机系统里面,实际上是没有询问这种状态的,如果在设置里面禁止了,等同的效果是禁止后不再提示。 所以,我们还是不能通过权限弹窗去解决这个问题。我们可以帮助玩家跳转到手机设置面板去,让玩家手动去修改设置。跳转的方法是: Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse(“package:” + getPackageName())); startActivityForResult(myAppSettings, REQUEST_APP_SETTINGS); 但这种操作比较的不友好,玩家也不一定知道怎样操作。 最终我们想达到的目的是让伤害降低到最小,让大部分正常的玩家还是可以通过权限弹窗去授权权限,让小部分不会弹窗的用户,跳转去手机设置面板。于是不能通过权限去直接判断是否需要弹窗。幸好之前我们在判断挂载方式的时候,发现了这种手机的特点是如果禁止读取外部存储权限时,挂载方式是"unmounted"的,所以我们可以通过挂载方式,先判断一下。如果发现了"unmounted"的,就先提示玩家去手动设置授权。

c#Winform主窗体和子窗体之间的传递

一、先将主窗体FrmMain和子窗体FrmUser关联起来。 一、主窗体全部代码 public partial class FrmMain : Form { FrmUser mFrmUser = new FrmUser(); FrmPro mFrmPro = new FrmPro(); private static FrmMain frmMain; public FrmMain() { InitializeComponent(); frmMain = this;//初始化主窗体 } /// <summary> /// 子窗体调用该方法后就可以调用主窗体的ShowMessage(string txt)方法,将信息显示是主窗体的label中 /// </summary> /// <returns></returns> public static FrmMain Instance() { if(frmMain == null) { return new FrmMain(); } return frmMain; } /// <summary> /// 用户管理按钮的点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnUserPage_Click(object sender, EventArgs e) { pnlMain.

Maven项目中出现红色波浪线的解决过程

一、问题分类 对于Maven项目出现红色波浪线可以首先对报错情况进行分析,我遇到的两种表现形式(还有其他的形式,请多多指教): 形式一:所用文件均出现红色波浪线(此问题可能是配置问题) 形式二:maven项目 Plugins Dependencies中出现红色波浪线(此问题可能是jar包丢失导致) 二、配置检查 (1)检查IDEA的maven配置 File-settings-Build ,Execution,Deployment-Build Tools-Maven检查maven软件、配置文件、本地仓库配置是否正确。 (2)如果settings中maven的配置正确,检查项目的maven配置 1)Run-Edit Configurations进入Run/Debug Configurations界面 2)Run/Debug Configurations界面选择Templates-JSR45 Compatible Server-Maven 检查maven配置是否正确。 3)如果项目的maven配置也正常,检查IDEA的jdk是否正确 File-Project Structure弹框中选择Project Settings-Project ,检查jdk的配置。 4)如果进行上面检查仍存在红色波浪线可查看jar包是否丢失(操作详见下文)。 三、丢失jar包 (1)快捷导入 1)快捷键Ctrl+Shift+Alt+s(或者File-Project Structure)选择Project Setting中的Libraries,删除之前产生的target包; 2)点击屏幕右侧的Maven Projects;找到Lifecycle 点击install; 3)完成后,Maven Project的刷新按钮即可。 (2)手动导入 在解决问题的过程中,如出现存在问题的jar包比较少,或者快捷导入后仍存在如下插件未安装jar包,可选择手动补充 1)手动导入jar,首先找到文件所在的目录:Maven的本地仓库目录\org\apache\maven\plugins,里面包含安装的所有plugins: 2)结合界面提示,找到报错的plugins文件; 3)打开官网Maven Repository:https://mvnrepository.com/可搜索想要找的plugin。 进入相应plugin页面下 选择相应的版本,下载文件 4)将下载的jar放入相应plugin文件夹中,刷新屏幕右侧maven,plugins红色波浪线即可消失。

C 数组逆序输出

编写程序对固定内容的数组进行逆序输出,第一个值和最后一个值的位置互换。 效果 完整代码 #include<stdio.h> #define N 10 int main() { int a[N]={10,100,20,43,54,15,6,77,82,91}; int i,t; printf("原始数组是:\n"); for(i=0;i<N;i++) printf("%d ",a[i]); for(i=0;i<N/2;i++) { t=a[i]; a[i]=a[N-1-i]; a[N-1-i]=t; } printf("\n排序后的数组:\n"); for(i=0;i<N;i++) printf("%d ",a[i]); printf("\n"); return 0; }

数通HCIE心路历程

数通HCIE心路历程 2019年12月9号,对于我来说注定是意义非凡的一天。那一天我的手机收到了来自华为的邮件,上面写着“恭喜您通过了2019年12月5日的HCIE-R&S认证考试,然后我马上打开看到了华为的logo成绩单,当我看到上面标注着笔试通过、实验考试通过、面试通过以及最终成绩写着通过的时候,我的眼眶突然间就湿润了,我明白考取HCIE的梦此刻实现了,自己为此所做的一切努力都是多么的值得。 时间回到大二的上学期末,当时的我作为一名已经读到大二的学生几乎没有属于自己长远规划的目标,那时候的我也只是考取了国家软考网络工程师,每一天毫无目的的学习生活让我的内心浮现出一种荒废感。这样的日子我坐不住了,我自己想着我不能再这样子下去了。有一天我们的网络工程专业的专业课老师来宿舍查看我们的情况,在他准备离开的时候我就找到了他,我把自己内心的想法都给他说明了。第二天,我的专业课老师找到了我,建议深处迷茫的我考取HCIE证书,那时候我的内心是激动的,说明我在老师的心中有这个能力去考取HCIE证书,最后他推荐我周末的时候去他的实验室上课。从那时候起我就没有了周末,每到周六周日我就要早上7点30分起床,洗漱完毕去吃个早餐就急匆匆的赶去地铁站搭地铁去实验室上课。那个时候老师在实验室讲课正好是路由交换的HCIA课程,就这样,我的“HCIE之旅”开始了。 当我准备好了要考取路由交换的HCIE证书后,我开始着手复习老师提供的一些学习资料,随后开始预约了HCIE的笔试考试,时间是1月20号。由于当时正值学校期末考试周,没有什么时间复习笔试的内容,一直是考完学校的考试之后才开始能不断的进行复习笔试考试,笔试考纲考的不算难,但是涉及的范围还是挺广的,比如二层的技术和MPLS VPN占比还是挺多的,占比最多的还是IPV4/V6 Unicast这些技术。因为自己在学校以及在实验室上课学习过一些简单的技术了,而且之前自己比较不熟悉的技术也有去看过,在距离笔试考试大概前三周我自己每一天都通过看些学习视频以及看一些学习资料去巩固笔试的大纲内容知识点。最后,笔试比较顺利,我成功的在2019年1月20日通过了HCIE笔试考试。 过完春节后,大二下学期就开学了,本以为可以尽快的投入到实验考试的准备当中,但是由于新学期的课程不断增多,自己也需要忙很多事情,在加上HCIE路由交换方向3.0新版本准备要发布了,也就是说准备要改版了,我担心3.0新版本出来后新增以及修改的内容会让自己猝不及防,因此有一段时间自己并没有针对性的去复习实验考试的内容,直到3.0版本真正的发布后,我马上开始进入了实验考试的复习。后来没多久就放暑假了,那个暑假跟父母说了自己假期不回家,也就是那一次是我第一次学生生涯暑假两个月没有回家。那个暑假我每天早上7点半开始出发坐地铁去到实验室敲实验,中午困了就直接在实验室倚着板凳就休息一会,然后晚上8、9点才回到学校,这样的日子持续了2个多月的假期。现在想起来真的挺累的,但是那时候觉得自己的暑假过得比以往更有意义。别的不多说了,下面说说我备考实验遇到的各种困难。华为的LAB实验考试才是真正动真格了,实验考试分为上下午考试,上午考的是TS和TAC,下午考的是LAB。TS就是我们说的排错题,考试的时候会有10道题目让我们去排错,考前复习准备工作就是多练、多想,因为每一题的错点都不难,只要自己能理解这道题的理论,同时考试的时候细心,那么就不会感觉太难。接下来TAC就是诊断题,TAC还是要靠自己多总结的,拿到一道题目如何解决,自己的思路要非常清晰,而且要求自己在考前就已经很好的准备了针对每一道TAC诊断题的方法,这很重要。 最后就是下午的LAB题了,LAB题才是实验考试中的核心,所以一定要准备非常充分。我在LAB题中遇到得问题就挺多的,首先前面的二层实验题目自己敲得没问题,同时自己也能去理解题目的套路以及相关的理论知识,接下来到三层IGP的题目才是让我一开始很头疼的地方,那就是OSPF和ISIS的双点双向引入这个相关理论知识我当时掌握得并不是很好,每一次敲完总会发现路由不正常,要么就是路由优先级不对,要么就是OSPF路由不活跃导致路由不放入路由表,之后通过问老师学习相关理论知识以及自己反复的敲命令,自己也理解了华为打4次TAG的原因,也理解了OSPF为什么设计出优先级的值为10和外部优先级的值为150,我的第一道难题也算是解决了。在后面的MPLS VPN中采用的是Option C方案,Option C又分为方案一和方案二,这个MPLS VPN也是让我非常的头痛了,最可怕的是敲完MPLS VPN发现问题进行排除故障的时候发现是因为前面敲的IGP协议有错误而导致的MPLS VPN出现问题,这是让我不能容忍的,因为如果我在考场上敲到MPLS VPN出现问题然后去找原因的时候是因为前面的IGP协议没通,这样将会导致我回头重新检查,在时间上我就无法去掌控。这一系列的原因也反映出我太粗心,急于求快,而忽略了在考场上敲实验是尽量快并且求稳的情况。后来我每天敲实验出现的问题我自己当天就会去思考、总结,考实验一定要多想实验拓扑的每一个步骤应该如何去做,我就是每一天积累相应的知识点然后按自己的理解去敲实验,因为这样才可以在考场上临危不乱,发挥自如。大概是复习了2个多月,自己感觉可以去考试了,然后就约了9月2日的实验考试,考点是深圳。 依稀还记得那天坐高铁到深圳是下着小雨,到了深圳找好酒店安置好后就拿出笔记本电脑重新完完整整的敲了一次LAB实验。考前一晚我很晚才睡着,脑子里想的都是第二天的考试,我想这就是我每次面临大型考试前都会有的一种紧张感吧!第二天上午考TS和TAC后,赶紧去吃了饭然后休息了一会马上又投入到下午的LAB实验考试当中,当敲完实验提交拓扑配置走出考场的时候,这一次实验考试算是结束了。回酒店的路上自己还是会后悔上午的TS没有认真检查过几遍,LAB没有花更多时间去验证几次,想归想,但考试已经结束了,已经不能再去改变任何事情,我只能好好的调整自己的心态,然后静静等待华为的邮件通知。 9月9号凌晨华为的邮件来了,我顺利的通过了9月2日的实验考试。收到邮件通知的时候自己很激动,毕竟这是自己暑假两个多月努力的成果,但是我很快就冷静下来,因为我知道考取HCIE证书的最后一关面试即将来临,这是HCIE考试里最难的一个关卡,我还没有真正的完成考取HCIE证书的任务,所以我不能高兴太早。 很快,大三新学期开学了,我也是一名大三的学生了,自己感觉时间过得真快。我也没来的及多想,看了一下大三的课程表发现有好多课程,每一天都有课,此时我内心想的是我如何去准备HCIE面试考试,同时还要兼顾到学校的课程,实验考试成绩出来后留给我的时间最晚只有三个月。进入复习前,我花了几天时间去思考我应该如何复习面试,自己写了一个计划表,然后我自己都对自己没有了信心,感觉有好多的内容不懂,好多内容理解的不够深,但是好在我的内心还是足够强大,我心里想着这几个月我一定能复习完所有知识点,没有什么可以难倒我的。在学校每天都需要上课,所以我只能按着我的计划进行复习,在没有课的时候就背着书包带着笔记本电脑和资料去图书馆备考,在图书馆复习会让我有学习的氛围,这样也能提高我的学习效率。面试考试需要复习的范围实在太广,知识点内容包括二层技术、路由技术、组播、IPV6、QOS等等,很多知识点自己复习的时候一定要逐一分类进行复习,在后阶段多去结合各个知识点进行对比,这样是最容易掌握知识的方法,通过对比各个技术会发现有相同点也有不同点甚至还会有相似之处。我自己会根据面试考试一共有三道题目进行针对性复习,其中有一道项目题对于我来说是比较困难的,因为我是学生的缘故,对于项目题的知识掌握程度自然不会比已经工作并且有项目经历的人好,我只能多听老师讲解以及用自己的理论知识去解析关于项目类的题目,知识掌握越多之后其实项目题还是可以凭自己理论知识去掌握的,但是自己要多查资料,多问老师,多总结才是最重要的,剩下两道理论题那就需要自己多结合实验和理论去记忆。面试注重的是基础,有时候面试挂了就是因为忽略了基础的理论知识,所以导致面试不通过。面试的知识点实在太广,我自己复习到后面有时候就会忘记了前面复习的知识点,或者说前面的知识点在我的记忆中会变的非常模糊,自己去表述出来的时候经常会结巴,这样的情况在真正面试的时候容易被考官打断,考官很明显就知道你对知识掌握不够。 针对于复习后面知识点忘记前面知识点的情况我自己也是认真的思考过,因为面试的内容太多,忘记是正常现象,最后我用了一个思维导图软件去记忆相关的知识点发现效果还是挺明显的,无聊的时候打开电脑看看协议导图,这让我对知识点的记忆变得更加的深刻。除了我会用手写记录笔记之外,我还会用电脑的有道云笔记去记录一些笔记,用电脑去记录笔记会比用手写记录笔记速度上快很多,也会省出更多的时间复习,但是电脑上做笔记一定要多看,这样才会对知识点记忆得更深刻。除了要针对性的去复习知识点外,自己还要多看学习视频,从最基础HCIA视频看起,不懂的就问老师,或者自己查相应的资料、查看PPT、查看PDF文档以及华为文档,华为文档里的东西都是“宝”,对知识点的解释至少是最可靠的,自己一定要有这种自学的能力。备考那段时间,不管去图书馆路上还是吃饭或者是睡觉的时候,自己脑子里想的都是今天复习了什么内容,有什么知识点还不够熟悉的,那么当我开启电脑进入学习状态的时候我都会第一时间去看这个知识点以及做相关的模拟实验查看实验现象。面试最重要的复习工作就是找老师进行模拟面试了,这是模拟真实的面试考试场景,自己多进行模拟面试是非常重要的,首先这样可以训练自己对相关技术知识点的表达能力,还能发现自己面试时对于时间的把控度是否合理。还有一点就是在自己复习的时候多对着电脑进行相关知识点的解析,要从自己的口中表述出来,就算没有人和你面对面进行模拟面试训练,一个人的时候也可以对着电脑进行模拟训练,这些都是模拟面试的方式。 时间很快,我预约了12月5日的面试,考点还是在深圳。考前一晚在酒店里我也是很晚才能睡着,这与我考实验的时候一样,也许是习惯了这种考前的状态吧。这一次是我第二次来到深圳的华为基地,似乎没有了第一次来到这里考实验考试时的紧张感。那天我是早上10点钟开始面试,排在我前面的有一位同学是9点钟开始面试,我在考场外等的一个小时里来回的在走廊走来走去,显得有些坐立不安。终于轮到我面试了,工作人员带我进到一间办公室,桌子上只有一台笔记本电脑和一个麦克风耳机,这些都是和考官交流的工具,当工作人员关上办公室门口的时候,我就知道现在我要开始面试了。我选择好自己的题目顺序,简单的跟考官进行自我介绍后,我开始了答题。第一大题主要考各个协议在IPV6中有什么修订和第二大题BGP的理论知识,我讲这两道题的时候自我感觉良好,答题的过程中没有被考官打断。电脑上面有画图软件和记事本文档可以辅助答题,如果需要的话记得多使用它们去解析题目,这样考官可以从视觉上看到以及从听觉上听到你对题目的一个分析流程,这样考官才会对你有好印象。最后还剩15分钟左右我大概讲了一下项目题大型割接,我讲的过程中考官也没有打断我。最终我把全部题目答完了,考官最后总结跟我说了我的基础还不错,但是有一些实验要多回去多练多分析,有一题简单的追问没有答好,回去要多看,跟考官道别后,面试考试结束了。走出考场的那一刻,我感觉整个人解放了,考官说我基础不错我很高兴,起码我得到考官了认可。最后,我顺利的通过了数通HCIE考试,太多的艰辛也许只有收到成绩单的那一刻才懂得这一切多么来之不易,看到成绩单时眼眶泛泪却忍着没有流下来,这大半年里忙着学校的课程同时还要忙着复习面试,有时候会想自己为什么要这么累,但是我从未想过要放弃,也许这就是HCIE的魅力所在吧! 写了这么多,更多的是感恩。很幸运在大学生活里遇到了我的网络工程专业课老师,如果没有他指引我或许我就不会下定决心考取HCIE证书,也感谢在实验室给我上课的老师,让我学习到更多的技术知识去备考考试,每一个周末在实验室上课都让我收获颇多;更要感谢的是我的父母,因为当初我在决定考取HCIE之前我怕我的家人不愿意让我考取HCIE证书,因为考取HCIE的钱是一笔不小的费用,同时我也知道考取HCIE并不是一件易事,万一考挂了几次,那又要多花很多钱。然而我是幸运的,父母文化虽然水平不高,但是他们知道读书是有用的,他们相信我、支持我,认为我有能力去做出自己的判断。没有他们一路上的支持,那么我想我在考取HCIE的路上会走的非常艰难;最后要感谢的是自己,依稀还记得备考HCIE的日子,感谢自己有这个毅力坚持下来了,感谢自己没有中途放弃,感谢每一天在图书馆奋斗、努力的自己 最后,引用许吉如在***节目上说过的一句话“每一个高光时刻它有多绚烂,这个高光时刻周围的阴影就可能有多寂寥”,以此来勉励正在备考HCIE的小伙伴们,让我们一起点亮IE的荣光,加油!

【processing笔记】

文章目录 [processing 官网链接](https://processing.org/)**rect()函数****ellipse()函数****fill()函数****stroke()函数****noStroke()函数****beginShape()****setup()函数****draw()函数****line()函数****strokeWeight()函数****alpha相关****变量的类型****鼠标交互****键盘交互****鼠标水平滑动改变小球颜色****使白色矩形重复平移****加载图片并显示****图片跟随鼠标移动****实现重影叠加效果。****贝塞尔曲线****贝塞尔曲线****音频播放****音频停止与回放****声音强度****声音交互****声音控制方块人的嘴巴动****播放多个音频文件****用麦克风录音存储为wav格式****数据映射****用for循环创造艺术图像****随机数****arrays数组****println相关****process标签页****用函数来输出一个渐变色图案****定时器****P3D渲染器****将当前变换矩阵嵌入和弹出矩阵堆栈。****绘制立方体****球体****定向光****环境光****自定义3D图形****加载视频****读取摄像头****调整摄像头影像的尺寸****获取颜色信息****读写像素点****视频输出像素点风格****像素块风格****视频替代摄像头画面****粒子系统****完成鼠标靠近粒子 颜色改变的效果****点击鼠标粒子都靠近鼠标点击位置****爆炸的像素****粒子连线****controlP5库 Gui Button****controlP5库 Gui Slider****在粒子连线中加入UI****绘制椭圆****noise随机数****利用sin()函数绘图** ** processing 官网链接 ** void setup() { } void draw() { } setup 是放置启动这个程序时用到的代码 draw是需要持续运行的代码 运行后出现的窗口默认是100X100像素 void setup() { size(800,600); } void draw() { } size(a,b);内输入两个数值代表像素点,是改变窗口大小的命令。 void setup() { size(800,600); } void draw() { background(255,255,255); } background(a,b,c);输入三个0到255代表红,绿,蓝RGB的数值,是窗口背景颜色的命令。 background(a);输入一个数字的时候,相当于重复三次这个数字。 如果不知道想要颜色的RGB具体的数值,在工具(Tools)颜色选择器(Color Selector)中找。 rect()函数 rect(a,b,c,d)绘制矩形命令;输入四个数值,第一个数值是从左到右X轴,第二个数值从上到下Y轴,第三个数值矩形的宽(Width),第四个数值矩形的高(Height)。 ellipse()函数 ellipse(a,b,c,d);在屏幕上绘制一个椭圆(椭圆形)。宽度和高度相等的椭圆是一个圆。默认情况下,前两个参数设置位置,第三个和第四个参数设置形状的宽度和高度。 fill()函数 fill();设置用于填充形状的颜色。例如,如果运行fill(204,102,0),则所有后续形状都将用橙色填充。 stroke()函数 stroke(a,b,c);设置用于在形状周围绘制线条和边框的颜色。根据当前的colorMode(),可以根据RGB或HSB颜色指定该颜色。默认颜色空间是RGB,每个值的范围都在0到255之间. 红色的矩形在绿色的上面,因为程序按照顺序执行,红色矩形是最后绘制的所以会在绿色矩形之上。 background()放在绘制绿色矩形与红色矩形中间后,绿色矩形不显示是因为先绘制绿色矩形后background函数设置了白色背景将绿色矩形覆盖掉了。 noStroke()函数 noStroke();禁用绘制笔划(轮廓)。如果同时调用noStroke()和noFill(),则不会在屏幕上绘制任何内容。 beginShape() 使用beginShape()和endShape()函数可以创建更复杂的表单。beginShape()开始记录形状的顶点,endShape()停止记录。kind参数的值告诉它要从提供的顶点创建哪些形状的形状。如果未指定模式,则形状可以是任何不规则多边形。 beginShape()可用的参数是POINTS,LINES,TRIANGLES,TRIANGLE_FAN,TRIANGLE_STRIP,QUADS和QUAD_STRIP。调用beginShape()函数后,必须遵循一系列vertex()命令。要停止绘制形状,请调用endShape()。该顶点()具有两个参数的函数指定2D位置,具有三个参数的vertex()函数指定3D位置。每个形状都会用当前的笔触颜色勾勒出轮廓,并用填充颜色填充。 setup()函数 setup函数在运行后执行一次; draw()函数 draw函数永远循环,直到停止 line()函数 line(x1,y1,x2,y2)在屏幕上画一条线(两点之间的直接路径)。前两个值是第一个点的坐标,后两个值是第二个点的坐标。要为线条着色,请使用stroke()函数。无法填充线条,因此fill()函数不会影响线条的颜色。

阿里云配置DNS服务器

DNS 基本概念 一、hosts 文件 作用: 实现名字解析,主要为本地主机名、集群节点提供快速解析 数据库: 平面式结构,集中式数据库 二、域名服务 DNS 作用: 实现名字解析(例如将主机名解析为 IP) 命名空间 name space: 用于给互联网上的主机命名的一种机制 DNS 数据库 Datebase: 层次化的,分布式的数据库 权威名称服务器: 存储并提供某个区域的实际数据,例如 126.com 的 DNS 服务器,记录了 126.com 域中 所有主机的记录如: www.126.com. x.x.x.x ftp.126.com. y.y.y.y 权威名称服务器类型包括: Master: 主 DNS 服务器,包含原始区域的数据 Slave: 备份 DNS 服务器,通过(区域传输)从 Master 服务器获得区域数据的副本 非权威名称服务器: 不存储某个区域的实际数据,仅缓存 DNS 服务器,虽然可以提供查询,但查询的内 容不具有权威性 DNS 解析流程: 例如客户端解析 www.126.com 1.客户端查询自己的缓存(包含 hosts 中的记录),如果没有将查询发送/etc/resolv.conf 中的 DNS 服务器 2.如果本地 DNS 服务器对于请求的信息具有权威性,会将(权威答案)发送到客户端。 3. 否则(不具有权威性),如果 DNS 服务器在其缓存中有请求信息,则将(非权威答案)发送到客户端 4. 如果缓存中没有该查询信息,DNS 服务器将搜索权威 DNS 服务器以查找信息: a.

Web安全--OS命令注入

1. 原理和成因 程序员使用脚本语言开发过程中,脚本语言开发十分快速、简洁,但是也伴随着一些问题。比如说速度慢,或者无法接触系统底层,如果我们开发的应用,特别是企业级的一些应用需要去调用一些外部程序,当应用需要调用一些外部程序时就会用到一些系统命令的函数。 应用在调用这些函数执行系统命令的时候,如果将用户的输入作为系统命令的参数拼接到命令行中,在没有过滤用户的输入的情况下,就会造成命令执行漏洞。 2. 造成漏洞的原因 (1)用户输入作为拼接 (2)没有足够的过滤 3. 漏洞危害 (1)继承web服务器程序权限,去执行系统命令 (2)继承web服务器权限,读写文件 (3)反弹shell (4)控制整个网站 (5)控制整个服务器 4. 相关函数 (1)system() system()能够将字符串作为os命令执行,自带输出功能,测试代码如下: <?php if(isset($_GET['cmd'])){ $str=$_GET['cmd']; system($str); }else{ echo "test error" } ?> (2) exec() exec()函数能将字符串作为OS命令执行,需要输出执行结果,例子如下: <?php if(isset($_GET['cmd'])){ $str=$_GET['cmd']; print exec($str) } ?> exec()返回的结果是有限的,但是命令是能正常执行的 (3)shell_exec() <?php if(isset($_GET['cmd'])){ $str=$_GET['cmd']; print shell_exec($str) } ?> (4)passthru() <?php if(isset($_GET['cmd'])){ passthru($_GET['cmd']); } ?> (5) 反引号 ` 两个反引号内的字符串被被解析成os命令 <?php if(isset($_GET['cmd'])){ $str=$_GET['cmd']; print `$str` } ?> 5. 漏洞利用 OS命令注入漏洞,攻击者直接集成Web用户权限,在服务器上执行任意命令,危害特别大。以下命令均在windows系统下测试成功。 (1)查询系统文件

Beff安装与使用

有很多版本的kali都是自带安装了Beff的,但是不知道我的kali为啥就没自动安装,所以这里我手动进行安装 1.安装beef 打开终端,输入如下命令: aptt-get install beef-xss 2. 打开beef 上诉安装好以后,建议重启kali机器 重启好以后就能正常打开beef软件了,打开以后会让你设置密码,这里自己设置密码 3. 打开beef 输入上面的地址即可打开beef,帐号为beef,密码为刚刚你设置的密码。如果想要重新设置密码的话,就按如下步骤进行密码修改: cd /usr/share/beef-xss vim config.yaml 4. 进行xss注入 在下图标注的位置输入上面示例的脚本进行提交 5. 打开beef 再打开beef即可进行攻击哦 具体使用和攻击示例请查看链接(转载内容):https://www.freebuf.com/articles/web/175755.html

面试题06. 从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 思路 从头到尾将链表打印到数组中,返回反转后的结果即可。 # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def reversePrint(self, head: ListNode) -> List[int]: res = [] while head: res.append(head.val) head = head.next return res[::-1] 来源:力扣leetcode