关于学习笔记:前后端交互

<article class=“article fmt article-content”><h2>前后端交互</h2><h3>前端是什么?</h3><p>前端是指与用户间接交互的局部,通常是指 Web 开发中的前端局部,也称为客户端或用户界面。前端开发波及创立网站或应用程序的用户界面,包含网页的外观、布局、交互和性能。</p><p>简略来说就是:用户的可见界面,数据展现在页面上出现给用户。</p><h3>后端是什么?</h3><p>后端是指网站、应用程序或服务的背地局部,负责解决数据、逻辑和与数据库交互等工作。它包含服务器端技术、数据库和应用程序,确保零碎的稳定性、安全性和性能。</p><h3>前后端交互的组织架构</h3><p>前后端交互的组织架构通常是基于<strong>客户端-服务器模型</strong>,其中前端作为客户端,后端作为服务器端。这种模型通过 HTTP 协定或其余通信协议实现通信。</p><p>在典型的 Web 应用程序中,前端和后端通过 HTTP 申请和响应进行通信。前端发送申请给后端,后端解决申请并返回相应的数据或后果,而后前端依据返回的数据更新用户界面。这种交互模式使得前端和后端可能拆散开发、测试和保护,进步了零碎的灵活性和可维护性。</p><h3>前后端交互的流程</h3><p>前后端交互的流程通常波及以下步骤:</p><ol><li><p><strong>前端发送申请</strong>:</p><ul><li>用户在浏览器中输出网址或者与页面交互,触发前端发送申请的动作。</li><li>前端能够应用HTTP申请向后端发送申请,申请的内容能够包含获取数据、提交表单、执行操作等。</li></ul></li><li><p><strong>后端接管申请</strong>:</p><ul><li>后端服务器接管到前端发送的申请。</li><li>后端服务器依据申请的内容,确定须要执行的操作或提供的服务。</li></ul></li><li><p><strong>后端解决申请</strong>:</p><ul><li>后端依据申请的类型和内容,执行相应的业务逻辑解决。</li><li>这可能包含拜访数据库、调用其余服务、计算数据等。</li></ul></li><li><p><strong>后端生成响应</strong>:</p><ul><li>后端解决完申请后,生成相应的数据或后果。</li><li>这些数据能够是动静生成的HTML、JSON、XML等格局的数据,用于更新前端页面或提供给前端应用程序。</li></ul></li><li><p><strong>后端发送响应</strong>:</p><ul><li>后端将生成的响应数据发送回前端。</li><li>通常,后端会应用HTTP响应来发送数据,包含响应状态码、头部信息以及响应体。</li></ul></li><li><p><strong>前端接管响应</strong>:</p><ul><li>前端浏览器或应用程序接管到后端发送的响应。</li><li>前端解析响应数据,依据须要更新页面内容、执行相应的操作等。</li></ul></li><li><p><strong>前端解决响应</strong>:</p><ul><li>前端依据接管到的响应数据进行解决,可能包含更新页面内容、显示提示信息、执行跳转等操作。</li></ul></li><li><p><strong>用户交互或页面更新</strong>:</p><ul><li>用户在前端页面上进行交互,或者依据前端的更新内容进行操作。</li><li>页面依据用户的操作或后端响应的更新进行相应的更新和交互。</li></ul></li></ol><p>这些步骤形成了前后端交互的根本流程。在理论利用中,依据具体的业务需要和技术架构,可能会有更多的细节和复杂性。</p><h3>传输协定</h3><p>在前后端交互的过程中,罕用的传输协定次要是 HTTP(Hypertext Transfer Protocol)和其平安版本HTTPS(HTTP Secure)。这两种协定是<strong>应用层协定</strong>,<strong>用于在客户端和服务器之间传输数据</strong>。</p><ul><li><strong>HTTP</strong>:客户端发送申请给服务器,服务器解决申请并返回相应的数据或后果。HTTP是基于文本的协定,通常应用TCP作为传输层协定,应用端口号80。</li><li><strong>HTTPS</strong>:HTTPS 是 HTTP 的平安版本,它通过应用 SSL(Secure Sockets Layer)或 TLS(Transport Layer Security)协定来加密数据,从而爱护数据的安全性和完整性。HTTPS 应用的端口号为443。</li></ul><p>在前后端交互中,通常应用 HTTP 申请来获取数据、提交表单、执行操作等。HTTPS 则用于在不平安的网络中加密数据传输,以避免数据被窃取或篡改。HTTPS 的应用能够通过在服务器上安装 SSL/TLS 证书来实现,这样就能够建设平安的加密通道,确保数据在传输过程中的安全性。</p><p><strong>拓展:</strong></p><p><strong>SSL</strong>(Secure Sockets Layer)和 <strong>TLS</strong>(Transport Layer Security)都是<strong>加密通信协议</strong>,用于爱护网络通信的安全性。TLS 实际上是 SSL 的继任者。</p><ul><li><p><strong>SSL(安全套接字层)</strong>:</p><ul><li>SSL 最后由网景公司开发,用于爱护 Web 通信的平安。</li><li>SSL 协定应用加密算法和身份验证来确保数据在客户端和服务器之间的传输平安。</li><li>SSL 协定有多个版本,然而因为安全漏洞和弱点,当初曾经被 TLS 协定所取代。</li></ul></li><li><p><strong>TLS(传输层平安)</strong>:</p><ul><li>TLS 是 SSL 的降级版本,旨在提供更强的安全性和性能。</li><li>TLS 协定继承了 SSL 的根本个性,但修复了 SSL 中存在的一些安全漏洞,并增加了新的性能和加密算法。</li><li>TLS 协定的最新版本是 TLS 1.3,它提供了更快的握手过程、更平安的加密算法和更好的性能。</li></ul></li></ul><p>TLS 协定和 SSL 协定都应用在应用层和传输层之间,它们次要用于爱护 Web 通信、电子邮件传输、VPN 连贯等。当客户端和服务器建设连贯时,它们应用 SSL/TLS 协定进行握手,并协商密钥替换算法、加密算法和其余平安参数。一旦握手胜利,客户端和服务器之间的通信就会通过加密通道进行,确保数据的安全性和完整性。SSL 和 TLS 协定的应用对于互联网通信的平安至关重要,尤其是在敏感信息的传输过程中。</p><h3>域名</h3><p>域名是互联网上用来辨认特定网络资源的名称。它是由一串字符组成的人类可读的标识符,用于代表互联网上的服务器或者网站。域名通常用于辨认特定的网络资源,比方网站、FTP服务器(提供文件存储和拜访服务的计算机)、电子邮件服务器等。</p><p>域名通常由两局部组成:</p><ol><li><strong>域名标签(Domain Label)</strong>:域名的每个局部被称为域名标签或子域名。在典型的域名中,这些标签之间用点号(.)分隔。例如,在域名 “example.com” 中,“example” 是一个子域名,“com” 是顶级域名(TLD)。</li><li><strong>顶级域名(Top-Level Domain, TLD)</strong>:顶级域名是域名体系结构中的最高级别域名。它位于域名的最初局部,用于示意域名的类别或国家/地区。常见的顶级域名包含 “.com”、".org"、".net"、".edu"、".gov" 等以及各国家/地区的顶级域名,如 “.cn”、".uk"、".jp" 等。</li></ol><p>域名的作用在于简化了互联网资源的拜访,因为人们更容易记住具备意义的域名而不是一长串数字组成的IP地址。域名零碎(DNS)将域名翻译成相应的IP地址,这样计算机能力找到正确的网络资源。</p><p>总之,域名在互联网上扮演着重要的角色,是连贯用户和网络资源之间的要害。通过域名,用户能够轻松地拜访网站、发送电子邮件和拜访其余网络服务。</p><h3>端⼝号</h3><p>端口号是一种逻辑标识,用于辨别计算机中不同应用程序或服务之间的通信端口。在计算机网络中,每个应用程序或服务都须要通过端口号来与其余应用程序或服务通信。</p><p>端口号的范畴是从0到65535,其中0到1023是为零碎保留的,用于一些常见的服务或协定,比方HTTP通常应用端口号80,HTTPS通常应用端口号443。其余的端口号则用于自定义的应用程序或服务。</p><p>一些常见的端口号和对应的服务包含:</p><ul><li>80:HTTP服务</li><li>443:HTTPS服务</li><li>21:FTP服务</li><li>22:SSH服务</li><li>25:SMTP服务(用于发送邮件)</li><li>110:POP3服务(用于接管邮件)</li><li>3306:MySQL数据库服务</li><li>5432:PostgreSQL数据库服务</li></ul><p>通过端口号,计算机能够将网络数据包调配给正确的应用程序或服务,从而实现不同应用程序之间的通信和合作。</p></article> ...

February 20, 2024 · 1 min · jiezi

关于学习笔记:吴恩达神经网络和深度学习Chapter3学习笔记

昨天那篇过了一天才审核通过,心愿当前能够略微快一点哈哈始终胆战心惊怕思否感觉我太小白了不给过。明天把第二周的根底作业实现了,难度不大。今天写选做作业。不出意外的话这周能够把神经网络和深度学习这门课刷完。 3.1~3.5这几节次要是解释计算和一些公式上的习惯标记,以及和向量相干的解释,因为太多数学公式懒得打,就不整顿了。 3.6~3.8 激活函数激活函数:深度学习笔记:如何了解激活函数?(附罕用激活函数)查了几篇文章,都提到了一个中央“激活函数将非线性个性引入到咱们的网络中”。 *问题是,为什么咱们不能在不激活输出信号的状况下实现此操作呢?如果咱们不使用激活函数的话,则输入信号将仅仅是一个简略的线性函数。线性函数一个一级多项式。现如今,线性方程是很容易解决的,然而它们的复杂性无限,并且从数据中学习简单函数映射的能力更小。一个没有激活函数的神经网络将只不过是一个线性回归模型(Linear regression Model)罢了,它功率无限,并且大多数状况下执行得并不好。咱们心愿咱们的神经网络不仅仅能够学习和计算线性函数,而且还要比这简单得多。同样是因为没有激活函数,咱们的神经网络将无奈学习和模仿其余简单类型的数据,例如图像、视频、音频、语音等。这就是为什么咱们要应用人工神经网络技术,诸如深度学习(Deep learning),来了解一些简单的事件,一些相互之间具备很多暗藏层的非线性问题,而这也能够帮忙咱们理解简单的数据。那么为什么咱们须要非线性函数?非线性函数是那些一级以上的函数,而且当绘制非线性函数时它们具备曲率。当初咱们须要一个能够学习和示意简直任何货色的神经网络模型,以及能够将输出映射到输入的任意简单函数。神经网络被认为是通用函数近似器(Universal Function Approximators)。这意味着他们能够计算和学习任何函数。简直咱们能够想到的任何过程都能够示意为神经网络中的函数计算。而这所有都归纳于这一点,咱们须要利用激活函数f(x),以便使网络更加弱小,减少它的能力,使它能够学习简单的事物,简单的表单数据,以及示意输入输出之间非线性的简单的任意函数映射。因而,应用非线性激活函数,咱们便可能从输入输出之间生成非线性映射。激活函数的另一个重要特色是:它应该是能够辨别的。咱们须要这样做,以便在网络中向后推动以计算绝对于权重的误差(失落)梯度时执行反向优化策略,而后相应地应用梯度降落或任何其余优化技术优化权重以缩小误差。*摘自什么是激活函数?它有什么作用?依据我集体的了解,激活函数位于两层之间,即上一层计算输入后,通过激活函数将output解决成别的状态,再作为input输出到下一层。为什么要用激活函数?如上文所摘,如果没有激活函数,咱们所失去的最终后果y,不过是输出x的线性组合而已。不过单纯线性激活函数适宜于回归模型,即输入后果不是0、1分类而是一个实数,例如对价格的预测。目前罕用的激活函数除了Chapter2中提到的sigmoid函数外,还有tanh、ReLU。Tanh函数能够看作sigmoid函数的变形:先平移,再拉伸。目标是将平均值从0.5调整到0,次要应用在暗藏层中。如上图所示,无论是tanh还是sigmoid函数,在达到肯定值后,函数的斜率会靠近于0,这会升高梯度降落算法的效率;因而引入了ReLU函数。 第三章拖得太久了,之前很多细节都遗记了……3.9及之后的大节次要是和数学无关,难度也不大,就不放上来了。这几天把反向流传和梯度降落再整一下,开始第四章。

May 4, 2023 · 1 min · jiezi

关于学习笔记:OneFlow学习笔记从OpExprInterpreter到OpKernel

撰文|月踏 更新|赵露阳 前文《OneFlow学习笔记:从Functor到OpExprInterpreter》讲了OpExprInterpreter的相干细节,再往下就是OneFlow中的虚拟机,它负责在eager模式下把指令(即op,在vm中称为指令)调度到具体的OpKernel上来执行。 1 Global简介先看一个非凡的类Global,定义在oneflow/core/common/global.h,这个类很简略,然而对于整个零碎来说很重要,次要的几个接口如下: template<typename T, typename Kind = void>class Global final { public: // 获取创立过的对象 static T* Get() { ... } // 创建对象 static void SetAllocated(T* val) { ... } template<typename... Args> static T* New(Args&&... args) { ... } // 开释对象 static void Delete() { ... } ...};这是一个能够依据指定程序来创立全局单例对象的类,次要用在零碎的初始化中,这样对于一些全局的对象在初始化的时候创立好,后续整个零碎的各个模块就都能够应用了。 2 零碎初始化过程再持续看零碎的初始化流程,首先在python/oneflow/__init__.py+217中能够找到上面这句话: __oneflow_global_unique_env = env_util.GetEnv()GetEnv()办法在python/oneflow/framework/env_util.py中定义,其返回一个EnvHolder的Python对象,此对象初始化时,通过self._env_cxt = create_env()创立了OneFlow运行时所须要的环境上下文: class EnvHolder(object): def __init__(self): if not HasAllMultiClientEnvVars(): SetDefaultMultiClientEnvVars() self._env_cxt = create_env() ...def create_env(): """create environment Returns: Env: [description] """ global default_env_proto assert len(default_env_proto.machine) > 0 CompleteEnvProto(default_env_proto) if default_env_proto.ctrl_bootstrap_conf.world_size > 1: check_non_localhost_proxy_and_print_warning() return c_api_util.GetEnvContext(default_env_proto)create_env()中,首先会通过CompleteEnvProto创立默认的env_proto对象,而后依据此env proto对象创立oneflow所须要的环境上下文env_ctx。 ...

April 28, 2022 · 5 min · jiezi

关于学习笔记:每日学习amdahl定律及其意义

什么是amdahl定律当咱们对系统的某个局部进行优化减速时,其对系统整体性能的影响取决于该局部的重要性和减速水平。 若零碎执行某应用程序须要工夫为$a_i$ 假如零碎某局部所需执行工夫与该工夫的比例为a,而该局部性能晋升比例为k。即该局部初始所需工夫为aTold,当初所需工夫为(aTau)/k。因而,总的执行工夫应为 该局部的零碎整体占比和优化晋升水平独特决定了优化成果

February 23, 2022 · 1 min · jiezi

关于学习笔记:Java

开发环境JDK:JAVA 编译环境JRE:JAVA 运行环境根本语法数据类型(四种八类型)整数型:byte, short, int, long;浮点型:float, double;字符型:char;布尔型:boolean.书写标准类名放弃首字母大写,包名放弃小写,办法名应用驼峰写法。 面向对象在 JAVA 中,万事万物都是对象。尽管如此,理论的代码编译中操作的的确对象的援用(reference)。 类也是对象对象援用是绝对于对象独立的存在,也就是说有一个对象利用,然而不须要一个对象与之对应。 Car carKey;以上创立的只是援用,而并非对象。如果想在代码之中应用这个援用时,会返回一个没有对象关联的异样。平安的做法是,在创建对象援用时把一个对象赋给它。此时咱们须要应用new办法。 new一个对象应用new进行对象的创立: Sheep sheep1 = new Sheep();Sheep sheep2 = new Sheep("codesheep", 18, 65.0f);通过new办法,通过调用类的无参或有参结构的办法来实例化了两个对象。 在创建对象的过程中,JVM解决了如下步骤 首先,new一个对象时,以Sheep sheep = new Sheep()为例,JVM会先来查看Sheep这个符号援用的类是否曾经被加载过,如果没有就要执行对应类的加载过程。在这个过程中,对象占用的内存就曾经定下来了。申明类型援用。Sheep sheep = new Sheep()中就申明了一个Sheep类型的援用sheep。依照第一步中布局的内存调配打算,JVM会在堆上给对象分配内存。初始化0值。例int的初始化0值就是0,对象化的初始化0值就是null。接下来JVM会进行对象头的设置,这外面就次要包含对象的运行时数据(比方Hash码、分代年龄、锁状态标记、锁指针、偏差线程ID、偏差工夫戳等)以及类型指针(JVM通过该类型指针来确定该对象是哪个类的实例);属性的显示初始化也好了解,比方定义一个类的时候,针对某个属性字段手动的赋值,如:private String name = "codesheep"; 就在这时候给初始化上;最初是调用类的构造方法来进行进行构造方法内形容的初始化动作。通过以上的步骤一个对象才得以诞生。 属性和办法类的一个最根本的因素就是属性和办法。 属性也被称为字段,是类的重要组成部分。属性能够使任意类型的对象,也能够是最根本的数据类型。 class A{ int a; Apple apple;}类中还应该包含办法,办法示意的是做某些事件的形式。办法其实就是函数,只不过Java习惯把函数成为办法,这种叫法也体现了面向对象的概念。 办法的根本形成包含: 办法名称;参数;返回值;办法体。e.g. public int getResult(){ // ... return 1;}其中getResult就是办法名,()示意承受的参数,return示意办法的返回值,{}中的为办法体。 构造方法在Java中,有一种非凡的办法被称为构造方法(或构造函数、结构器)。在Java中,通过提供这个结构器,来确保每个对象都被初始化。构造方法只能在对象创立期间调用一次,保障了对象初始化的进行。构造方法比拟非凡,它没有参数类型和返回值,它的名称要和类名称保持一致,并且构造方法能够有多个。 e.g. //一堆初始化办法的初始化类class Apple{ int sum; String color; public Apple(){} public Apple(int sum){} public Apple(String color){} public Apple(int sum, String color){}}//开始class createApple{ public static void main(String[] args){ Apple apple1 = new Apple(); Apple apple2 = new Apple(1); Apple apple3 = new Apple("red"); Apple apple4 = new Apple(2,"color"); }}以上,在Apple类中,定义了四个构造方法。其中,不加任何参数的构造方法被称为默认的构造方法,即: ...

December 22, 2021 · 8 min · jiezi

关于学习笔记:阿里p8私藏MyBatis笔记从入门到精通纵享源码细节

前言越来越多的企业曾经将MyBatis应用到了正式的生产环境,我认为风行的起因就在于绝大部分我的项目都是面向表构造编程的,把Java对象仅当成数据容器,查问和模型变更都设计在一张表上,所谓业务逻辑就是一堆增删改查的sql汇合,因而Mybatis用起来十分不便。 为什么要学MyBatis?除了我下面说的目前MyBatis在国内十分风行外,还有以下几点: ①学好MyBatis能很好地帮忙咱们解决数据层开发的问题; ②MyBatis源码中有很多设计模式和并发编程的技巧,学好源码对晋升编码能力有很大的帮忙; ③最初,Mybatis源码也是大厂面试的常常问的点。 基于上述情况,本次将给大家分享阿里p8私藏MyBatis笔记,帮忙大家由浅入深地学习MyBatis相干常识,纵享源码细节,让开发者不仅知其然,更知其所以然。 注:因为内容较多,本次将展现局部,如果看得不过瘾想更加深刻地理解本笔记彻底把握 本文分为两局部,然而我想反套路来一波,首先给大家展现一下源码,再展现MyBatis整体学习内容,不多bb,间接上了。![上传中...]()阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节A:精进MyBatis源码剖析 - 整体架构①整体架构 我的项目构造整体架构根底反对层外围解决层接口层 阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节B:精进MyBatis源码剖析 - 根底反对层①根底反对层 解析器模块反射模块异样模块数据源模块事务模块缓存模块类型模块IO模块日志模块注解模块Binding模块 阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节C:精进MyBatis源码剖析 - MyBatis初始化(一)之加载 mybatis-config.xml①MyBatis的初始化 ②初始化(一)之加载mybatis-config.xml SqlSessionFactoryBuilderXMLConfigBuilderConfiguration阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节D:精进MyBatis源码剖析 - MyBatis初始化(二)之加载 Mapper 接口与 XML 映射文件①MyBatis的初始化 ②初始化(二)之加载Mapper接口与映射文件 解析入口MapperAnnotationBuilderXMLMapperBuilderXMLStatementBuilderMapperBuilderAssistantRequestMappingResultMapMappedStatement阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节E:精进MyBatis源码剖析 - MyBatis初始化(三)之 SQL 初始化(上)①MyBatis的初始化 ②初始化(三)之SQL初始化(上) LanguageDriverXMLScriptBuilderNodeHandlerDynamicContextSqlNodeOgnlCache阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节F:精进MyBatis源码剖析 - MyBatis初始化(四)之 SQL 初始化(下)①MyBatis的初始化 ②初始化(四)之SQL初始化(下) SqlSourceBuilderParameterExpressionParameterMappingSqlSourceBoundSqlDefaultParameterHandler阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节G:精尽MyBatis源码剖析 - SQL执行过程(一)之 Executor①MyBatis的SQL执行过程 ②SQL执行过程(一)之Executor ExecutorBaseExecutorSimpleExecutorReuseExecutorBatchExecutor二级缓存Executor在哪被创立阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节H:精尽MyBatis源码剖析 - SQL执行过程(二)之 StatementHandler①MyBatis的SQL执行过程 ②SQL执行过程(二)之StatementHandler StatementHandlerRoutingStatementHandlerBaseStatementHandlerSimpleStatementHandlerPreparedStatementHandlerCallableStatementHandlerKeyGeneratorJdbc3KeyGeneratorSelectKeyGeneratorNoKeyGenerator阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节I:精尽MyBatis源码剖析 - SQL执行过程(三)之 ResultSetHandler①MyBatis的SQL执行过程 ②SQL执行过程(三)之ResultSetHandler ResultSetWrapperResultSetHandlerDefaultResultSetHandler阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节J:精尽MyBatis源码剖析 - SQL执行过程(四)之提早加载①MyBatis的SQL执行过程 ②SQL执行过程(四)之提早加载 ResultLoaderResultExtractorResultLoaderMapProxyFactoryJavassistProxyFactoryCglibProxyFactory阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节K:精尽MyBatis源码剖析 - SqlSession 会话与 SQL 执行入口①SqlSession会话与SQL执行入口 SqlSessionFactoryBuilderDefaultSqlSessionFactoryDefaultSqlSessionMapperMethod阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节O:精尽MyBatis源码剖析 - 插件机制①插件机制 植入插件逻辑分页插件示例InterceptorInvocationPluginInterceptorChain阿里p8私藏MyBatis笔记,从入门到精通,纵享源码细节P:精尽MyBatis源码剖析 - MyBatis-Spring 源码剖析①配置示例 ...

July 17, 2021 · 1 min · jiezi

关于学习笔记:CRC16学习笔记

参考文章: http://www.360doc.com/content...http://www.xjtudll.cn/Exp/273/http://www.ip33.com/crc.htmlhttps://blog.csdn.net/liyuanb...最近在学习Modbus协定,看到CRC校验后被难住,而后在网上找了一下材料,整顿如下,不便查阅。 什么是CRCCRC即循环冗余校验码(Cyclic Redundancy Check):是一种数据传输检错性能,对数据进行多项式计算,并将失去的后果附在帧的前面,接管设施也执行相似的算法,以保障数据传输的正确性和完整性。 CRC算法CRC算法的根本思维是将传输的数据当做一个位数很长的数。将这个数除以另一个数。失去的余数作为校验数据附加到原数据前面。 在CRC算法中,这个被除数有一个专有名称叫做“生成多项式”。生成多项式的选取是个很有难度的问题,如果选的不好,那么检出谬误的概率就会低很多。好在这个问题曾经被专家们钻研了很长一段时间了,对于咱们这些使用者来说,只有把现成的成绩拿来用就行了。 最罕用的几种生成多项式如下: CRC8=X8+X5+X4+X0CRC-CCITT=X16+X12+X5+X0CRC16=X16+X15+X2+X0CRC12=X12+X11+X3+X2+X0CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+X0CRC算法的编程实现假如咱们的生成多项式为:100110001(简记为0x31),也就是CRC-8 则计算步骤如下: 1、将CRC寄存器(8-bits,比生成多项式少1bit)赋初值02、在待传输信息流前面退出8个03、While (数据未解决完)4、Begin5、 If (CRC寄存器首位是1)6、 reg = reg XOR 0x317、 CRC寄存器左移一位,读入一个新的数据于CRC寄存器的0 bit的地位。8、End9、CRC寄存器就是咱们所要求的余数。实际上,真正的CRC 计算通常与下面形容的还有些出入。这是因为这种最根本的CRC除法有个很显著的缺点,就是数据流的结尾增加一些0并不影响最初校验字的后果。这个问题很让人恼火啊,因而真正利用的CRC 算法根本都在原始的CRC算法的根底上做了些小的改变。 所谓的改变,也就是减少了两个概念,第一个是“余数初始值”,第二个是“后果异或值”。 所谓的“余数初始值”就是在计算CRC值的开始,给CRC寄存器一个初始值。“后果异或值”是在其余计算实现后将CRC寄存器的值在与这个值进行一下异或操作作为最初的校验值。退出这些变形后,常见的算法形容模式就成了这个样子了: 1、设置CRC寄存器,并给其赋值为“余数初始值”。2、将数据的第一个8-bit字符与CRC寄存器进行异或,并把后果存入CRC寄存器。3、CRC寄存器向右移一位,MSB补零,移出并查看LSB。4、如果LSB为0,反复第三步;若LSB为1,CRC寄存器与0x31相异或。5、反复第3与第4步直到8次移位全副实现。此时一个8-bit数据处理结束。6、反复第2至第5步直到所有数据全副解决实现。7、最终CRC寄存器的内容与“后果异或值”进行或非操作后即为CRC值。CRC16/MODBUS计算方法1、设置CRC寄存器,并给其赋值0xFFFF。2、将数据的第一个8-bit字符与CRC寄存器进行异或,并把后果存入CRC寄存器。3、CRC寄存器向右移一位,MSB补零,移出并查看LSB。4、如果LSB为0,反复第三步;若LSB为1,CRC寄存器与0x31相异或,后果存入CRC寄存器。5、反复第3步与第4步直到8次移位全副实现。此时一个8-bit数据处理结束。6、反复第2至第5步直到所有数据全副解决实现。7、最终CRC寄存器的内容即为CRC值。以下应用C#代码实现上述计算方法 private void CalculateCRC(byte[] pByte, int nNumberOfBytes, out ushort pCheckSum){ int nBit; pCheckSum = 0xFFFF; for (int nByte = 0; nByte < nNumberOfBytes; nByte++) { pCheckSum ^= pByte[nByte]; for(nBit = 0;nBit < 8;nBit++) { if((pCheckSum & 0x1) == 1) { pCheckSum = (pCheckSum >> 1) ^ 0xA001; } else { pCheckSum >>= 1; } } }}理论应用中,上述代码因为效率过低很少被应用。罕用查表法代替。 ...

May 29, 2021 · 6 min · jiezi

Vuejs学习笔记

Vue.js学习笔记 v-bind绑定属性,代码: v-bind:hrefv-bind:srcv-bind:classvar app3 = new Vue({ el: '#app3', data: { target_location: 'https://baidu.com', target_name: '百度一下', img_location: '../img/bing-0615.jpeg', isActive: true }});<!doctype html><html lang="zh-cn"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>v-bind的使用</title> <style> .active { background-color: #00b3ee; } </style></head><body><div id="app3"> 跳转到 <a v-bind:href="target_location" target="_blank">{{target_name}}</a><br> <a :class="{active: isActive}">Click me!</a> 图片: <img alt="沙丘上的日落" v-bind:src="img_location"/></div><script src="../lib/vue.js"></script><script src="../js/main.js"></script></body></html>v-on绑定动作:代码 v-on.preventvar app4 = new Vue({ el: '#app4', data: {}, methods: { onEnter: function () { console.log("mouse enter"); }, onLeave: function () { console.log("mouse leave"); }, onSubmit: function () { console.log("已经提交!"); } }});<!doctype html><html lang="zh-cn"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>v-on的使用</title></head><body><div id="app4"> <form @keyup.enter="onEnter" v-on:submit.prevent="onSubmit"> <!-- prevent:抑制默认行为 --> <input type="text"/> <button type="submit">提交</button> </form> <button v-on="{mouseenter: onEnter, mouseleave: onLeave}">测试按钮</button></div><script src="../lib/vue.js"></script><script src="../js/main.js"></script></body></html>v-model绑定数据: ...

June 15, 2019 · 2 min · jiezi

你必须知道的Git命令

这篇笔记是为了学习Git知识而收集总结的,主要是看受一篇帖子《你可能不知道的15条Git命令》的影响,才想记录这篇笔记的,如有雷同,纯属巧合。 Git 是一个分布式版本控制软件, 最初目的是为更好地管理Linux内核开发而设计。来源:维基百科 - Git Git是一个软件,它允许你通过提交对一个系统(或一组)文件的历史进行注释。这些提交便是在给定时间点对系统做出的差异“快照”。 官网下载速度慢,可使用这个链接下载 或者Github下载地址, 需要其他版本请提issue联系我。 1. Git 配置--system #系统级别--global #用户全局--local #单独一个项目git config --global user.name "xxxx" #用户名git config --global user.email "xxxx@xxx.com" #邮箱git config --list # 列举所有配置连接远程仓库github 创建SSH Key ssh-keygen -t rsa -C <youremail@example.com>登陆GitHub,打开Account settings -> SSH Keys -> Add SSH Key,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容测试是否连接 ssh git@github.com几个概念: 工作区(Working Directory): 你在电脑里能看到的目录。 暂存区(stage / index): 保存了下次将提交的文件列表信息, 一般存放在 .git目录下 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。 版本库(Repository): 工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。 远程仓库(Remote) 阮一峰老师对Git工作区、暂存区、版本库、远程仓库的解释 Runoob对Git工作区、暂存区、版本库、远程仓库的解释 忽略文件配置:添加.gitignore文件 文件 .gitignore 的格式规范如下: ...

May 9, 2019 · 4 min · jiezi

重学前端学习笔记八JavaScript中的原型和类

笔记说明重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的可以加入winter的专栏学习【原文有winter的语音】,如有侵权请联系我,邮箱:kaimo313@foxmail.com。一、什么是原型?1.0、定义原型是指一个词语或一个类型意义的所有典型模型或原形象,是一个类型的组典型特征1.1、基于类的编程语言诸如 C++、Java 等流行的编程语言是使用类的方式来描述对象,基于类的编程提倡使用一个关注分类和类之间关系开发模型。1.2、基于原型的编程语言如 JavaScript 编程语言是利用原型来描述对象,基于原型的编程看起来更为提倡程序员去关注一系列对象实例的行为,而后才去关心如何将这些对象,划分到最近的使用方式相似的原型对象,而不是将它们分成类。1.3、原型系统的“复制操作”有两种实现思路一个是并不真的去复制一个原型对象,而是使得新对象持有一个原型的引用另一个是切实地复制对象,从此两个对象再无关联。javaScript选择了第一种方式。 二、JavaScript 的原型2.0、原型系统的两条概括如果所有对象都有私有字段 [[prototype]],就是对象的原型读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。2.1、三个内置函数可以利用下面三个方法,更直接地访问操纵原型,来实现抽象和复用。 Object.create 根据指定的原型创建新对象,原型可以是 nullObject.getPrototypeOf 获得一个对象的原型Object.setPrototypeOf 设置一个对象的原型winter举了用原型来抽象猫和虎的例子: var cat = { say() { console.log("meow~"); }, jump() { console.log("jump"); }}var tiger = Object.create(cat, { say: { writable: true, configurable: true, enumerable: true, value: function(){ console.log("roar!"); } }})var anotherCat = Object.create(cat);anotherCat.say(); // meow~var anotherTiger = Object.create(tiger);anotherTiger.say(); // roar!三、早期版本中的类与原型3.0、“类”的定义是一个私有属性 [[class]]所有具有内置 class 属性的对象:(ES3和之前版本) var o = new Object;var n = new Number;var s = new String;var b = new Boolean;var d = new Date;var arg = function(){ return arguments }();var r = new RegExp;var f = new Function;var arr = new Array;var e = new Error;console.log( [o, n, s, b, d, arg, r, f, arr, e].map(v => Object.prototype.toString.call(v) ))语言使用者唯一可以访问 [[class]] 属性的方式是 Object.prototype.toString。 ...

May 6, 2019 · 2 min · jiezi

重学前端学习笔记五如何运用语义类标签来呈现Wiki网页

笔记说明重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的可以加入winter的专栏学习【原文有winter的语音】,如有侵权请联系我,邮箱:kaimo313@foxmail.com。HTML语义:如何运用语义类标签来呈现Wiki网页?通过wiki网页案例来学习语义类标签HTML最初的设计场景就是“超文本”,早期HTML工作组的专家都是出版界书籍排版的专家。案例网址: https://en.wikipedia.org/wiki/World_Wide_Web 打不开上面这个网址的,(winter很贴心)提供了副本网址: http://static001.geekbang.org/static/time/quote/World_Wide_Web-Wikipedia.html 说明:本文图片由winter专栏提供,觉得不错的可以去订阅winter的专栏学习全文。1、aside 标记的这块区域属于aside内容主要就是起到导航作用。 2、article 标记的这块区域文章的主体部分可使用article,具有明确的独立性。 3、hgroup,h1,h2 标记的部分可以像下面这样解析: hgroup是标题组h1是一级标题:World Wide Webh2是二级标题:From Wikipedia, the free encyclopedia代码的话就类似这样: <hgroup><h1>World Wide Web </h1><h2>From Wikipedia, the free encyclopedia</h2></hgroup>4、abbr 说实话这个标签我没有见过,有点惭愧,我特意查了一下w3c的abbr标签的定义和用法: <abbr> 标签指示简称或缩写,比如 "WWW" 或 "NATO"。通过对缩写进行标记,您能够为浏览器、拼写检查和搜索引擎提供有用的信息。<abbr> 标签最初是在 HTML 4.0 中引入的,表示它所包含的文本是一个更长的单词或短语的缩写形式。浏览器支持情况: 所有浏览器都支持 <abbr> 标签注释:IE 6 或更早版本的 IE 浏览器不支持 <abbr> 标签。实列:标记一个缩写 The <abbr title="People's Republic of China">PRC</abbr> was founded in 1949.通过这些介绍,winter这里提的WWW就很好理解了: <abbr title="World Wide Web">WWW</abbr>.5、hr 你们一开始是不是觉得这里是不是用hr吗? 我一开始认为就是用hr,但被winter打脸了_(:3」∠)_. 答案是不用。 解释如下: winter: hr表示故事走向的转变和话题的转变,显然这里是两个标题,并没有这种关系,应该通过css的border来实现<hr>注意的几个点 修改颜色使用background-color属性hr标签是块级标签,有边框设置它自身的边框为0,然后在设置height。6、p 标记的部分有三个注记(note),它在文章中的作用就是额外的注释,但是html中并没有note相关的语义,这时可以使用p标签进行相关实现。 7、strong 如果上下文中某些词很重要我们可以用strong标签 ...

April 28, 2019 · 2 min · jiezi

重学前端学习笔记三前端知识框架图

笔记说明重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的可以加入winter的专栏学习【原文有winter的语音】,如有侵权请联系我,邮箱:kaimo313@foxmail.com。列一份前端知识框架图两个目标1、把无法通查阅解决的原理和背景讲清楚2、把不方便查阅和记忆的内容整理好前端知识划分本文所有知识架构图由winter专栏提供1、基础部分JavaScript知识架构 编程语言一般规律:用一定的词法和语法,表达一定语义,从而操作运行时 CSS和HTML知识架构 文档元信息:通常是出现在 head 标签中的元素,包含了描述文档自身的一些信息语义相关:扩展了纯文本,表达文章结构、不同语言要素的标签链接:提供到文档内和文档外的链接替换型标签:引入声音、图片、视频等外部元素替换自身的一类标签表单:用于填写和提交信息的一类标签表格:表头、表尾、单元格等表格的结构 浏览器的实现原理知识架构 2、实践部分前端工程实践 性能工具链持续集成搭建系统架构与基础库前端的知识框架 个人总结我上大学那一会,还没有专门开设前端课程,只有几本书简单讲解了JavaScript跟部分网页知识,前端也没有十分重视,也没有听过前端工程师这个职位,想必大家很多都一样,从事前端这份工作要不是自学过来的,要不就是培训过来的,当然也有很多大佬是从事其他语言开发过来的,如果觉得自己的前端知识架构不太完善的话,希望这篇能帮助到你

April 25, 2019 · 1 min · jiezi

重学前端学习笔记二

笔记说明重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的可以加入winter的专栏学习【原文有winter的语音】,如有侵权请联系我,邮箱:kaimo313@foxmail.com。明确你的前端学习路线与方法学习路径于学习方法1、零基础入门(前端教材,MDN网站)javaScrip高级程序设计精通CSS...MDN2、一年以上工作经验 (比如学习:重学前端)摸索合适自己的前端学习方法建立前端技术的知识架构理解前端技术背后的核心思想前端学习方法1、建立知识架构目的:把零散的知识组织起来,发现一些知识盲区注意:知识架构的优劣取决于逻辑性跟完备性2、追本溯源winter举了css里的display属性,讲清楚就必须关注正常流(Normal Flow)、关注弹性布局系统以及grid这些内容还举了MVC这类涉及的概念经历各种变迁,变得很复杂和有争议性,这个时候就需要做一些考古工作(比如wiki上找找资料,论文,以及当时的背景...)为什么JavaScript是现在这个样子的(里面还有一些趣闻)个人总结看完这篇其实我想到的是一句话,知其然知其所以然。这两个方法在其他学习领域也具有通用性,不仅仅局限于前端学习,如果你前端遇到什么问题的时候,不妨想想他的来源会也许对你很有帮助

April 25, 2019 · 1 min · jiezi

软件工程学习笔记

要想管理好一个软件项目,主要是管理好「人」和「事」,「人」包括项目涉及到到所有关联人员,而管理好「事」就是软件工程要做的事情。 基本理论时间,范围,成本,质量 四个要素不可能面面俱到,如同CAP定理和Base理论一样。一定要让老板和产品经理意识到这个问题,才能顺利进行解决方案到分析和讨论。 风险管理主要风险项目风险:预算、进度、用户、需求等人员风险:离职、人手不足技术风险:引进了项目成员不熟悉的技术、技术不成熟等商业风险:市场反应、产品策略、市场变化和应对策略等应对方法

April 22, 2019 · 1 min · jiezi

【修炼内功】跃迁之路

而立之年回顾我的此半生经历了2018的种种之后,终于找到一丝平静。跃迁,这是2019年,对自己的一种期待。树无根不长,人无志不立。志不立,天下无可成之事!此文用以记录2019年成长之路(不定期更新),谨以自勉!技术类文学类《看见》柴静

March 28, 2019 · 1 min · jiezi

C语言笔记(第一章:C语言编程)

第一章:C语言编程标签(空格分隔): C语言学习本章主要内容C语言标准标准库的概念如何创建C程序如何组织C程序如何编写在屏幕上显示文字的程序1.C语言标准任何物品事件的使用都需要一个大家都认同的使用规则,如同游戏一样,大家需要遵守同一个游戏规则,才能更好的使用。1989 年国际标准组织 ISO 采纳了美国国家标准协会(ANSI)对于C语言的标准化,此时C语言又被称为 ANSI C。正式发布后官方名称——ISO/IEC 9899: 1990,简称:C89/90 标准1999 年C语言标准委员会对C语言进行了改进,正式发布了 ISO/IEC 9899: 1999,简称:C99 标准2007 年,C语言标准委员会又重新开始修订C语言,到了 2011 年正式发布了 ISO/IEC 9899 : 2011,简称:C11 标准。C标准的详细介绍——维基百科2.标准库的概念概念: 标准库定义了编写C程序时常常需要的常量、符号和函数。同时提供了基本C语言的一些可选扩展。位置:标准库在一系列标准文件——头文件中指定,头文件的扩展名总是.h。例如: < assert.h >—定义awwert和static_asssert宏C标准库也称为ISO C库,是用于完成诸如输入/输出处理、字符串处理、内存管理、数学计算和许多其他操作系统服务等任务的宏、类型和函数的集合。它是在C标准中(例如C11标准)中定义的。3.创建C程序创建C程序有四个基本的过程编辑编译链接执行1.编辑编辑的过程就是创建和修改C程序的源代码——我们编写的程序指令称为源代码。编译器:是提供了编写,管理,开发与测试的环境也称为集成开发环境(Integrade Developmen Environment,IDE)2.编译编译器将源代码转换成为机器语言,并且在编译的过程中,找出并报告错误。编译器能找出程序中很多的无效或无法识别的错误,以及结构错误。源文件就是用汇编语言或高级语言写出来的代码保存为文件后的结果。扩展名为:.C编译器的输出结果称为——对象代码(object code),存放对象代码的文件称为对象文件(object file)如果程序有错误则阻止对象程序和文件的创建如果程序没有错误则编译成功,会生成一个与源文件同名的文件扩展名为.obj(Windows环境)/.o(Linx/UNIX环境)3.链接通过链接器把源文件和对象文件以及必须的代码模块组合成一个新的文件。链接器:将源代码文件中由编译器产生的各种对象模块组合起来,再从C语言提供的程序库中添加必要的代码模块,将他们组合成一个可执行的文件。扩展名为:.exe连接器可以检测和报告错误。4.执行当成功完成了上述三个阶段后,运行程序。程序运行的流程图如下:st=>start: 开始e=>end: 成功op1=>operation: <编辑>创建/修改程序源代码op2=>operation: 源文件(.C)op3=>operation: <编译>生成机器指令cond1=>condition: 成功?op4=>operation: 对象文件(.obj)op5=>operation: <链接>链接源代码文件库等cond2=>condition: 成功?op6=>operation: 可执行文件(.exe)op7=>operation: <执行>运行程序cond3=>condition: 成功?st->op1->op2->op3->cond1cond1(no)->op1->op2->op3->cond1cond1(yes)->op4->op5->cond2cond2(no)->op1->op2->op3->cond1cond2(yes)->op6->op7->cond3cond3(no)->op1->op2->op3->cond1cond3(yes)->e

February 21, 2019 · 1 min · jiezi

CORS:跨域资源共享

定义是由W3C提出的一个用于浏览器以XMLHttpRequest方式向其他源的服务器发起请求的规范。不同于JSONP,CORS是以Ajax方式进行跨域请求,需要服务端与客户端的同时支持。目前CORS在绝大部分现代浏览器中都是支持的(IE浏览器不能低于10)原理CORS标准定义了一个规范的HTTPHeaders来使得浏览器与服务端之间可以进行协商来确定某个资源是否可以由其他域的客户端请求获得。尽管很多的验证与鉴权是由服务端完成,但是本质上大部分的检查和限制还是应该由浏览器完成。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。一般来说CORS会分为简单请求与预检请求两大类。预检请求当浏览器的请求方式满足以下的任意一个条件的时候,浏览器会先发送一个OPTION请求,用来与目标域名服务器协商决定是否可以发送实际的跨域请求。OPTIONS请求头部中会包含以下头部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers。服务器收到OPTIONS请求后,设置Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers头部与浏览器沟通来判断是否允许这个请求。请求方法不是下列之一:GETHEADPOST请求头中的Content-Type请求头的值不是下列之一:application/x-www-form-urlencodedmultipart/form-datatext/plain否则就是预检请求。预检请求会在正式通信之前,增加一次HTTP查询请求。浏览器会先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。预检请求的发送请求:“预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。请求头信息里面,关键字段是Origin,表示请求来自哪个源。除了Origin字段,“预检"请求的头信息包括两个特殊字段:Access-Control-Request-Method:该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是GET。Access-Control-Request-Headers:该字段指定浏览器CORS请求会额外发送的头信息字段.预检请求的返回:Access-Control-Allow-Methods:必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次预检请求。Access-Control-Allow-Headers:如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在预检中请求的字段。Access-Control-Max-Age:该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是5个小时(18000秒),即允许缓存该条回应18000秒(即5小时),在此期间,不用发出另一条预检请求。一旦服务器通过了预检请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。简单请求当浏览器的请求方式是HEAD、GET或者POST,并且HTTP的头信息中不会超出以下字段:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain浏览器会将该请求定义为简单请求,对于简单的跨域请求或者通过了预检的请求,浏览器会自动在请求的头信息加上Origin字段,表示本次请求来自哪个源(协议 + 域名 + 端口),即表明这是一个跨域请求。服务端会获取到这个值,根据相应的跨域规则然后判断是否同意这次请求并返回。典型的请求头尾:// 请求 - GET /cors HTTP/1.1 - Origin: http://localhost:8080 - Host: api.alice.com - Accept-Language: en-US - Connection: keep-alive - User-Agent: Mozilla/5.0…如果服务端允许,在返回的头信息中会多出几个字段:// 返回 Access-Control-Allow-Origin: http://localhost:8080 Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: Info Content-Type: text/html; charset=utf-8Access-Control-Allow-Origin:必须。它的值是请求时Origin字段的值或者 ,表示接受任意域名的请求。Access-Control-Allow-Credentials:可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。 再需要发送cookie的时候还需要注意要在AJAX请求中打开withCredentials属性:withCredentials = true;需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且原网页代码中的document.cookie也无法读取服务器域名下的Cookie。Access-Control-Expose-Headers:可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方 法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last- Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader(‘Info’)可以返回Info字段的值。如果服务端拒绝了调用,即不会带上 Access-Control-Allow-Origin 字段,浏览器发现这个跨域请求的返回头信息没有该字段,就会抛出一个错误,会被 XMLHttpRequest 的 onerror 回调捕获到。这种错误无法通过 HTTP 状态码判断,因为回应的状态码有可能是200。总结服务器端对于跨域请求的处理流程如下:首先会检测http请求头是否有origin字段;如果没有,或者不允许,直接当成普通请求处理,结束;如果有并且是允许的,那么再看是否是预检请求如果不是预检请求,就返回Allow-Origin、Allow-Credentials等,并返回正常内容。如果是预检请求,就返回Allow-Headers、Allow-Methods等,内容为空。

February 21, 2019 · 1 min · jiezi

位运算

简介众所周知,在计算机中,任何对数的处理都会回归于对相应二进制数的处理。我们把这对应的二进制形式称为机器数(最高位储存符号,“0”是“+”,“1”是“-”),位运算可以对机器数直接进行一元操作(有一个被处理数)或二元操作(有两个)。在平时,位运算比部分正常运算略快;不过当问题本身涉及到对二进制数的转化与处理时,位运算更能发挥巨大的作用。位运算符简介左移运算符 <<对于一个二进制数,我们使用左移操作,它包含被操作值和移位值,左移操作就是将该数每一位上的数向左移动移位值,如0000 0000 0000 0011(3)向左移位1一位成为0000 0000 0000 0110(6).v<<s上述代码展示了左移运算符的使用,v是被操作的整数值,s是移动位数。对于二进制数,我们知道每一位上等于右边一位的两倍。那么,左移一位即等于乘2。那么3<<1便等价于(1×2^1+1×2^0)×2=6。位移n位,以此类推,等于原值的2^n倍。右移运算符 >>v>>s据左移运算符的功能类推可知,右移运算符即将每一位右移n位。位移后的值等于原值的1/2^n倍。对于位移运算符,位移后腾出的位置用“0”填充,超出边界的值舍弃。按位反运算符 ~位反运算符将每一位转换为它的反面。按位或运算符 |对两个等长二进制整数值操作,若两个数的对应位中只要有一个及以上的“1”,结果新值中此位为“1”,其余情况此位则为“0”。按位异或运算符 ^对两个等长二进制整数值操作,若两个数的对应位中只有一个为“1”,新值相应位为“1”,而若都是“0”或“1”,相应位为“0”。按位与运算符 &对两个等长二进制整数值操作,若两个数的对应位中两个都是“1”,新值相应位为“1”,其余情况新值相应为皆为“0”.

February 4, 2019 · 1 min · jiezi

测试是否能用markdown

积极进取’‘‘include<stdio.h>main(){printf(“hello,world”);}

January 28, 2019 · 1 min · jiezi

小李飞刀:醉卧沙场君莫笑,python你还是等等我

前面的一些碎碎念两天的耽搁,思考了下,虽然需要全面基础的学习,但是重点还是应该放在实战上。所以后续要速速的推倒这个教程了,用一些数据来实行一些分析:)认真学习的分割线打打打打鸡血!!!喝了一点点梅子酒,让我的创造力更加丰丰丰丰富!IO编程文件读写读读读当我想读文件的时候,我可以做下面的动作。偷偷的先open()个文件,记得传入文件名和标志符号然后再小小的read()一下最后记得close()f = open(’/Users/michael/test.txt’, ‘r’)f.read()f.close()当文件不存在的时候是会报错的喔,所以我们可以用try…finally来实现准确的关闭文件。try: f = open(’/path/to/file’, ‘r’) print(f.read())finally: if f: f.close()更简洁的版本是with open(’/path/to/file’, ‘r’) as f: print(f.read())如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便。当读入的文件为二进制文件或图片等其他,用rb模式打开文件即可。当读入的文件不是UTF-8编码的时候,要传入encoding参数。写写写当我想写文件的时候,我在open()的时候把标志符改为wf = open(’/Users/michael/test.txt’, ‘w’)f.write(‘hello world’)f.close()可以传入wb来写二进制文件。写特定编码的文件的时候,传入encoding参数。为了不然后面写入的文件覆盖前面的,用a(append)模式写入即可,会追加到文件末尾。StringIO和BytesIOStringIOStringIO顾名思义就是在内存中读写str。要把str写入StringIO,首先要先创建一个StringIO,然后写入~用getvalue来获取写入后的str。如果想读取StringIO,也可以用str初始化一个StringIO,用readline()读取。BytesIO这位朋友是用来操作二进制文件的,在内存中读写bytes。>>> from io import BytesIO>>> f = BytesIO()>>> f.write(‘中文’.encode(‘utf-8’))6>>> print(f.getvalue())b’\xe4\xb8\xad\xe6\x96\x87’然后同StringIO一样,也可以用一个bytes初始化BytesIO,然后像文件一样读取。—–写于2019-01-09

January 11, 2019 · 1 min · jiezi

小李飞刀:ppppppython你好哇

日常的写在前面难得的周末,有大段的时间可以用来学习,体验就和工作日的晚上完全不一样了。好好的沉下心学习下~即刻很喜欢了!好好学习的分割线打打打鸡血!!!!!!面向对象高级编程前天的定制类的__call__通过小佳扬的一语惊醒梦中人,就是把对象函数化了。感觉有点囫囵吞枣,看完教程后要还好好地归纳下。枚举类定义常量时候使用,例如定义月份。JAN = 1FEB = 2MAR = 3…NOV = 11DEC = 12但是此时的类型是int。通过Python提供的Enum类来实现为枚举类型定义一个class类型。from enum import EnumMonth = Enum(‘Month’, (‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’, ‘May’, ‘Jun’, ‘Jul’, ‘Aug’, ‘Sep’, ‘Oct’, ‘Nov’, ‘Dec’))这样就获得了Month类型的枚举类,可以使用Month.Jan来引用一个常量,或者枚举成员。for name, member in Month.members.items(): print(name, ‘=>’, member, ‘,’, member.value)value属性是自动赋给成员的值,默认从1开始计数。如果需要更精确地控制枚举类型,可以从Enum派生出自定义类。from enum import Enum, unique@uniqueclass Weekday(Enum): Sun = 0 # Sun的value被设定为0 Mon = 1 Tue = 2 Wed = 3 Thu = 4 Fri = 5 Sat = 6@unique装饰器可以帮助我们检查保证没有重复值。使用元类type()动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。type()函数可以查看类型或者变量的类型,class的类型就是type。而且type()函数既可以返回一个对象的类型,又可以创建出新的类型。#用type()函数创造出hello类def fn(self, name=‘world’): # 先定义函数 print(‘Hello, %s.’ % name)Hello = type(‘Hello’, (object,), dict(hello=fn))用type()创建类,需要依次传入三个参数:class的名称;继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上这样和直接定义class的写法没有差异,但是这样的话就可以在代码运行的过程中,动态创建类,这和静态语言有很大不同。metaclass除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass。先定义metaclass,就可以创建类,最后创建实例。据说很难理解的魔术代码,还是认真的努力理解下吧!看下大牛的代码!这个metaclass可以给我们自定义的MyList增加一个add方法:定义ListMetaclass,按照默认习惯,metaclass的类名总是以Metaclass结尾,以便清楚地表示这是一个metaclass。# metaclass是类的模板,所以必须从type类型派生:class ListMetaclass(type): def new(cls, name, bases, attrs): attrs[‘add’] = lambda self, value: self.append(value) return type.new(cls, name, bases, attrs)有了ListMetaclass,我们在定义类的时候还要指示使用ListMetaclass来定制类,传入关键字参数metaclass:class MyList(list, metaclass=ListMetaclass): pass这样MyList创建的时候,需要通过ListMetaclass.new()来创建。new()方法接收到的参数依次是:当前准备创建的类的对象;类的名字;类集成的父类集合;类的方法集合。而MyList()可以调用add方法,但普通list()就没有。list即类的对象。这个复杂的有点变态的定义方式,在一些场景下,例如ORM的编写中,会很有用。ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码更简单,不用直接操作SQL语句。这块有点复杂,虽然看懂了,但是还要好好琢磨下错误、调试和测试错误处理高级语言都内置了一套try…except…finally…的错误处理机制,Python小可爱也有。try当有错误时候,会打断代码的进行,跳转到except处,一旦有finally的话就一定会执行,无论有没有发生错误。可以有多个except获取不同的错误,但是注意父类和子类的问题,如果一旦包括了父类错误,子类所在的except就不会被执行。except后也可以加else语句,当没有错误发生的时候,会执行else语句。Python所有的错误都是从BaseException类派生的,常见的错误类型和继承关系有这些:https://docs.python.org/3/lib…也就是说,不需要在每个可能出错的地方去捕获错误,只要在合适的层次去捕获错误就可以了。这样一来,就大大减少了写try…except…finally的麻烦。调用栈如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出。所以找错误栈的时候,一定要找到准确的最里面那层。错误记录等Python解释器打印错误栈的信息,程序也结束了。既然可以捕获,就在捕获的同时打印错误信息并分析原因,让程序继续下去。Python内置的logging可以很容易的记录错误信息。# err_logging.pyimport loggingdef foo(s): return 10 / int(s)def bar(s): return foo(s) * 2def main(): try: bar(‘0’) except Exception as e: logging.exception(e)main()print(‘END’)这样打印完错误信息后还会打印END,即运行了后续的代码。将logging通过配置记录到日志文件中方便后续的排查。抛出错误捕获的错误其实是错误class的一个实例,错误也是需要定以后才能抛出然后被捕获到的。如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise语句抛出一个错误的实例.# err_raise.pyclass FooError(ValueError): passdef foo(s): n = int(s) if n==0: raise FooError(‘invalid value: %s’ % s) return 10 / nfoo(‘0’)另一种抛出错误的例子如下。# err_reraise.pydef foo(s): n = int(s) if n==0: raise ValueError(‘invalid value: %s’ % s) return 10 / ndef bar(): try: foo(‘0’) except ValueError as e: print(‘ValueError!’) raise #错误又被抛出bar()这种方式也很常见,在抛出问题后继续抛回上一级,由顶曾调用者进行处理。raise语句如果不带参数,就会把当前错误原样抛出。此外,在except中raise一个Error,还可以把一种类型的错误转化成另一种类型。调试用print()打印有问题的变量麻烦在还得删掉或注释掉相应语句断言凡是可以用print打印的地方,都可以用asset断言来代替。def foo(s): n = int(s) assert n != 0, ’n is zero!’#判断此处n!=0是否为True,如果非则抛出AssertionError return 10 / ndef main(): foo(‘0’)可以在启动Python解释器的时候关闭assert$python -0logging同样是替换print,logging不会抛出错误,而且可以输出到文件。import logginglogging.basicConfig(level=logging.INFO)s = ‘0’n = int(s)logging.info(’n = %d’ % n)print(10 / n)这就是logging的好处,它允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。pdb启动Python的调试器pdb,让程序以单步方式运行。pdb.set_trace()这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb,然后,在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点 ...

January 5, 2019 · 1 min · jiezi

小李飞刀:Python我又来啦,例无虚发~

一点点小刀刀晚上收到了某招聘软件的HR的消息,心里慌的不行。因为很想换岗位了,可是当机会来的时候,我却只能表示能力不行。所以要速速的加油了!!!开始学习的分割日常一点点小鸡血!请不要假装努力,结果不会陪你演戏。面向对象高级编程使用@propertyPython内置的@property将方法变成属性调用。class Student(object): @property def score(self): return self.score @score.setter def score(self, value): if not isinstance(value, int): raise ValueError(‘score must be an integer!’) if value < 0 or value > 100: raise ValueError(‘score must between 0 ~ 100!’) self.score = value加上@property后就变成了getter的方法,@property本身又创建了另一个装饰器score.setter,负责把一个setter方法变成属性赋值。只定义getter方法,不定义setter方法就是一个只读属性做个作业~多重继承通过多重继承,一个子类可以继承多个父类的属性与方法。class Father(object): passclass Mother(object): passclass children(Father,Mother): pass#这样孩子就同时继承了爸爸和妈妈的属性MixIn设计继承关系的时候,多重继承的设计被成为MixIn。所以在上面的代码中,我们可以考虑把Father改为FatherMixIn来更好的看出继承关系。class FatherMixIn(object): passclass MotherMixIn(object): passclass children(FatherMixIn,MotherMixIn): passMixIn的目的就是给一个类增加多种功能,所以在设计类的时候,尽量考虑多重继承,少用复杂的多层次的类的继承。Python自带的很多库也使用了MixIn。举个例子,Python自带了TCPServer和UDPServer这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMixIn和ThreadingMixIn提供。通过组合,我们就可以创造出合适的服务来。很多语言仅有单一继承的情况,如Java。定义类__str 定义__str__方法,可以打印的好看直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,repr()是为调试服务的。iter 定义__iter__方法,在被用于for…in循环时返回迭代对象,for循环会不断的调用__next__()方法拿到下一个值,直到5终止。getitem 定义__getitem__方法,让实例变成list,但并不是真实的list,所以通过定义,让它变得像list一样可操作性。 要正确实现一个__getitem__()还是有很多工作要做的,因为传入的参数可能不是int。getattr 可以尝试链式调用,这个等我明天脑子清晰的时候详细研究下。 代码先贴class Chain(object):def init(self, path=’’): self._path = pathdef getattr(self, path): return Chain(’%s/%s’ % (self.path, path))def str(self): return self.path__repr = str#无论API怎么变,SDK都可以根据URL实现完全动态的调用__call__还得看第二遍…明天一定要弄懂了晚安~ ...

January 4, 2019 · 1 min · jiezi

小李飞刀:python新年第一杀

新年快乐2019年终于来了,突然觉得有点如释重负。大概2018年实在是太沉重了吧。2019年应该是要充满拼劲的一年!!!!希望可以成功转型自己喜欢的职业。开始认真学习了鸡血一波。我今天的生活,绝不是我昨天生活的冷淡抄袭。——《红与黑》 司汤达面向对象编程实例属性和类属性实例可以继承类的属性,然后用实例属性我们可以通过self对实例进行属性绑定。但是也同样可以对类进行绑定属性。建议类的属性名和实例属性名不要重复,否则类的属性名会覆盖。面向对象高级编程使用__slots__Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性。class Student(object): slots = (’name’, ‘age’) # 用tuple定义允许绑定的属性名称 —-喝酒后遗症,今天太晚了,2019年争取每天都12点前睡觉,早上7点前起床!晚安!

January 2, 2019 · 1 min · jiezi

小李飞刀:python的2018年倒数二杀!

随便叨叨真的是很话唠的在下了。昨天没有很完整的学习,就没有发布笔记了。昨天主要是匆匆忙忙的回家了,买了好吃的法棍回家,好吃的法棍简直是战斗力的最佳保证!然后和家里人聊聊天,其实平时对着电脑多了,对着电脑聊天总是不如面对面来的有感觉。PS:但是还是很讨厌接到工作上的完全没逻辑的电话的。2018的最后两天。我很想念小胡哥哥,大概这个地方他都看不到的吧,毕竟学术上我们俩的交叉是极少的。希望2019年会变成更好的自己,也能拥有更多掌握自己生活的能力。开始认真学习的分割简单打点鸡血吧!大学时候很喜欢的一段话。每一个优秀的人,都有一段沉默的时光。那一段时光,是付出了很多努力,忍受孤独和寂寞,不抱怨,不诉苦,日后说起时,连自己都能被感动的日子。偏函数Partial function不同于高数里的偏函数。这个属于Python的functools里提供的一个很有用的功能。主要用于,设定函数的默认值,但并不改变原有的函数。比如对int()函数设定额外的参数base=8改为八进制来进行整数转化。#正常情况下int(‘12345’,base = 8)#或者我们考虑自己定义个函数int2def int2(x,base=8): return int(x,base)而functools.partial就不需要自己另外定义函数。import functoolsint2 = functools.partial(int,base=2)此时int2()就是创建出来的一个全新的函数。简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。然鹅这个偏函数,还可以在另外加入参数。当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。在使用中应该要多考虑下使用场景,又是反复使用偏函数可能会产生反效果(个人感觉,还需要实践测试)。模块模块要尽可能的不和内置函数产生冲突。为了不和别人的模块冲突,所以有了包。包名不冲突,那所有的模块就不会冲突了。每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。因为有了包,有了模块,所以可以产生多级的文件树。使用模块sys模块下有一个argv参数,用list存储命令行的所有参数。所以argv必定有至少一个参数,就是文件名。if name==’main’: test()当命令行运行hello模块文件时候,Python解释器把特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时候,if判断将失效。比如当进入交互模式时候,导入hello模块,不会直接执行test()函数,需要调用。作用域在Python里,我们通过_前缀来实现私有变量。分为正常的朋友、特殊的朋友、和暗搓搓的朋友。正常的朋友就是正常可以直接引用的。特殊的朋友,比如__xx__这个样子的,虽然可以被直接引用,但是有特殊用途。比如可以暴露我身份的__author__就是特殊变量啦。然后_xx这个样子的朋友,就是暗搓搓的朋友们啦,非公开的,不应该直接被引用。def _private_1(name): return ‘Hello, %s’ % namedef _private_2(name): return ‘Hi, %s’ % namedef greeting(name): if len(name) > 3: return _private_1(name) else: return _private_2(name)在模块内公开greeting()函数,但是内部逻辑用私有函数隐藏,这样调用的时候就不考虑内部逻辑。非常有用的代码封装和抽象的方法外部需要引用的函数才定义为public,不需要引用的全部定义成private安装第三方模块在Python中,安装第三方模块,是通过包管理工具pip完成的。然鹅这一步,在Mac或者Linux下是不需要安装pip的。(悲伤的windows鹅,幸好安装Python的时候妥妥安装了第三方库一般都有官方注册安装常用模块用Anaconda,一个基于Python的数据处理和科学计算平台,已经内置很多有用的第三方库。Anaconda会把系统Path中的python指向自己自带的Python,并且,Anaconda安装的第三方模块会安装在Anaconda自己的路径下,不影响系统已安装的Python目录。可以尝试直接import numpy等已安装的第三方模块模块搜索路径添加自己的搜索目录,有俩办法修改sys.path,添加要搜索的目录import syssys.path.append(’/user/gaga/my_py_scriptss’)-设置环境变量PYTHONPATH,不影响Python自身的搜索路径。面向对象编程emmm,真是个令人悲伤的标题。Object Oriented Programming—>所以OOP才是一种程序设计思想吗?….只是思想….OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。突然觉得OOP是一个很浪漫的思想。(题外话)面向对象的设计思想是抽象出Class,根据Class创建Instance。面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。类和实例类的定义是使用class关键字。—–困了的分界线,明日继续分解下一回合…(好像明日2019年??? 今晚小酌一杯再来继续!

December 31, 2018 · 1 min · jiezi

中级工程师之路

前言:之前在问答中问了一个问题 毕业半年感觉没什么进步该怎么办? 这个问题一直让我感觉比计较焦虑。于是在一个关于面试经验的博客中找到了一些灵感。就是通过问题进行学习,对自身的知识体系进行整理和补充。以问题作为切入点,不断对不懂或者需要解释的知识点提出疑问,并查询学习解决这些问题的方法。最终提升自己的能力!????个人感觉掘金的目录更好一些,所以原文都在掘金????文章每天更新一次????填坑-十万个为什么?(1)2018年12月17日 https://juejin.im/post/5c1707…①什么是HTML?什么是CSS?什么是JavaScript?②什么是DOM树?③JavaScript 在页面上做了什么?④CSS如何影响HTML?????填坑-十万个为什么?(2)2018年12月18日 https://juejin.im/post/5c1841…①浏览器输入网址到页面打开发生了什么?②什么是DNS?③域名解析的过程?④本地dns服务器到底是什么?????填坑-十万个为什么?(3)2018年12月19日 https://juejin.im/post/5c1994…①JavaScript获取一个对象的所有属性(自身属性和继承属性)?②什么是不可枚举属性?③判断对象中是否存在某属性?④判断属性是否可枚举?????填坑-十万个为什么?(4)2018年12月20日 https://juejin.im/post/5c19fd…①JavaScript创建对象的方法?②JavaScript继承的实现方法?③Function.prototype.call() 实现继承时的原理?(相关apply()、bind()方法的使用)

December 20, 2018 · 1 min · jiezi

小李飞刀:ppppppython是需要好好学习的

又是写在前面的乱七八糟持续学习的第三天了,持续学习是一个不容易培养的好习惯,但是坚持就是胜利嘛昨天因为一点点事情,所以没能学习很长时间,今天要补回来。周末要搬家,估计也得耽搁点学习时间,都要努力补回来感觉其实学习编程是一种锻炼逻辑思维的好办法,我这个人本身挺没逻辑的,读书的时候算法就很弱。前段时间因为一些原因吧选择参加国考,被行测狠狠的吊打,逻辑性真的很重要,贯穿生活啊。然后学习python呢,其实是为了后续的转行,其实真的是转行,以前是前端来着,可能还是个伪的。但是生活嘛,处处有惊喜啦关于职业选择知己知彼,百战不殆。除了认真磨炼基础,还得了解对方的想法。所以来分析下现在的招聘要点。有厉害的朋友们自己爬了数据来贡献。python爬取前程无忧和拉勾数据分析岗位并分析Python分析拉勾网数据分析岗位感谢大神们的分享与分析,后续努力我也自己爬一个。直接抄其中一份的结论吧1.各地区招聘公司数量和平均待遇。用tebleau生成地理图十分方便强大。可以看出不论是招聘公司的数据还是平均待遇水平主要都是北上广深杭州占优势。成都紧随其后。2.公司类型可以看出招聘的公司主要是民营企业和一些创业公司为主。3.公司规模和公司领域可以看出招聘公司的规模在50-500人规模为主,招聘的领域主要是互联网公司,金融紧随其后。4.经验和学历要求学历这里主要是大专本科为主,要求不算很高。5.岗位要求和岗位职责看词云结果所以其实数据分析岗位还是对数学能力及技术有一定的要求,(想起了万恶之源高数,扶额)还是要好好学习啊,线代统计学都抓起来看。我自己现在在的地区其实对于互联网行业并不是很友好,所以如果要继续在互联网行业深耕,还是要去搞更远的地方。之前年轻的时候觉得离家近好些,梦想“钱多事少离家近”。但事实证明,总是要有一些代价的。如果愿意承受代价,那就只能努力,而且不抱怨。无论如何,希望自己,成为那个不抱怨的自己,成为心目中那个梦想的自己。学习开始啦, 希望今天可以开始刷leetcode~不可变对象接着昨天的进度,之前不可变对象我们说的,有tuple,还有str。如果对str进行操作,a = ‘abc’a.replace(‘a’,‘A’) #‘Abc’但是a还是’abc’,因为a是变量,‘abc’才是字符串对象replace方法是作用在字符串对象上的对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。来做作业练习:把(1, 2, 3)和(1, [2, 3])放入dict或set中,并解释结果函数函数!Python内置了很多有用的函数,我们可以直接调用。要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数。可以直接从Python的官方网站查看文档:http://docs.python.org/3/libr…也可以在交互式命令行通过help(abs)查看abs函数的帮助信息。要学会看报错信息。定义函数(似乎看到函数有点小激动)def很重要,遇到return就执行完毕return none可以简写成return在Python交互环境中定义函数时,注意Python会出现…的提示。函数定义结束后需要按两次回车重新回到>>>提示符下。来完成第一个函数定义,关于my_abs,文件名为abstest.py空函数什么都不想做的函数朋友,所以直接给pass了。def nop: passpass语句什么都不做,那有什么用?实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。pass似乎是个很随和的朋友(随口说说的)参数检查内置函数和自定义函数,在报错信息上有所差异。TypeError可以检查参数个数的问题,但是当参数类型不对时候,自定义函数无法检查。所以,来修改下我们的my_abs()返回多个值返回值为tuple在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。好哒,我已经可以开始刷leetcode啦,明天见。

December 20, 2018 · 1 min · jiezi

磨刀霍霍:我李汉三又回来写代码啦~

写在前面的话不知不觉毕业已经三年多了,现在的工作中,极少涉及代码的工作。主要接触的项目是BI的建设,做的更多的类似产品经理的工作,或者比较初级的数据分析的工作。因为没有美工和测试小伙伴,所以还额外承包了这两项工作的我,偶尔也能接触到代码,比如echarts的使用,比如sql语句的编写。除此之外,有时候还有视频制作和文案撰写的工作。整体来说,整个工作生涯算是比较“充实”,什么都尝试过,所以在即将四周年的时候,我想,我该做点改变,再不疯狂我就老了。考虑过文案策划及后期制作的工作,但是考虑到三年累计的工作经验,且屈服于现实的状况,我还是选择继续数据分析的工作,或许这个转折也挺生硬的,而且我其实更喜欢做后期制作的工作(例如明星大侦探里有毒的后期),但是当我做下了这个决定,我就准备努力冲啦!我不害怕可能会有复杂的困难,我只害怕自己不曾努力,然后在老了之后才追悔莫及。毕竟,我已经丢了三年。所以,无论如何,加油吧!所以下面是认真开始学习的正文数据分析,我决定从python入手,主要的学习途径是廖雪峰的官方网站。python的简介和安装这一步可以跳过,因为之前就已经尝试安装过。第一个python程序无论如何,hello world!print(‘hello world!’)python交互模式和命令行模式的不同执行.py文件只能在命令行模式下执行。在windows下不能直接运行.py文件,但是,在Mac和Linux上是可以的,方法是在.py文件的第一行加上一个特殊的注释:#!/usr/bin/env python3print(‘hello, world’)然后,通过命令给hello.py以执行权限:$ chmod a+x hello.py就可以直接运行hello.py了。(然鹅,现在并没有Mac,摊手)输入和输出print()函数可以接受多个字符串,用逗号“,”隔开,就可以连成一串输出,遇到逗号“,”会输出一个空格。input()函数用于输入,在输入的同时,在变量中存储了输入的参数。input()可以显示字符串来提醒用户。Python基础python的注释是用#,使用缩进方式的语法,当以:结尾时,视为代码块。按照约定俗成的管理,应该始终坚持使用4个空格的缩进。请务必注意,Python程序是大小写敏感的,如果写错了大小写,程序会报错。数据类型整数、浮点数、字符串。如果字符串里面有很多字符都需要转义,就需要加很多,为了简化,Python还允许用r’‘表示’‘内部的字符串默认不转义如果字符串内部有很多换行,用n写在一行里不好阅读,为了简化,Python允许用’’’…‘‘‘的格式表示多行内容,注意在输入多行内容时,提示符由>>>变为…,提示你可以接着上一行输入,注意…是提示符,不是代码的一部分。布尔值 使用and or not 计算。空值 None 但不等同与0,因为0是有意义的。变量 可以是任意数据类型,也可以重复赋值。| 动态语言和静态语言的区别。静态语言在定义变量时候必须指定变量类型(eg:Java)。| 理解变量在内存中的表示。常量 Python中,通常用大写的变量名表示常量。| 除法 地板除 求余数10 / 3 无论除数与被除数是否为整数,结果都为浮点数10 // 3 只取结果的整数部分10 % 3 得出余数字符串与编码对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符。由于Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。ython对bytes类型的数据用带b前缀的单引号或双引号表示x = b’ABC’y = ‘ABC’x与y是不同的,x是字节型的,y是str,x的每个字符只占用一个字节纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。在bytes中,无法显示为ASCII字符的字节,用x##显示。反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法。如果bytes中包含无法解码的字节,decode()方法会报错。如果bytes中只有一小部分无效的字节,可以传入errors=‘ignore’忽略错误的字节。len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数。1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。为了保证源文件以utf-8读出,需要在开头注释:#!/usr/bin/env python3 —告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;# -- coding: utf-8 -- —告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。如果要保证源文件是utf-8编码,需要在编辑器中进行设定。格式化%和format()使用list和tuple| list为有序集合。是使用方括号的朋友| 用len()可以获取元素个数。索引从0开始,最后一个元素的索引为len(list)-1。获取最后一个元素,还可以用-1作为索引,直接获得最后一个元素。| list为可变的有序表,可以append()追加元素到末尾;可以insert()到指定位置;可以pop()删除最末尾元素,参数可以为i,即索引位置;可以直接赋值给对应的索引位置list[i] = value;内里的元素类型也可以各自不同,或者为另一个list。当list里面啥都没有的时候,len(list)输出为0。| tuple->元祖,一旦初始化就不能修改。因为不可变,所以更安全。是使用圆括号的朋友定义一个只有1个元素的tuple,要使用(1,),加上逗号,不产生歧义,否则可能会误认为数学计算。 t = (1,)理解“可变的tuple”>>> t = (‘a’, ‘b’, [‘A’, ‘B’])>>> t[2][0] = ‘X’>>> t[2][1] = ‘Y’>>> t(‘a’, ‘b’, [‘X’, ‘Y’])其实变化的是tuple里的list的指向,所以并不是tuple本身发生了变化。

December 18, 2018 · 1 min · jiezi

《Web前端黑客技术揭秘》笔记

一、Web安全的关键点浏览器的同源策略同源策略:不同域的客户端脚本在没明确授权的情况下,不能读写对方的资源。http://www.topo.com 的不同域/同域站点是否同域原因https://www.topo.com不同域协议不同,https与http是不同的协议http://alpha.topo.com不同域域名不同,alpha子域与www子域不同http://topo.com不同域域名不同,顶级域与www子域不是一个概念http://www.topo.com:8080不同域端口不同,8080与默认端口80不同http://www.topo.com/a/同域满足同协议、同域名、同端口,只是目录不同默认情况下是不允许跨域访问的,只有目标站点(http://www.topo.com)明确返回HTTP响应头:Access-Control-Allow-Origin: http://www.evil.com,那么www.evil.com上的客户端脚本才有权通过AJAX对www.topo.com上的数据进行读写操作。AJAXAsynchronous JavaScript and XML(异步的 JavaScript 和 XML)AJAX是在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。DOMDocument Object Mode (文档对象模型)中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。二、前端基础Web安全事件的角色:W3C、浏览器厂商、Web厂商、攻击者、用户。URLUniform Resource Locator(统一资源定位符)protocol://hostname[:port]/path/[;parameters][?query]#fragmentURL有三类编码方式:escape、encodeURI、encodeURIComponent,对应着三个解码函数unescape、decodeURI、decodeURIComponent。HTTPHyper Text Transfer Protocol(超文本传输协议)详情JavaScript<script>alert(1)</script><img src=# onerror=“alert(1)” /><input type=‘text’ value=“x” onmouseover=“alert(1)” /><iframe src=“javascript:alert(1)"></iframe><a herf=“javascript:alert(1)">x</a>…Cookie[name] [value] [domain] [path] [expires] [httponly] [secure]名称、值、所属域名、所属相对根路径、过期时间、是否有HttpOnly标志、是否有Secure标志三、前端黑客之XSSCross Site Script(跨站脚本),发生在目标网站中目标用户的浏览器层面上,当用户浏览器渲染整个HTML文档的过程中出现了不被预期的脚本指令并执行,XSS就会产生。反射型XSS发出请求时,XSS代码出现在URL中,作为输入提交到服务端,服务端解析后响应,在响应内容中出现这段XSS代码,最后浏览器解析执行。存储型XSS提交的XSS代码会存储在服务端,下次请求目标页面时不用再提交XSS代码。DOM型XSSDOM型XSS的XSS代码不需要服务器解析响应的直接参与,触发XSS靠的是浏览器端的DOM解析,可以认为完全是客户端的事情。常见的输入点:document.URLdocument.URLUnencodeddocument.locationdocument.referrerdocument.cookiewindows.locationwindows.name常见输出点:直接输出HTML内容:document.write()document.writeln()document.body.innerHtml=直接修改DOM树:document.forms[0].action=document.attachEvent()document.create()document.execCommand()document.body. …()替换document URLdocument.location=document.location.hostname=document.location.replace()document.location.asign()document.URL=window.navigate()打开或修改新窗口document.open()window.open()window.location.href=直接执行脚本eval()window.execScript()window.setInterval()window.setTimeout()XSS危害:挂马、盗取用户Cookie、Dos客户端浏览器、钓鱼攻击、劫持用户Web行为、蠕虫式挂马刷广告等等。四、前端黑客之CSRFCross-site request forgery(跨站请求伪造跨站的请求)跨站点的请求:跨站点请求的来源一般为其他站点,但是也可以来自本站。请求是伪造的:发出的请求不是用户的意愿的请求。HTML CSRF发起的CSRF请求都属于HTML元素发出的,HTML中能设置href/src等连接的标签都可以发起一个GET请求,如:<link href=”"><img src=”"><meta http-equiv=“refresh” content=“0; url="><iframe src=”"><script src="">…CSS中的:@import ““background:url(”")CSRF危害:篡改目标网站上的用户数据、盗取用户隐私数据、作物其他攻击向量的辅助攻击手法、传播CSRF蠕虫。五、前端黑客之界面操作劫持界面操作劫持攻击是一种基于视觉欺骗的Web会话劫持攻击,它通过在网页的可见输入控件上覆盖一个不可见的框(iframe),让用户以为在操作可见控件,但是实际上用户的操作行为被其不可见的框所劫持,执行不可见框中的恶意劫持代码,从而完成在用户不知情的情况下窃取敏感信息,篡改数据等攻击。分类点击劫持劫持的是用户的鼠标点击操作,主要的劫持目标是有重要会话交互的页面,比如,银行交易页面、后台管理页面或者劫持用户的摄像头和麦克风。拖放劫持在现在的Web应用中,有一些需要用户采用鼠标拖放完成的操作,而且用户也经常在浏览器中使用鼠标拖放操作来代替复制粘贴。因此,拖放操作劫持很大程度的扩展了点击劫持的攻击范围,也将劫持模式从单纯的鼠标点击扩展到了鼠标拖放行为。通过劫持某个页面的拖放操作实现对其他页面链接的窃取,这些链接中可能会有session key、token、password等信息;或者可以把其他浏览器中的页面内容拖放到富文本编辑器模式中,这样就能够看到页面源代码了,而这些HTML源代码中可能会存在敏感信息。触屏劫持移动智能终端设备由于体积限制,一般都没有鼠标、键盘这些输入设备,用户更多的操作是依靠手指在触屏上的点击或滑动等动作完成。在移动设备上,类似点击劫持的攻击模式,实现了对用户触摸屏操作的劫持攻击。原理分析点击劫持:CSS透明层+iframe利用CSS中透明属性opacity,取值范围0~1,取值0时透明度最高用iframe嵌入被劫持界面:<iframe id = “victim” src=“www.victim.com” scrolling=“no”>危害界面操作劫持实际上突破了CSRF的防御策略,这是一种社工色彩很强的跨域操作,而这种跨域正好是浏览器自身的特性,带来的危害可以很大,比如,篡改与删除数据,偷取隐私甚至爆发蠕虫。六、漏洞挖掘CSRF的漏洞挖掘目标表单是否有有效的token随机串目标表单是否有验证码目标是否判断了Refere来源网站根目录下的crossdomain.xml的"allow-access-from domain"是否是通配符目标JSON是否可以自定义callback函数界面劫持的漏洞挖掘目标的HTTP响应头是否设置了X-Frame-Options字段目标是否有Javascript的Frame Busting机制更简单的是用iframe嵌入目标网站试试反射型XSS漏洞挖掘反射型XSS最常见的就是直接在URL中进行注入,URL的格式如下:<scheme>://<netloc>/<path>?<query>#<fragment> 在完整的URL构成中,<path>、<query>、<fragment>都是用户可控的一般情况下可以通过将payload加入到参数来测试XSS的存在与否<script>alert(1)</script>’"><script>alert(1)</script><img/src=@ onerror=alert(1) />’ onmouseover=alert(1) x=’ onmouseover=alert(1) x=javascript:alert(1)//’";alert(1)//}x:expression(alert(1))…..根据请求后的反应看是否有弹出窗或浏览器脚本错误,如果有则说明目标存在XSS漏洞例如:www.test.com/xss.php?id=1,这里输入点为id=1,既然有输入点,查看结果则依赖于输出点,可能是以下几处:HTML标签之间,<div id=“body”>[输出]</div>HTML标签内,<input type=“text” value=[输出] />Javascript代码的值,<script>a="[输出]”;…</script>CSS代码的值,<style>body{font-size:[输出]px;…}</style>HTML标签之间有很多标签之间的脚本是无法执行的,如:<title>、<textarea>、<xmp>、<iframe>、<noscript>、<plaintext>,可以先闭合前面的标签,来使得脚本能够成功执行。</title><script>alert(1)</script>HTML标签内" onmouseover=alert(1) x=" 这种是闭合属性,然后使用on事件来触发脚本。"><script>alert(1)</script> 这种是闭合属性后又闭合标签,然后直接执行脚本。细分为三种场景:1.输出在src/href/action等属性内2.输出在on*事件内3.输出在style属性内Javascript代码的值</script><script>alert(1)//CSS代码的值与“输出再在style属性内”类似,构造能执行的Javascript语句,闭合标签。存储型XSS漏洞挖掘与反射型XSS相比,存储型XSS漏洞挖掘的差别在于:存储型XSS一般都是基于表单的提交,然后进入服务端存储,最终在某个页面输出。一般情况下,存储型XSS表单提交之后的输出点有以下几种可能:表单提交后跳转到的页面可能是输出点。表单所在的页面可能是输出点。表单提交后不见了,整个网站的某个源文件是输出点,需要借助爬虫进行分析。

September 24, 2018 · 1 min · jiezi