TedQin


  • Home

  • Categories

  • Archives

  • Tags

vue2.0仿去哪儿网移动端Webapp遇到的问题

Posted on 2019-07-31 | In 前端 , javascript , vue

vue2.0仿去哪儿网移动端Webapp遇到的问题

github地址:https://github.com/tedqin/Travel
demo:https://tedqin.github.io/Travel/

使用vue2.0对去哪儿网的移动端web页面的复现,做个总结。

为什么使用单页面应用

多页面应用

  • 每次页面跳转,后端返回一个新的html
    • 优点:首屏时间快、seo效果好(搜索引擎可以识别跳转的多个链接)
    • 缺点:页面切换慢(每次跳转需发送http请求)

单页面应用

  • js感知路由变化,动态清除页面内容并将新页面渲染
    • 优点:页面切换快
    • 缺点:首屏时间慢,seo差

移动web端配置

  • 使用rem单位
  • 防止手指放大缩小页面,修改index.js
<meta name="viewport" content="width=device-width, 
initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

组件开发

合理拆分组件,提高开发效率。父组件通过import方式导入子组件,并且

export default {
  name: 'xxx',
  components: {注册子组件名}

插槽

使用场景:当组件的内容希望父组件去定制

stylus

style库,增加开发效率。
其中,.a >>> .b具有穿透scoped限制的效果

防抖

为了防止图片加载的过程中,页面抖动(图片未加载完毕的时候,文字会在上方,加载完毕后会抖动)

.wrapper
    width: 100%
    height: 0
    overflow: hidden
    padding-bottom: 26.7% //图片的宽高比

vuex进行非父子组件数据传递

一般使用

vuex中有几个关键:单向数据的改变过程
state存放公用数据,组件改数据必须调用actions,做一些异步处理或者批量的同步操作。然后actions调用mutations,只有通过改变mutations的值才能改变state

  • 在state中设置默认值
    attr = 'aaa'
  • 在组件中通过dispatch向actions派发数据(如果没有异步请求,可以直接使用commit,跳过这步)
    this.$store.dispatch('actionsName', data)
  • 在actions中通过commit向mutations发送数据

      actionnName(tcx, data) {
          tcx.commit('mutationsName', data)
          }
    
  • 然后在mutations中修改state中的值

      mutationsName(state, data) {
          state.attr = data
          }
    

高级使用

  • 引入mapState, mapMutations import [mapState, mapMutations] from 'vuex
  • 把mapState添加到计算属性(compute)中,把mapMutations添加到方法(methods)中
      computed: {
          ...mapState({
              currentCity: 'city
          })
      },
      methods: {
          ...mapMutations(
              ['changeCity']
          )
      }
    

axios发送ajax请求

  • 使用生命周期函数mounted函数获取ajax数据,此时vue实例被挂载,但dom还没有渲染,可以节省性能
  • 请求url:axios.get('xxx/xxx.json')
  • axios返回的是promise对象,可以使用then

      methods: {
          getCityInfo () {
            axios.get('/Travel/static/mock/city.json')
              .then(this.handleGetCityInfoSucc)
          },
          handleGetCityInfoSucc (res) {
            res = res.data
            if (res.ret && res.data) {
              const data = res.data
              this.cities = data.cities
              this.hotCities = data.hotCities
            }
            ...
    
  • 对以上代码的解释:
    • 在mounted钩子函数里面定义一个A方法,只要页面加载完毕就执行A方法
    • A方法用于获取后端的数据,它是一个promise函数,只要获取到了函数就then一个B函数
    • B函数可以接收一个res参数,这个参数就是返回的结果
  • ajax请求一般放在最外层的组件,这样只需要一次请求就可以获取所有页面的内容

ajax获取动态数据

  • 在路由里的地址后面写:id,表示把对应的id参数存在了id变量中
  • 在获取ajax请求的地址上,可以写axios.get('xxx/xxx.json?id=' + this.$route.params.id)
  • 也可以写axios.get('xxx/xxx.json', {params: {id: this.$route.params.id}})

router-link

  • vue中的内置路由组件
    <router-link to='/city'></router-link>
  • 使用前先在router/index.js中配置路由
  • 可以通过配置tag属性改成别的标签

单行内容超出范围

当单行文字内容超出显示范围,而显示......时,可以

overflow: hidden
white-space: nowrap
text-overflow: ellipsis

betterscroll

页面滚动插件

函数节流

当鼠标在字母表上来回移动的时候,touchMove执行的频率是非常高的,通过函数节流限制下执行的频率:增加延时器

localstorage

自动缓存,刷新页面的时候已经选择的城市不发生改变

  • 相当于cookie,但是用法要简单很多
  • 用法:
    localStorage.arrt = va;ue
  • 最好使用try catch包裹,因为在部分浏览器会报错

keepalive

优化问题:缓存页面数据,防止切换页面会发生多次ajax请求

<keep-alive>
    <router-view/>
</keep-alive>

它的意思是,路由内容每被加载一次,就把路由中的内容放到内存之中,下一次再进这个路由的时候,不需要再次渲染这个组件去重新执行钩子函数,只需要你从内存把以前的内容拿出来显示到页面上就可以

组件中name属性

  • 在递归组件时使用
  • keepalive取消缓存在exclude=’组件name’中使用
  • vue devtool调试工具中显示项目结构的名字

组件异步加载

正常情况下,单页应用会在进入首页时加载所有组件
可以删除import特定的组件,然后通过component: () => import('@/pages/home/Home)按需加载

全局事件解绑

  • window是全局事件,无论那个页面都会监听这个事件,会影响到其他页面,所以要解绑
  • 在有keep-alive时会出现两个新的钩子函数:
    • activated 在页面被显示时执行
    • deactivated 在页面即将被隐藏或页面被替换的时候执行

简写

  • @表示src目录
  • es6中,键值对相同写一个就可以

组件一览

  • home
    • Header 头部
    • Icon 原型图标区域
    • Recommend 推荐
    • Swiper 图片轮播
    • Weekend 周末推荐
  • city
    • Header 头部
    • Alphabet 右侧城市首字母下拉列表
    • List 城市列表
    • Search 搜索
  • detail
    • Header 头部
    • Banner 主页面
    • List 图片详情页的轮播

部署到GitHub pages

参考 https://medium.com/@Roli_Dori/deploy-vue-cli-3-project-to-github-pages-ebeda0705fbd

webpack

后期更新

javascript整理

Posted on 2019-07-15 | In 前端 , javascript

闲来无事,把之前的笔记整理一下。

基础知识

变量类型

  • 值类型:a和b相等,改a,b不变 (直接赋值值)
    • undefined string number boolean
  • 引用类型:a和b相等,改a,b变 (赋值地址)
    • object function
  • 强制类型转换
    • 字符串拼接
      • var a=10; var b=100 + '10'//string
    • ==
      • 100=='100'; 0==''; null==undefined //true
    • if
      • if(b=100)//转换为true
    • 逻辑运算符(&,||)
      • 10&&0;''||'abc'; !window.abc//都转换为true或false
  • 问题
    • typeof能得到哪些类型
      • number, string, object, boolean, function, undefiend, symbol (null是object)
      • symbol: 可以生成永不重复的值,可以用一个字符串标记
    • 何时使用===,何时使用==
      • ===:内容相等数据类型也相同的严格模式;==:内容相等数据类型可以不相等
      • 使用==的唯一情况:’’if(obj.a==null){}’’

原型 原型链

  • 构造函数
    • function Foo(name,age) {this.name=name; this.age=age return this} var f = new Foo('ted',20)
    • var a ={}是var a =new Object()的语法糖//数组,函数同理
    • 函数名大写字母开头
  • 原型规则和示例
    • 所有的引用类型(数组对象函数)都具有对象特性,即可自由扩展属性(null除外)
    • 所有的引用类型都有一个__proto__属性,属性值是一个普通对象
    • 所有的函数都有一个prototype属性,属性值也是一个普通的对象
    • __proto__对象指向它的构造函数的prototype对象(完全等于)
    • 当试图得到一个引用类型的某个属性时,如果这个变量本身没有这个属性,那么会去它的__proto__,即它的构造函数的prototype中找
    • 例子:不遍历原型上的属性:if(f.hasOwnProperty(item))
  • 原型链
    • 一个对象,对象自身不存在的属性到它的隐式原型找,它的隐式原型不存的的话,再到它的隐式原型的隐式原型中找
    • Object.prototype指向null,防止死循环
  • instanceof
    • instanceof判断一个函数是否是一个变量的构造函数
    • var f = new Foo('ted') f instanceof Foo//true
    • 判断逻辑:f的__proto__一层层往上,能否对应到Foo.prototype
  • 问题
    • 如何准确判断一个变量是数组
      • var arr = [] arr instanceof Array//true
    • 写一个原型链继承的例子
      • function Animal(){this.eat = function(){console.log('eat')}} function Dog(){this.bark(){console.log('bark')}} Dog.prototype=new Animal() var haski=new Dog() //这个比较low
      • function Elem(id){this.elem=document.getElementById(id)}
        Elem.prototype.html=function(val) {
          var elem=this.elem 
          if(val){
              elem.innerHTML=val
              return this
          } else{ 
              return elem.innerHTML}}</pre> 
        
        Elem.prototype.on=function(type,fn){
          var elem=this.elem
          elem.addEventListener(type,fn)
              </pre>
        
        var div1 = new Elem('div1')
    • 描述new一个对象的过程
      • 创建一个新对象
      • this指向这个新对象
      • 执行构造函数的代码,即对this赋值
      • 返回this

作用域 闭包

  • 执行上下文 代码执行的环境
    • 一段<script>:全局上下文
      • 变量定义->函数申明
    • 一个函数:函数上下文
      • 变量定义->函数申明->this->arguments
  • this
    • this要在执行时才能确认值,定义时无法确认
    • call可以改变this的值:a.fn.call({name:B})
    • 1.作为构造函数执行:指向定义的对象
      function Foo(name) {
      this.name = name}
      var f = new Foo(‘ted’)
    • 2.作为对象属性执行:指向该对象
      var obj = {
      name: ‘A’, printName: function () {console.log(this.name)}}
      obj.printName()
    • 3.作为普通函数执行: 指向window
      function fn() {
      console.log(this)}}
    • 4.call apply bind
      function fn1(name, age) {
      alert(name); console.log(this)}
      fn1(‘ted’,20)//普通函数的this,指向window
      fn1.call({x:100},’ted’,20)//通过call函数改变this,指向{x:100}这个对象
      fn1.apply({x:200}, [‘ted’, 20])//apply和call不同在于参数用数组传递
      //bind:适用于函数表达式 
      var fn2 = function (name, age) {
      alert(name); console.log(this)}
      .bind({y:300})
      fn2('ted',20)//通过bind函数改变this,this也指向{y:300}这个对象
  • 作用域
    • JS没有块级作用域
      • 在函数中定义和赋值的变量可以在函数外使用
      • ES6中加入块级作用域:
        for(let i = 0; i< 10; i++){}
        console.log(i)//报错,let定义的变量有块级作用域,在for中定义的不能在for之外访问
    • JS有函数和全局作用域
      • 定义在函数中的变量,只能在函数中修改
    • 自由变量:当前作用域没有定义的变量,可以在父级作用域中去找
  • 作用域链
    • 当前作用域可访问父级作用域
    • 一个元素的父级作用域是在它定义的时候的作用域,而非执行
  • 闭包
    • 函数作为返回值
    • 函数作为参数传递
    • 闭包中返回的函数,若有自由变量,则向(函数定义时)父作用域寻找
  • 问题

    • 说一下对变量提升的理解
      • 在各个执行上下文中,变量定义+函数声明都会提前
    • 说明this几种不同的使用场景
      • 作为构造函数:指向定义的对象
      • 作为对象属性:指向该对象
      • 作为普通函数:指向window
      • call apply bind: 指向改变的对象
    • 创建10个<a>标签,点击的时候弹出来对应的序号
      *
    • 如何理解作用域
      • 自由变量
      • 作用域链,自由变量的查找
      • 闭包的两个场景
    • 闭包
    • 实际开发中闭包的应用

      • 封装变量,收敛权限

        let isFirstLoad = function () {
          let _list = []
          return function (el) {
              if (_list.indexOf(el) >= 0) {
                  return false
              } else {
                  _list.push(el)
                  return true
              }
          }
        }
        
        let firstLoad = isFirstLoad()
        isFirstLoad(10) //true
        isFirstLoad(10) //false
        isFirstLoad(20) //true
        
        

异步和单线程

  • 什么是异步(对比同步)
    • 同步会阻塞,异步不会,遇到setTimeout会先执行后面的代码
    • 何时使用:有可能发生等待的情况-等待的过程不能阻塞程序运行
  • 前端使用异步的场景
    • 定时任务:setTimeout,setInverral
    • 网络请求:ajax请求,动态加载 (时间不固定)
    • 事件绑定:如点击事件,在不点击的时候不能阻塞程序运行
  • 异步和单线程
    • 单线程:代码一个个排队执行,不能同时干两件事
    • js是单线程,所以在遇到阻塞的情况,要用异步,现将不需要等待的代码执行完,再执行异步代码
  • 问题
    • 同步和异步的区别是什么?分别举一个同步和异步的例子
      • 同步会阻塞代码,异步不会,alert是同步,setTimeout是异步
    • 一个关于setTimeout的笔试题
    • 前端使用异步的场景有哪些?
      • 定时任务-网络请求-时间绑定

补充

  • 日期

          Date.now() //获取时间戳
    
          //2019/09/17/23:41:44
          let dt = new Date()
          dt.getTime() //获取时间戳
          dt.getFullYear() //2019
          dt.getMonth() //8 (0-11)
          dt.getDate() //17 (0-31)
          dt.getHours() //23 (0-23)
          dt.getMinutes() //41 (0-59)
          dt.getSeconds() //44 (0-59) 
    
    
  • Math

    • 获取随机数Math.random()
  • 数组api
    • forEach 遍历所有元素
    • every 判断所有元素是否都符合条件
    • some 判断是否有至少一个元素符合条件
    • sort 排序
    • map 对元素重新组装,生成新数组
    • filter 过滤符合条件的元素
  • 对象api
    • for in
  • 题目

    • 获取2019-07-25格式的日期

        let formatDate = function (dt) {
            if (!dt) {
                dt = new Date()
            }
      
            let year = dt.getFullYear()
            let month = dt.getMonth() + 1
            let date = dt.getDate()
      
            if (month < 10) {
                month = '0' + month
            }
            if (date < 10) {
                date = '0' + date
            }
      
            return year + '-' + month + '-' + date
        }
      
        let dt = new Date()
        console.log(formatDate(dt))
      
    • 获取随机数,要求是长度一致的字符串格式

        //获取长度一致的随机数
        let formatRandom = function () {
            let random = Math.random()
            random = random + '0000000000'
            return random.slice(0, 10)
        }
      
        console.log(formatRandom())
      

JS API

  • JS语法标准(基础知识):ECMA 262标准
  • JS-WEB-API(浏览器):W3C标准
    • DOM操作
    • BOM操作:浏览器操作 获取当前地址 获取屏幕尺寸
    • 事件绑定
    • AJAX请求(包括http协议)
    • 存储
    • 没有规定任何JS基础相关的东西
  • 全面考虑,JS内置的全局函数和对象(浏览器打造)
    • Object,Array,Boolean等
    • window document
    • 所有未定义的全局变量,如navigator.userAgent

DOM操作

  • DOM本质
    • 浏览器拿到html代码后,把html结构化成浏览器可识别以及js可识别的东西,就是dom
    • dom本质是js的对象
  • DOM节点操作

    • 获取dom节点

      
        //获取DOM节点
        //get
        let id1 = document.getElementById('id1') //id
      
        let divs = document.getElementByTagName('div') //元素集合
        let div0 = document.getElementByTagName('div')[0] //元素
      
        let classes = document.getElementsByClassName('class1') //class集合
        let class0 = document.getElementsByClassName('class1')[0] //class
      
        //query
        let id1 = document.querySelector('#id1') //id
      
        let divs = document.querySelectorAll('div') //元素集合
        let div0 = document.querySelector('div') //元素,选择第一个div
        let div0 = document.querySelector('div')[0] //元素,选择第一个div
      
        let classes = document.querySelectorAll('.class0') //class集合
        let class0 = document.querySelector('class0') //class,选择第一个class
        let class0 = document.querySelector('class0')[0] //class,选择第一个class
      
      
    • property

      • js对象中的属性

        //获取attribute
        let p0 = document.quertSelectorAll('p')[0]
        
        console.log(p0.style.width) //获取样式
        p0.style.width = '200px' //修改样式
        console.log(p0.className) //获取class
        p0.className = 'p0' //修改class
        
        console.log(p0.nodeName) //p
        console.log(p0.nodeType) //1 
        
    • attribute

      • HTML文档中 标签的属性

        
        //获取attribute
        let p0 = document.querySelectorAll('p')[0]
        p0.getAttribute('attr1') //获取p0上的attr1属性的值
        p0.getAttribute('attr1', 'abc') //修改属性
        p0.getAttribute('style') //获取style,元素上必须有style才行
        p0.getAttribute('style', 'font-size:30px')
        
        
  • DOM结构操作

    • 新增节点 document.createElement(node)

        //添加新节点
        let div1 = document.getElementById('div1')
        let p1 = documemt.createElement('p')
        div1.appendChild(div1)
        //移动现有节点
        let p2 = document.getElementById('p2')
        div1.appendChild(p2)
      
      
    • 获取父节点 childNode.parentElement

        let div1 = getElementById(div1)
        let parent = div1.parentElement
      
      
    • 获取子节点 .parentNode.childNodes

        let div1 = getElementById(div1)
        let parent = div1.parentElement
      
      
      • .childNodes返回所有节点包括文本和注释节点 .children只返回元素节点
    • 删除节点 parentNode.removeChild(childNode)

        let div1 = getElementById(div1)
        let child = div1.childNodes
        //删除第一个子元素
        div1.removeChild(child[0])
      
  • 问题

    • DOM是哪一种基本数据结构
      • 数
    • DOM操作的常用API有哪些
      • 获取DOM节点,以及节点的property和attr
      • 获取父节点,子节点
      • 新增,删除,移动节点
    • DOM节点的attr和property有何局别
      • property是js属性的修改和获取
      • attr是对html标签的修改和获取

BOM操作

  • navigator浏览器
    • 判断浏览器类型 userAgent
      var ua = navigator.userAgent
      var isChrome = ua.indexOf(‘Chrome’)
      console.log(isChrome)
  • screen屏幕
    • console.log(screen.width)
      console.log(screen.height)
  • location地址栏信息 拆解url
    •   location.href //url
        location.protocal //协议 http https
        location.host //域名
        location.pathname //路径 /learn/199
        location.search //url ? 后面的字符串
        location.search //url # 后的hash
  • history历史 前进后退

    • history.back
      history.forward
  • 问题

    • 如何检测目标浏览器的类型

        let ua = navigator.userAgent
        let isChrome = ua.indexOf('Chrome')
        console.log(isChrome)
      
      
    • 拆解url的各部分

        location.href //url
        location.protocal //协议 http https
        location.host //域名
        location.pathname //路径 /learn/199
        location.search //url ? 后面的字符串
        location.search //url # 后的hash
      

Ajax

  • XMLHttpRequest

    
      let xhr = new XMLHttpRequest() 
      xhr.open("GET", "/api", "false")
      xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
              if (xhr.status === 200) {
                  alert(xhr.responseText)
              }
          }
      }
      xhr.send(null)
    
    
  • 状态码说明

    • readyState == 4 ajax状态码
      • 0-(未初始化)还没有调用send()方法
      • 1-(载入)已调用send()方法,正在发送请求
      • 2-(载入完成)send()方法执行完成,已经接收到全部响应内容
      • 3-(交互)正在解析响应内容
      • 4-(完成)响应内容解析完成,可以在客户端调用了
    • statue == 200 http标准状态码
      • 2xx - 表示成功处理请求。如200
      • 3xx - 需要重定向,浏览器直接跳转
      • 4xx - 客户端请求错误,如404
      • 5xx - 服务端错误
  • 跨域

    • 什么是跨域
      • 浏览器有同源策略,不允许ajax访问其他接口,如http://www.a.com:80不能访问http://www.b.com
      • 跨域条件:协议(http)、域名(www.a.com)、端口(:80)有一个不同就算跨域
    • 可以跨域的三个标签
      • <img src=xxx>
        • 用于打点统计,统计网站可能是其他域
      • <link href=xxx>
        • 可以使用CDN,CDN也是其他域
      • <script src=xxx>
        • 可以使用CDN,CDN也是其他域
        • 可以用于JSONP
    • JSONP 前端

        <!-- jsonp跨域 -->
        <script>
          function callbackFunc (data) {
            alert(data)
        }
      
        </script>
      
        <script src="http://www.baidu.com/api/data.js"></script>
      
      
      • 前端定义一个callback函数,得到信息。再用script标签获取一个跨域的信息,这个信息会调用callback({x:100, y:200})
    • 服务器端设置http header 后端

        //后端通过设置httpheader跨域
        response.setHeader("Access-Control-Allow-Origin", "http://a.com, http://b.com");
        response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
        response.setHeader("Access-Control-Allow-Methods", "PUT, POST,GET, OPTIONS, DELETE");
        //允许接收跨域的cookie
        response.setHeader("Access-Control-Allow-Credentials", "true");
      
  • 问题

    • 手动编写一个ajax,不依赖第三方库
      • 前面有
    • 跨域的几种实现方式
      • JSONP
      • 服务器端设置http header

事件绑定

  • 通用事件绑定

    
      //通用事件绑定函数
      function bindEvent (elem, type, fn) {
          elem.addEventListener(type, fn)
      }
    
      let a1 = document.getElementById('a1')
      bindEvent(a1, 'click', function (e) {
          e.preventDefault()
          alert('clicked')
      })
    
    
  • 事件冒泡

    • 若底层和父层节点有相同绑定事件,底层业务节点的事件(如点击)会先执行,然后会一层层网上执行,先执行底层的事件,然后上一层的事件,然后…
    • 点击激活弹出激活,点击取消弹出取消
      (e.stopPropatation():阻止冒泡)
  • 代理 事件冒泡的应用

    • 点击a标签的元素,会弹出相应文字

      `

      <!DOCTYPE html>




      propogation



      a1
      a2
      a3
      a4




    ```

(这里target可以定位到当前点击的元素)
  • 问题
    • 编写一个通用的事件监听函数
    • 描述事件冒泡流程
      • dom树形结构
      • 冒泡
      • 阻止冒泡
      • 应用:代理
    • 对于一个无限下拉加载图片的页面,如何给每个图片绑定事件
      • 使用代理:代码简洁,对浏览器压力小

存储

  • cookie
    • 属于http的东西,本身用于客户端和服务端通信
    • 但是它有本地存储的功能,于是被“借用”
    • 使用document.cookie=...获取和修改即可
    • 限制:
      • 存储量太小,只有4kb
      • 所有http请求都带着,会影响获取资源的效率
      • API简单,需要封装才能用document.coockie
  • sessionStorage和localStorage

    • H5专门为存储而设计,最大容量5M
    • API简单易用,key+value
      • localStorage.setItem(key,value)
        localStorage.getItem(key)
  • 问题

    • 描述一下cookie(h5之前),sessionStorage和localStorage的区别
      • cookie和后两者的区别
        • 容量
        • 是否会携带到ajax请求中
        • API易用性
      • 后两者的区别
        • localStorage不会主动删除,sessionStorage随着每次会话结束会清除,95%的场景存储到localStorage中

开发环境

IDE(写代码的效率)

  • webstorm
  • sublime
  • vscode
  • atom

git 版本管理,多人协作

  • 常用命令
    • git add .
    • git checkout xxx
    • git commit -m ‘xxx’ //提交到本地仓库
    • git push origin master
    • git pull origin master
    • git branch
    • git checkout -b xxx
    • git merge xxx

js模块化

  • 不适用模块化的情况
    • 如果a.js, b.js, c.js, c依赖b,b依赖a,引用的时候必须要按顺序,如果顺序错就会报错
    • 引用的文件的变量必须是全局变量,容易被污染
  • 使用模块化
    • a.js 传递出别人所需要的功能函数,b和a需要哪个函数引用哪个函数
    • 引用的时候直接引用最表层的js文件即可
  • AMD 异步模块定义规范

    • require.js
    • 全局define函数
    • 全局require函数
    • 依赖的js会自动、异步加载

      `
      //util.js
      define(function() {

       return {
           func: function () {
               return 1
           }
       }
      

      })

      //a-utils.js
      define([‘./utils.js’], function(util) {

       return {
           func2: function () {
               return util.func()
           }
       }
      

      })

    ```

*  html用:``<script src="/require.js" data-main="./main.js"></script> ``
*  好处:异步加载,不使用(依赖)就不加载
  • CommonJs

    • nodejs模块化规划,现在被大量用于前端
    • 前端开发依赖的插件和库,都可以用npm中获取
    • 构建工具的高度自动化,使得使用npm的成本非常低
    • CommonJS不会异步加载js,而是同步一次性加载出来

        //util.js
        module.exports = {
            func: function () {
                return 1
            }
        }
      
        //a-util.js
        let util = require('./util.js')
        module.exports = {
            func2: function () {
                return utils()
            }
        }
      
  • AMD和CommonJS的使用场景

    • 需要异步加载,用AMD
    • 使用了npm之后建议使用CommonJs

打包工具

  • webpack

    • 启动一个服务,先全局安装,npm install http-server =g,然后在要访问的页面根目录启动服务 http-server 8080
    • npm init 初始化,完成后多处package.json文件
    • npm install webpack --save -dev 安装webpack
  • 配置webpack

    • 创建webpack.config.js

        var path = require('path')
        var webpack = require('require')
      
        module.exports = {
            context: path.resolve(__dirname, './src'),
            extry: {
                app: './app.js'
            }.
            output: {
                path: path.resolve(__dirname, './dist')
                filename: 'bundle.js'
            }
        }
      
    • 创建src app.js等文件

    • 在package.json scripts里加入”start”: “webpack”,就可以在命令行执行start进行打包输出
  • webpack进行代码压缩:
    • 在config的exports中追加plugins: [new webpack.optimize.UglifyJsPlugin()]
  • webpack的主要作用:
    • 代码合并:合并commonjs的语法规范,否则前端无法识别
    • 代码压缩:保证代码上线

上线回滚的流程

  • 上线的基本流程
    • 将测试完成的代码提交到git版本库的master分支
    • 将当前服务器的代码全部打包并记录版本号,备份
    • 将master分支的代码提交覆盖到线上服务器,生成新版本号
  • 回滚的基本流程
    • 将当前服务器的代码全部打包并记录版本号,备份
    • 将备份的上一个版本号解压,覆盖到线上服务器,并生成新的版本号
  • linux基本命令
    • mkdir
    • ls
    • ll 列表形式的ls
    • pwd
    • cd
    • cd ..
    • rm -rf 文件夹名 //删除当前目录下所有文件
    • vi a.js //创建并进入a.js
      • i //insert
      • : //最下行
      • w //写
      • q //退出
    • cp a1 a2 //创建a2,把a1复制到a2
    • mv a1 f1 //把a1移动到f1文件夹
    • cat a1 //查看当前文件
    • grep ‘2’ a.js //查找a.js中的2

运行环境

页面加载过程

  • 加载资源的形式
    • 输入url(或跳转页面)加载html
    • 加载html中的静态资源
      • 如<script><img>
  • 加载一个资源的过程
    • 浏览器根据DNS服务器得到域名的IP地址
    • 向这个IP的机器发送http请求
    • 服务器收到、处理并返回http请求(图片,html js代码,)
    • 浏览器得到返回的请求并渲染
  • 浏览器渲染页面的过程
    • 根据HTNL结构生成DOM树
    • 根据CSS生成CSSOM(结构化处理)
    • 将DOM和CSSOM整合成RenderTree(渲染树,每个节点都规定了样式)
    • 根据RenderTree开始渲染和展示
    • 遇到<script>时,会执行并阻塞渲染
  • 题目
    • 从输入url到得到html的详细过程
      • 根据DNS得到域名IP-向该IP发送请求-服务器收到处理返回请求-浏览器得到返回内容
    • window.onload和DOMCotentLoaded的区别
      • onload:页面全部资源加载完,包括图片视频等才会执行
      • CotentLoaded:DOM渲染完即可执行,图片还没有加载完
    • 为什么把css文件放在head中?
      • 因为渲染默认是顺序的,保证在渲染body时候浏览器已经知道对应的样式了
    • 为什么把js放在body最下面?
      • 不会阻塞之前body中html的渲染
      • 保证script能拿到所有的html节点标签

性能优化

  • 基本2点
    • 多使用内存、缓存或者其他方法 -开源
    • 减少CPU计算、减少网络 -节流
  • 加载资源优化
    • 静态资源的压缩合并
      • 合并:将多个js文件合并成一个js
      • 压缩:压缩体积
    • 静态资源缓存
      • 通过连接名称,名称不变的话,浏览器会加载之前同名的缓存
    • 使用CDN让资源加载更快
      • 不同区域的网络优化,上海转到上海的节点等等
    • 使用SSR后端渲染,数据直接输出到HTML中(不同ajax请求数据)
  • 页面渲染优化

    • CSS放前面,JS放后面
    • 懒加载(图片懒加载,下拉加载更多/先用一张模糊的图片代替原图,要用的时候再加载) 什么时候用什么时候加载
    • 减少DOM查询,对DOM查询做缓存
    • 减少DOM操作,多个操作尽量合并在一个执行
      • 先创建一个片段frag=document.createDocumentFragment()
    • 事件节流

      • 间隔一段时间执行一次
      • 如键盘输入,在ns内执行一次事件, 不停的输入,也会在一段时间后输出一次

          //时间戳版
          function throttle(fn, delay) {
              let previous = 0
              return function (args) {
                  let _args = args
                  let _this = this
                  let now = Date.now()
                  if (now-previous > wait) {
                      fn.call(_this, _args)
                      previous = now
                  }
              }
          }
        
    • 事件防抖

      • 超过一段时间不输入,执行一次
      • 防止输入一个就输出一个这样的抖动情况,设置一个延迟,超过这个延迟不执行输入的情况下,才会执行输出。也就是输入一堆,停5ms不输入以后,才会输出

          function debounce (fn, delay) {
              let timeout
              return function (args) {
                  let _this = this
                  let _args = args
                  clearTimeout(timeout)
                  timout = setTimeout(function (_args, _this) {
                      fn.call(_this, _args)
                  }, delay)
              }
          }
        
          //使用防抖
          function print (content) {
              console.log(content)
          }
        
          let input = document.getElementById('text')
          let debounceInput = debounce(print, 100)
          input.addEventListener('keyup', function () {
              debounceAjax(e.target.innerHTML)
          })
        
    • 尽早执行操作(DOMCotentLoaded)

安全性

  • XSS跨站请求攻击
    • 新浪博客写一篇文章,同时偷偷插入一段攻击代码<script>
    • 攻击代码中,获取查看者的cookie,发送到自己的服务器
  • XSS预防
    • 前端替换关键字,例如替换<为&lt;>为&gt
    • 后端替换
  • XSRF跨站请求伪造
    • 你已登录一个购物网站,正在浏览商品
    • 付费接口是xxx.com/pay?id=100但是没有任何验证
    • 你收到一封钓鱼邮件,隐藏着<img src='xxx.com/pay?id=100'>
    • 查看邮件的时候,就悄悄付费了
  • XSRF预防
    • 增加验证流程,如输入指纹、密码、短信验证码
  • 问题
    • 前端安全问题的场景有哪些

面试技巧

  • 简历
    • 简介明了,重点突出项目经历和解决方案
    • 把个人博客放在简历中,并且定期维护更新博客
    • 把个人的开源项目放在简历中,并维护开源项目
    • 不能造假,要保证能力和经历上的造假
  • 谈谈你的缺点
    • 说一下最近正在学的东西,比如我对vue不是很了解,正在学vue.js

面试题

  • window.onload和DOMCotentLoaded的区别
    • onload事件触发:页面上所有dom,样式表,脚本,图片,flash都已经加载完;DOMCotentLoaded:仅dom加载完
  • 如何理解JSON
    • 是一个JS对象,有两个API:
      • JSON.stringify(obj)//将js的对象转换成json字符串
      • JSON.parse('{"a":5}')//json字符串转js对象
    • 是一个数据格式
  • js有哪些内置函数
    • Object
    • Array
    • Boolean
    • Number
    • String
    • Function(以上为构造函数)
    • Date
    • RegExp
    • Error
  • new一个vue对象发生了什么?
    1. 执行this._init()方法,初始化对象:
      • 合并配置options
      • 初始化生命周期
      • 初始化事件中心
      • 初始化渲染
      • 初始化data,props,computed,watcher等
    2. 初始化完成,检查如果有el属性,就调用vm.$mount方法挂载

promise

一种异步解决方案,类似一个容器,包括未来会执行的任务

.then()

参数1为resolve的内容,参数2(可以不要)为reject的内容

.catch()

用于resolve有错误的情况,一般用在.then的最后

.finally()

用于不管promise最后状态如何都执行的操作

.all()

用于将多个promise包装成一个
const p = Promise.all([p1, p2, p3]);

  • 必须等三个都resolve,p才resolve,而有一个reject p就reject
  • 场景:几个任务时间不一样,需要等全部完成才执行下一个任务

.race()

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3])

  • 只要有一个resolve了,就算完成
  • 场景:把异步操作和定时器绑定,如果定时到了异步操作还没完成就报错

.resolve()

将对象转换为promise对象,状态为resolve
let jsPromise = Promise.resolve(para)

  • param:
    • promise对象,直接返回不做修改
    • thenable对象:有then: function(resolve, reject){resolve()}的对象,直接封装,立即执行then
    • 普通对象:直接封装,状态为resolve

.reject()

将对象转换为promise对象,状态为reject

.try()

模拟try代码块

DCGAN进行图像修复

Posted on 2019-07-10 | In machine learning , gan

本文已置于https://github.com/tedqin/GAN-ImageRepairing

总体设计

和典型的使用神经网络来实现目的方法一样,简单来讲,基于DCGAN的图像修复首先需要先训练出一组优秀的生成器和判别器,然后利用这一组训练好的模型进行图像修复。
首先第一步需要进行图像预处理,这是因为DCGAN的模型结构决定了图像的尺寸大小是64”×” 64”×” 3,进行图像预处理之后,由于神经网络需要矩阵形式的输入,所以修复流程的首要步骤就是将图像分解为样本点,这个步骤可以由判别器的卷积实现,然后生成器和判别器进行博弈,得到训练好的模型,由生成器快速生成伪造的图像,然后建立适当的损失函数和惩罚因子来寻找修复图像所需要的最佳伪造图像。
由此,总的系统流程主要可以分为三步:

  • 图像预处理。
  • 训练DCGAN模型。
  • 找到补全原图像所需要的最佳伪造图像,进行图像修复。

图像预处理

Openface预处理

Openface是一个基于深度神经网络的开源人脸识别系统。

  • 用OpenCV或者dlib中预训练好的模型检测人脸
  • 将人脸迁移到神经网络。利用dlib的实时姿态估计与OpenCV的仿射线变换来使人脸的眼睛和嘴唇出现在每个图像上的相同位置。
  • 使用深度神经网络将面部表示(或嵌入)在128维单位超球面上。这种嵌入方法可以通用于任何人脸表示上面。与其他的一些人脸表征方法不同,这种人脸嵌入方法具有很好的性质,两个嵌入人脸间的距离较大就意味着这两幅面孔可能不是来自于同一个人。

运用Openface来消除除了人脸外的其他的因素,比如背景、发型等等,然后移动图像,使得数据集中的每个人的人脸区域居于整张图片的中央。

构建掩膜

为了能够评估修复结果,需要知道被损坏图像之前的样子。我采用给未损坏图像一个二进制掩膜来作为损坏区域,这样就可以在修复掩膜之后,对比修复前的图像进行修复效果评估。

训练

训练过程中,定义了一个采样器,在每一个epoch训练完成以后,用采样器对生成器进行采样并且保存样例图像

在20个epoch训练完成以后,生成的图像效果已经比较好,此时生成器和判别器的损失函数变化如图

修复

部分结果如下:

知识整理CSS

Posted on 2019-06-01 | In 前端 , css

CSS选择器

标签:p{}
class: .class{}
id:#id {}
同一标签,多个类:p.class1{} .class2{
集体选择器:p,.class1,#id1 {}
后代选择器(选择子孙代):p em a {}
子代选择器(只能选择子代):div > p
相邻选择:div + p
通配符选择:*
否定选择:not(.link) {}
属性选择器:[title] {}
伪类选择::link {}
链接伪类 ``:link``:未访问的链接 ``:visited``:已访问的链接 ``:hover``:鼠标悬停状态 ``:active``:鼠标点击到松开的阶段 (hover和active可用于任何标签)
伪元素选择:::before {}

权重

  • !important 优先级最高,但也会被权重高的important所覆盖
  • 行内样式总会覆盖外部样式表的任何样式(除了!important)
  • 如果两个相同权重的选择器作用在同一元素上:以后面出现的选择器为最后规则,以与元素距离近的选择器为最后规则

一句话总结: !important > 行内样式 > ID选择器 > (类选择器 | 属性选择器 | 伪类选择器 ) > 元素选择器 | 伪元素选择弃 > *

css3 属性选择器

选择器 描述
[attribute] 用于选取带有指定属性的元素。
[attribute=value] 用于选取带有指定属性和值的元素。
[attribute~=value] 用于选取属性值中包含指定词汇的元素。
`[attribute =value]` 用于选取带有以指定值开头的属性值的元素,该值必须是整个单词。
[attribute^=value] 匹配属性值以指定值开头的每个元素。
[attribute$=value] 匹配属性值以指定值结尾的每个元素。
[attribute*=value] 匹配属性值中包含指定值的每个元素。

伪类和伪元素区别

伪类值一种状态,用于选择DOM树之外的信息,或是不能用简单选择器进行表示的信息。前者包含那些匹配指定状态的元素,比如:visited,:active;
伪类将特殊的效果添加到特定选择器上。它是已有元素上添加类别的,不会产生新的元素。例如:

a:hover {color: #FF00FF}
p:first-child {color: red}

伪元素是DOM树没有定义的虚拟元素,是一个真实存在的元素,他可以有样式有内容
伪元素在内容元素的前后插入额外的元素或样式,但是这些元素实际上并不在文档中生成。它们只在外部显示可见例如:

p::before {content:"第一章:";}
p::after {content:"Hot!";}
p::first-line {background:red;}
p::first-letter {font-size:30px;}

换句话说伪类和伪元素的区别就是伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档树以外的元素。

浏览器解析CSS

.wrapper div > p CSS中,浏览器查找元素是通过选择权从后往前找的, 这样做的目的是加快CSS解析速度,从后往前,排除法

盒子模型

盒模型有两种, W3C标准盒子模型、IE 怪异盒子模型;

盒模型是由: 内容(content)、内边距(padding)、边框(border)、外边距(margin) 组成的。

标准模型的宽高是指的content区宽高; IE盒模型的宽高是指的content+padding+border的宽高。

  • 盒子模型类型 box-sizing: border-box | content-box
    • border-box:width的值为width=width
    • content-box:width的值为width=border+padding+content
  • height:长度/百分比/auto
  • width:
  • border边框
    • 边框粗细border-(top/l/r/bottom)-width: thin/medium/thick/长度值
    • 边框颜色 border-color:
    • 样式border-style: none/solid实线/dotted点状
    • 简写: 粗细-样式-颜色
  • padding内边距 主要用来设置空隙 盒子与边框的距离
    • padding粗细padding-(top/l/r/bottom): thin/medium/thick/长度值
    • padding粗细简写:全/上下 左右/上 左右 下/上 右 下 左
  • margin外边距 边框与外界的距离
    • 可以为负值
    • 设置为auto:实现水平方向居中

bfc

W3C对BFC定义:

浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。

BFC(Block formatting context)直译为”块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

BFC作用:

  • 利用BFC避免外边距折叠
  • 清除内部浮动 (撑开高度)
  • 原理: 触发父div的BFC属性,使下面的子div都处在父div的同一个BFC区域之内
  • 避免文字环绕
  • 分属于不同的BFC时,可以阻止margin重叠
  • 多列布局中使用BFC

如何生成BFC:(脱离文档流,满足下列的任意一个或多个条件即可)

  • 根元素,即HTML元素(最大的一个BFC)
  • float的值不为none
  • position的值为absolute或fixed
  • overflow的值不为visible(默认值。内容不会被修剪,会呈现在元素框之外)
  • display的值为inline-block、table-cell、table-caption

非布局样式

文字粗细:font-weight: normal/bold
文字斜度:font-style: normal/italic/oblique
文字粗细:font-weight: 600
字重(粗体)font-weight
斜体 font-style
下划线 text-decoration
指针 cursor

滚动

  • visible 滚动条隐藏, 文字超出显示
  • hidden 滚动条隐藏, 文字超出不显示
  • scroll 滚动条一直显示,无论文字是否够多
  • auto 滚动条自动隐藏

文本对齐方式

文本水平对齐方式:text-align: left/right/center/justify
左对齐/右对齐/居中对齐/两端对齐 只对块级元素有效

行高

首行缩进:text-indent: 2em
行高:line-height: 120em 最好用em防止字体过大导致显示不全
注意:图片是按照inline元素做的排版,会涉及字体对齐,默认按照baseline对齐,和底线有空隙。 为了删除这个空隙,可以直接vertical-align: bottom或者display: block

行高的构成

行高是由 line-box 组成的
line-box 是由一行里的 inline-box 组成的
inline-box中最高的那个,或字体最大的拿个决定行高

你对 line-height 是如何理解的?

  • line-height 指一行字的高度,包含了字间距,实际上是下一行基线到上一行基线距离
  • 如果一个标签没有定义 height 属性,那么其最终表现的高度是由 line-height 决定的
  • 一个容器没有设置高度,那么撑开容器高度的是 line-height 而不是容器内的文字内容
  • 把 line-height 值设置为 height 一样大小的值可以实现单行文字的垂直居中
  • line-height 和 height 都能撑开一个高度,height 会触发 haslayout(一个低版本IE的东西),而 line-height 不会

line-height 三种赋值方式有何区别?(带单位、纯数字、百分比)

  • 带单位:px 是固定值,而 em 会参考父元素 font-size 值计算自身的行高
  • 纯数字:会把比例传递给后代。例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px
  • 百分比:将计算后的值传递给后代

浮动

  • 可以让行内元素形成块级元素
  • 元素”浮动”
  • 脱离文档流
  • 不脱离文本流
  • 位置尽量靠上,并靠左或右
  • 脱离文档流,只能左右 float:left/right/none
  • 对自己的影响
    • 形成”块”(BFC)
    • 这个块会负责自己的布局,宽高由自己决定。比如 span 中用 float 这个span就形成了一个BFC,就可以设置宽高了
  • 浮动后出现的问题:
    • 浮动溢出(高度塌陷)
  • 解决:清除浮动

    • clear:none/left/right/both
    • 1.给父元素添加overflow:hidden 使父元素变成一个bfc,同时需要父元素指定宽度
    • 2.css3 clearfix :after 使用伪元素

        .clearfloat:after{
           display:block;
           clear:both;
           content:"";
           visibility:hidden;
           height:0}
       .clearfloat{zoom:1}
      
    • 3.结尾添加一个空行

        <div class="parent">
        <div class="left">Left</div>
        <div class="right">Right</div>
        <div class="clearfloat"></div>
      </div>
      <style>
        .left {float:left}
        .clearfloat{clear:both}
      </style>
      
      

inline-block的间隙

两个并列的inline-block中间会有一条裂缝,这个的原因是两个标签之间有空格,浏览器把这些空格当成文字中空格,所以这两个块中间多少有间隙。

解决办法:

  1. 删除两个标签间的空格,但是这样html排版不好
  2. 容器元素font-size: 0 然后再在里面再重新设置字体大小

元素内容的垂直方式

只对行内元素有效
vertical-align: sub/supper/文字向上向下对齐

单行文本溢出显示省略号

  • overflow: hidden;
  • text-overflow: ellipsis;
  • white-space: no-wrap;

多行文本溢出显示省略号

  • overflow: hidden;
  • text-overflow: ellipsis;
  • display: -webkit-box;
  • -webkit-line-clamp: 3;
  • -webkit-box-orient: vertical;

display属性

将元素显示为内联元素: inline
将元素显示为块级元素: block
将元素显示为内联元素具有快级属性可以设置宽高: inline-block
inherit 规定应该从父元素继承 display 属性的值
none 此元素将显示为块级元素,此元素前后会带有换行符。
list-item 象块类型元素一样显示,并添加样式列表标记。
table 此元素会作为块级表格来显示

ps:宽高设为100%,表示和父元素相同

display: none; 与 visibility: hidden; 的区别

结构:

  • display:none
    • 会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击
  • visibility: hidden
    • 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击
  • opacity: 0
    • 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击

继承

  • display: none和opacity: 0
    • 非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。
  • visibility: hidden
    • 继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式。

性能

  • display:none
    • 修改元素会造成文档回流。读屏器不会读取display: none元素内容,性能消耗较大
  • visibility:hidden
    • 修改元素只会造成本元素的重绘,性能消耗较少。读屏器读取visibility: hidden元素内容
  • opacity: 0
    • 修改元素会造成重绘,性能消耗较少

相同点: 它们都能让元素不可见、他们都依然可以被 JS 所获取到

CSS预处理器

  • 嵌套
    • 反映层级和约束
  • 变量和计算
    • 减少冗余代码
  • entend和mixin
    • 代码片段重用
    • mixin是直接把CSS代码每个地方重复写一份
    • extend是使用逗号分割的选择器来为多个不同的地方使用同一段CSS
  • 循环
    • 适用于复杂有规律的样式
  • import
    • CSS模块化
  • 常见三种css预处理器:sass less stylus

CSS单位

  1. px 绝对单位。传统上一个像素对应于计算机屏幕上的一个点,而对于高清屏则对应更多。

  2. % 父元素宽度的比例。

    • 如果对 html 元素设置 font-size 为百分比值,则是以浏览器默认的字体大小16px为参照计算的(所有浏览器的默认字体大小都为 16px),如62.5%即等于10px(62.5% * 16px = 10px)。
  3. em 相对单位。 不同的属性有不同的参照值。

    • 对于字体大小属性(font-size)来说,em 的计算方式是相对于父元素的字体大小
    • border, width, height, padding, margin, line-height)在这些属性中,使用em单位的计算方式是参照该元素的 font-size,1em 等于该元素设置的字体大小。同理如果该元素没有设置,则一直向父级元素查找,直到找到,如果都没有设置大小,则使用浏览器默认的字体大小。
  4. rem 是相对于根元素 html 的 font-size 来计算的,所以其参照物是固定的。

    • 好处:rem 只需要修改 html 的 font-size 值即可达到全部的修改,即所谓的牵一发而动全身。
  5. vw, vh, vmin, vmax 相对单位,是基于视窗大小(浏览器用来显示内容的区域大小)来计算的。

    • vw:基于视窗的宽度计算,1vw 等于视窗宽度的百分之一
    • vh:基于视窗的高度计算,1vh 等于视窗高度的百分之一
    • vmin:基于vw和vh中的最小值来计算,1vmin 等于最小值的百分之一
    • vmax:基于vw和vh中的最大值来计算,1vmax 等于最大值的百分之一

CSS 优化、提高性能的方法有哪些?

  • 多个 css 合并,尽量减少 HTTP 请求
  • css 雪碧图
  • 抽象提取公共样式,减少代码量
  • 选择器优化嵌套,尽量避免层级过深 (用‘>’替换‘ ’)
  • 属性值为 0 时,不加单位
  • 压缩CSS代码
  • 避免使用 CSS 表达式
    • 它们要计算成千上万次并且可能会对你页面的性能产生影响。

position 定位模型

  • static:常规流 忽略跑偏移量(忽略 top, bottom, left, right - z-index 声明)
  • inherit 规定从父元素继承 position 属性的值
  • relative:
    • 相对相对于其正常位置进行定位。设置偏移量 top/bottom/left/right:10px
    • 常规流的位置会留下,不会影响其他元素;也就是如果因为它的移动空出来了区域,其他的元素不会填充
  • absolute:绝对定位
    • 相对于值不为 static 的第一个父元素进行定位。
    • 常规流的位置会被占据,会影响其他元素;也就是如果因为它的移动空出来了区域,其他的元素会填充
    • 如果设置上下左右偏移量为0,margin:autoauto,子元素就会相对于父元素居中
  • 常用: 父元素设置为relative,子元素设置为absolute,子元素就可以设置相对于父元素的偏移量
  • fixed:相对定位
    • 相对于浏览器窗口进行定位。不会随着视图滚动而滚动,其余和absolute一样
  • 后三者可以设置z-index

DOM层级顺序与z-index

DOM层级顺序,大概来说就是DOM节点在z轴方向(垂直于屏幕向外的方向)的显示优先级。为了调整DOM层级顺序,我们想到的往往就是用CSS的z-index属性来控制。
dom层级顺序规则:

  1. 顺序规则
    • 在不设置position属性(或设置成static)的情况下,文档流后面的DOM节点会覆盖前面的DOM节点。
  2. 定位规则
    • 定位节点(position属性设置为relative,absolute或fixed的节点)会覆盖非定位节点(不设置position属性或position属性设为static的节点)
  3. 参与规则
    • z-index属性仅对定位节点生效。(使用position的节点)
    • 有三个DOM节点,其定位为static。但是A的z-index最大,但是依旧是在最底部,C的z-index最小,而在最顶部,因此可知z-index并未生效,此时为顺序规则在生效。
  4. 默认值规则
    • z-index设为0和没有设置z-index的节点在同一层级内没有高低之分。在IE6和7种,z-index的默认值为0,其他浏览器中默认值为auto。
  5. 从父规则
    • 两个节点A和B都是定位节点,如果节点A的z-index值比节点B的大,那么节点A的子元素都会覆盖在节点B以及节点B的子节点上。

link 与 @import 的区别

  • link 属于 XHTML 标签,除了加载 CSS 外,还能用于定义 RSS, 定义 rel 连接属性等作用;而@import 是 CSS 提供的,只能用于加载 CSS;
  • 页面被加载的时,link 会同时被加载,而@import 引用的 CSS 会等到页面被加载完再加载;
  • import 是 CSS2.1 提出的,只在 IE5 以上才能被识别,而 link 是 XHTML 标签,无兼容问题;
  • link 支持使用 js 控制 DOM 去改变样式,而@import 不支持;

CSS 有哪些继承属性

  • 关于文字排版的属性如:
    • font
    • word-break
    • letter-spacing
    • text-align
    • text-rendering
    • word-spacing
    • white-space
    • text-indent
    • text-transform
    • text-shadow
  • line-height
  • color
  • visibility
  • cursor

CSS3新特性

  • 新增的选择器:
    • 元素选择器
      • 子元素选择器:father > son1 {}
      • 相邻兄弟元素选择器:father > son1 + son2 {}
      • 通用兄弟选择器: father > son1 ~ son5 {}
      • 群组选择器: father > son1, father > son2, father > son3 {}
    • 属性选择器
      • a[href] {}
    • 伪类选择器
      • 动态伪类(之前有):
        • 锚点伪类 a:link{} a:visited{}
        • 用户行为伪类 :hover :active :focus
      • UI元素状态伪类
        • input:enabled {} :disabled :checked
    • 结构类选择器
      • first/last子类选择器section:fi<div class="a2">123 </div><div class="a2">123 </div><div class="a2">123 </div><div class="a2">123 </div>rst-child {}
      • 父元素的第N个子元素ul>li:nth-child(3){}
        • 选择多个: nth-child(n){}
  • 弹性盒模型 display: flex;
  • 边框与圆角
    • 圆角 border-radius:10px/10rem/10%
    • 盒阴影 box-shadow:水平偏移 垂直偏移 模糊 扩展 颜色
    • 边界图片 border-image:source
  • 文本
    • 文本阴影 text-shadow:h v blur color
    • 自动换行 word-break
    • 文本属性
  • 字体 @font-face
    • @font-face {font-familt:<name> src:<source> [<format>]}
  • transform 转换
    • 旋转transform:rotate(<angle>)
    • 平移trandform:translate(x,y)
      • trandform:translateX(200px)
      • trandform:translateY(200px)
    • 缩放:水平 垂直 都有
      • trandform:scaleX(.5)
    • 扭曲: 三种
      • skewX(<angle>)``
    • 3D transform
      • rotateX
      • translate3d(x,y,z)
      • scale3d(x,y,z) scaleZ(z)
  • 动画
    • transition 补间动画 两个状态
    • keyframe 关键帧动画 有很多状态
    • 逐帧动画 没有补间

如何水平/垂直居中一个元素?

  • 水平居中

    • 如果需要居中的元素为inline或inline-block,为父元素设置 text-align: center;即可实现

    • 如果要居中的元素为一个块级元素的话,一般使用 margin: 0 auto; 进行居中。

  • 垂直居中

    • 对于绝对定位元素,直接宽高减去一半

        #d1 {
          width: 100px;
          height: 100px;
          position: absolute;
          top: 50%;
          left: 50%;
          margin-left: -50px;
          margin-top: -50px;
          background: red
        }
      
    • 用css3的transform,无需知道宽高

          width: 100px;
        height: 100px;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate( -50%, -50%);
        background: red
      
    • 相对定位元素,先水平居中再垂直

li 与 li 之间有看不见的空白间隔是什么原因引起的?有什么解决办法?(也称幽灵字符)

行框的排列会受到中间空白(回车\空格)等的影响,因为空格也属于字符, 这些空白也会被应用样式,占据空间,所以会有间隔,把字符大小设为 0,就没有空格了

display:inline-block 什么时候会显示间隙?(携程)

  • 相邻的 inline-block 元素之间有换行或空格分隔的情况下会产生间距
  • 非 inline-block 水平元素设置为 inline-block 也会有水平间距
  • 可以借助 vertical-align:top; 消除垂直间隙
  • 可以在父级加 font-size:0; 在子元素里设置需要的字体大小,消除垂直间隙
  • 把 li 标签写到同一行可以消除垂直间隙,但代码可读性差

用纯 CSS 创建一个三角形的原理是什么?

把border的其他三条边设为透明 注意,这里要把 border-width 、border-style、 border-color 分开写。

.tri {
  width: 0px;
  height: 0;
  border-style: solid;
  border-width: 100px;
  border-color: transparent transparent red transparent;
}

常用布局方式

表格布局

    <table>   
        <tr>   
            <td class="left">left</td>   
            <td class="right">right</td>   
        </tr>      
    </table>

float+margin

    <style>
        .container {
            width: 500px;
            height: 500px;
        }
        .left {
            width: 100px;
            height: 100%;
            float: left;
            background: green;
        }
        .middle {
            margin-left: 100px; /*空出和左边width一样*/
            margin-right: 200px; /*空出和右边width一样*/
            background: #000
        }
        .right {
            height: 100%;
            width: 200px;
            float: right;
            background: yellow;
        }
    </style>

    <div class="container">
        <div class="left">left</div>
        <div class="right">right</div>  <!--先写right,right写在最后会因为float上靠-->
        <div class="middle">middle</div>
    </div>

inline-block

  • 像文本一样排block元素
  • 问题:中间有间隙:
    • 解决方法:把父元素字体大小设为0,并在子元素中设置字体大小
    <style>
        .container {
            width: 500px;
            height: 500px;
        }
        .left {
            width: 100px;
            height: 100%;
            display: inline-block;
            background: green;
        }
        .right {
            height: 100%;
            width: 200px;
            display: inline-block;
            background: yellow;
        }
    </style>

    <div class="container">
        <div class="left">left</div>
        <div class="right">right</div> 
    </div>

flexbox

参考

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

  • 弹性盒子的属性:

  • flex-direction:属性决定主轴的方向(即项目的排列方向)。

    • row(默认值):主轴为水平方向,起点在左端。
    • row-reverse:主轴为水平方向,起点在右端。
    • column:主轴为垂直方向,起点在上沿。
    • column-reverse:主轴为垂直方向,起点在下沿。
  • flex-wrap: 定义,如果一条轴线排不下,如何换行。
    • nowrap(默认):不换行。
    • wrap:换行,第一行在上方。
    • wrap-reverse:换行,第一行在下方。
  • flex-flow: flex-direction属性和flex-wrap属性的简写形式
  • justify-content: 定义了项目在主轴上的对齐方式。
    • flex-start(默认值):左对齐
    • flex-end:右对齐
    • center: 居中
    • space-between:两端对齐,项目之间的间隔都相等。
    • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
  • align-items: 定义项目在交叉轴上如何对齐。
    • flex-start:交叉轴的起点对齐。
    • flex-end:交叉轴的终点对齐。
    • center:交叉轴的中点对齐。
    • baseline: 项目的第一行文字的基线对齐。
    • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
  • align-content: 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

    • flex-start:与交叉轴的起点对齐。
    • flex-end:与交叉轴的终点对齐。
    • center:与交叉轴的中点对齐。
    • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
    • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
    • stretch(默认值):轴线占满整个交叉轴。
  • 项目的属性

  • order:定义项目的排列顺序。数值越小,排列越靠前,默认为0。
  • flex-grow:定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
  • flex-shrink:定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
  • flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
  • flex:是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto
  • align-self:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch
    <style>
        .a1 {
            display: flex;
            height:100px;
            width: 500px;
            background: #000
        }
        .a2 {
            flex: 1;
            background: red
        }
    </style>

    <div class="a1">
        <div class="a2">123
        </div>
    </div>

响应式设计和布局

  • 响应式设计就是网站能够兼容多个不同大小的终端,而不是为每个终端做一个特定的版本
  • 基本原理是利用 CSS3 媒体查询,为不同尺寸的设备适配不同样式
  • 对于低版本的 IE,可采用 JS 获取屏幕宽度,然后通过监听window.onresize 方法来实现兼容
  • 主要考虑屏幕大小
  • 主要方法:
    • 隐藏:隐藏导航栏等不重要的东西
    • 折行:pc端一行显示多个的在移动端一行显示少一些
    • 自适应空间:多留出自适应空间
  • 方式:

    • rem:通过html的字体大小确定元素大小
      • html默认的样式字体大小为16px,1rem=16px,不同屏幕在mediaquery中改html的字体大小即
    • viewport:在meta中手工确定屏幕大小content="width=320"
    • 媒体查询:为不同屏幕写样式

        @media (max-width: 640px) {
            .left{display: none} /*为移动端隐藏样式*/
        }
      

请列举几种隐藏元素的方法

  • visibility: hidden; 这个属性只是简单的隐藏某个元素,但是元素占用的空间任然存在
  • opacity: 0; CSS3 属性,设置 0 可以使一个元素完全透明
  • position: absolute; 设置一个很大的 left 负值定位,使元素定位在可见区域之外
  • display: none; 元素会变得不可见,并且不会再占用文档的空间。
  • transform: scale(0); 将一个元素设置为缩放无限小,元素将不可见,元素原来所在的位置将被保留
  • HTML5 属性,效果和 display:none;相同,但这个属性用于记录一个元素的状态
  • height: 0; 将元素高度设为 0 ,并消除边框
  • filter: blur(0); CSS3 属性,将一个元素的模糊度设置为 0

css 属性 content 有什么作用?

content 属性专门应用在 before/after 伪元素上,用于插入额外内容或样式

元素竖向的百分比设定是相对于容器的高度吗?

元素竖向的百分比设定是相对于容器的宽度,而不是高度

a 标签上四个伪类的使用顺序是怎么样的?

link > visited > hover > active 简称 lvha(love-ha)

伪类的特殊性(应用优先级)是同样的,所以后出现的伪类会覆盖先出现的伪类(同时激活)

在这里,比如把hover放在active后面,那么实际你在激活(active)链接的时候就触发了hover伪类,hover在后面覆盖了active的颜色,所以始终无法看到active的颜色

设置元素浮动后,该元素的 display 值会如何变化?

设置元素浮动后,该元素的 display 值自动变成 block

请解释 CSS sprites,以及你要如何在页面或

  • CSS Sprites 其实就是把网页中一些背景图片整合到一张图片文件中,再利用 CSS 的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position 可以用数字能精确的定位出背景图片的位置。
  • CSS Sprites 为一些大型的网站节约了带宽,让提高了用户的加载速度和用户体验,不需要加载更多的图片。

margin叠加几种情况

margin叠加的意思是:当两个或者更多的margin相遇时,它们将形成一个外边距,这个外边距的高度等于两个发生叠加的外边距中高度较大者。

  1. 当一个元素出现在另一个元素上面时,第一个元素的底边外边距与第二个元素的顶边外边距发生叠加。如图:

  2. 一个元素在另一个元素中时,它们的顶边距和低边距也会发生叠加

  3. 果一个元素是空元素(即一个元素没有内容,内边距和边框),这种情况外边距的顶边距和低边距碰在一起也会发生叠加

  4. 在上面那种空元素的情况,如果该空元素与另一个元素的外边距碰在一起,也会发生叠加。

以上4种外边距叠加情况只会发生在普通文档流的垂直方向。行内框、浮动框、绝对定位框之间的外边距不会发生叠加,同样水平方向也不会发生叠加。

水平居中和垂直居中

css问题

  • css优先级
    • 权重:id>class>tag
    • !important: 最高
    • 内联样式高
    • 后写的优先级高
  • 伪类和伪元素的区别
    • 伪类表状态 hoover等
    • 伪元素是真的元素 before after 在页面中会显示
    • 前者单冒号 后者双冒号
  • 实现两栏(三栏)布局的方法
    • 表格布局
    • float+margin 清楚浮动
    • inline-block 处理间隙
    • flexbox 兼容性差
  • absolute和fix有什么区别
    • absolute相对于最近的absolute/relative来定位
    • fix相对于屏幕/viewport定位
  • inlineblock为什么有间隙
    • 空白字符
    • 解决:消灭字符;父元素字体设为0
  • 清除浮动
    • 为什么有浮动:浮动的元素不会占据父元素的布局空间,父元素不会管浮动元素,所以可能会高度塌陷
    • 清除:给父元素加定高宽;父元素加overflowhidden;给父元素加:after{clearboth};最后加一行空行clearboth
  • 如何适配移动端页面
    • viewport
    • rem/viewport/media query
    • 设计上:隐藏/折行/自适应
      visibility: hidden;
      display: block;
      font-size: 0;
      content: “ “;
      clear: both;
      height: 0;

Alexnet图像分类

Posted on 2019-05-22 | In machine learning , cnn

github链接:https://github.com/tedqin/Alexnet_Imagenet

背景

  • 概述

    • Alexnet是Hinton小组在ImageNet图像处理大赛ISVRC2012中使用的神经网络模型,并获得了第一名,测试错误率相比往年的第一名都有大幅度的提升,top5测试错误率是15.3%,第二名是26.2%。Alexnet有60M个参数,650,000个神经元,5个卷积层和3个全连接层(1000类的softmax分类器)。Alexnet模型由Alex Krizhevsky 等人在两个GTX 580 3GB GPU上训练5、6天左右得到。目前是深度学习图像处理领域当中最常用的模型之一。
      AlexNet相比于以前的一些网络模型来说,做出了很多创新,主要包括以下几点
  • 框架

    • 使用激活函数ReLu
    • 多GPU并行训练
    • 局部影响标准化
    • 重叠池化

模型结构

Alexnet有5个卷积层和3个全连接层,并且Alex发现移除任意一层都会降低最终的效果。网络结构如图

这个网络前面5层是卷积层,后面三层是全连接层,最终softmax输出是1000类。

  • 第三卷积层用384个33256的卷积核,得到1313192*2的卷积层。
  • 第四卷积层用384个33192的卷积核,得到1313192*2的卷积层。
  • 第五卷积层用256个33192的卷积核,得到1313128*2的卷积层。
    每个全连接层有4096个神经元。

总体而言,Alexnet网络的结构如下:

数据集

测试

caffe提供的预训练模型一共包括了1000类图像,涵盖了生物、天文、自然、科技等多个方面的相关图像,具体在caffe_classes.py下,由于文件本身较大就没放在github上,可以很容易在网上找到
测试集包括1000张图像,共200类,标签存储在lable.txt当中。取测试图像概率最大类的下标作为测试的分类结果(即top-1测试),并且与label对比,最后计算得出整个测试集得precision在75%左右,算是比较好的结果。

总结

AlexNet可以说是深度神经网络的鼻祖,相比于后来的VGG和googlenet而言,它的构造更加简单,而且结构也已经非常的成熟和稳固。
作为学校的大创项目用alexnet有点蠢,但是时间紧迫,也分享下自己学习cnn的过程。

learningJS

Posted on 2018-12-13 | In 前端 , javascript
output is the best input,以下每一项都可以单独写一篇文章

javascript

  • 原型、原型链
  • 闭包
  • es6的新特性
  • 作用域

    • 全局和局部环境
    • var let const的区别
  • ajax xhr

  • this 箭头函数
  • 事件绑定、监听、委托、代理
  • 继承
  • 常用数组方法
  • defer和async
  • 虚拟dom

html

  • html的语义标签
  • html5新特性
  • canvas

css

  • bootstrap

dom

  • 定位元素的几种方法
  • 遍历

浏览器

  • 渲染和绘制
  • 兼容性
  • 布局

模块化

  • webpack

性能优化

c++tips笔记

Posted on 2018-10-18 | In cpp

指针

*

    • 是取值运算符,对地址使用可以获得地址中储存的数值。对于指针a,*a表示取a中的值
  • 在 定义 时, 是一个标识符,声明该变量是一个指针,比如说int p; 那p就是一个指向int型的指针
  • 在 调用 时, p是指针p指向的那个变量,比如说之前有int a=5;int p=&a;那么p的值是a的地址,也就是指针p指向a, p则等于a的值,即p=5。

&

  • &在 定义 时则是引用,比如说有定义int a=5;再定义int b=&a;那么这里的b则引用a的值,即b=5,而再给b赋值:b=10,a的值也会变为10。
  • &在 调用 是地址运算符,对变量使用可以获得该变量的地址, 对于变量b,&b表示取b的地址

example

  • 先定义有int x = 0;int *p = &x;
  • 若定义函数: void fun1(int a){ a=5;} ,则调用:fun1(x); 之后,x还等于0;因为fun1函数只改变了形参a的值,a只是fun1函数里的局部变量,调用fun1(x)相当于是“a=x;a=5;”,x没变;
  • 若定义函数:void fun2(int &a){ a=5;} , 则调用:fun2(x); 之后,x等于5;因为这里的a引用了x的值;
  • 若定义函数:void fun3(int a){ a=5;} , 则调用:fun3(p); 之后,x也等于5;因为fun3函数的参数a是一个指针,相当于a=p; a则与 p指向同一地址,改变 a即改变p即x
  • return *this:

strcpy和strncpy:

strcpy(char *ch1, char *ch2):

  • 直接将ch2指向的由”\0”结束的字符串复制到ch1,ch1必须有足够的空间来存储ch2
  • 若ch2长于ch1,还是会复制,但是ch1会溢出
    *

strncpy(char *ch1, char *ch2, n):

  • 将ch2中最多n个字符复制到ch1
  • 如果n>ch1长度,ch1溢出
  • 如果n<ch1长度,且如果
    • ch2长度<=ch1长度,则ch2前n个字符复制到ch1
    • ch2长度>ch1长度,出错
  • 建议:将n设置为ch1长度

mac常用指令

Posted on 2018-10-10 | In 基础知识

ps: * 指令名称 指令 实例

参考:https://www.jianshu.com/p/8803bf591956

基本指令

目录操作

  • 创建目录 mkdir mkdir dirname
  • 删除目录 rmdir rmdir dirname
  • 移动或重命名一个目录 mvdir mvdir dir1 dir2
  • 改变当前目录 rmdir rmdir dirname
  • 显示当前目录的路径名 pwd pwd
  • 显示当前目录的内容 ls ls -la

文件操作

  • 显示文件内容或连接文件 cat cat filename
  • 显示非文本文件的内容 od od -c filename
  • 复制文件或目录 cp cp file1 file2
  • 删除文件或目录 rm rm filename
  • 改变文件名或所在目录 mv mv file1 file2
  • 使用匹配表达式查找文件 find find . -name "*.c" -print
  • 显示文件类型 file file filename

选择操作

  • 显示文件的最初几行 head head -20 filename
  • 显示文件的最后几行 tail tail -15 filename
  • 显示文件每行中的某些域 cut cut -f1,7 -d: /etc/passwd
  • 从标准输入中删除若干列 colrm colrm 8 20 file2
  • 排序或归并文件 sort sort -d -f -u file1
  • 去掉文件中的重复行 uniq uniq file1 file2
  • 显示两有序文件的公共和非公共行 comm comm file1 file2
  • 统计文件的字符数、词数和行数 wc wc filename
  • 给文件加上行号 nl nl file1 >file2

进程操作

  • 显示进程当前状态 ps ps u
  • 终止进程 kill kill -9 30142

时间操作

  • 显示系统的当前日期和时间 diff diff file1 file2
  • 显示⽇日历 cal cal 8 1996
  • 统计程序的执⾏行行时间 time time a.out

网络与通信操作

  • 远程登录 telnet telnet hpc.sp.net.edu.cn
  • 远程登录 rlogin rlogin hostname -l username
  • 在远程主机执⾏行行指定命令 rsh rsh f01n03 date
  • 在本地主机与远程主机之间传输⽂文件 ftp ftp[ftp.sp.net.edu.cn]
  • 在本地主机与远程主机之间复制⽂文件 rcp rcp[ftp.sp.net.edu.cn]
  • 给⼀一个⽹网络主机发送 回应请求 ping ping hpc.sp.net.edu.cn
  • 阅读和发送电⼦子邮件 mail mail
  • 允许或拒绝接收报⽂文 mesg mesg n

core shell 指令

  • 列列出最近执⾏行行过的⼏条命令及编号 history history
  • 重复执⾏行行最近执⾏过的某条命令 r r-2
  • 给某个命令定义别名 alias alias del=rm -i
  • 取消对某个别名的定义 diff diff file1 file2
  • 比较并显示两个文件的差异 unalias unalias del

其它命令

  • 显示操作系统的有关信息 uname uname -a
  • 清除屏幕或窗⼝口内容 clear clear
  • 显示当前所有设置过的环境变量量 env env
  • 列列出当前登录的所有⽤用户 who who
  • 显示当前正进⾏行行操作的⽤用户名 whoami whoami
  • 显示终端或伪终端的名称 tty tty
  • 显示或重置控制键定义 stty stty -a
  • 查询磁盘使⽤用情况 du du -k subdirdf
  • 显示⽂文件系统的总空间和可⽤用空间 /tmp
  • 显示当前系统活动的总信息 w
  • 在本地主机与远程主机之间复制⽂文件 rcp rcp[ftp.sp.net.edu.cn]
  • 给⼀一个⽹网络主机发送 回应请求 ping

sudo命令

  • 临时使⽤用root权限来编辑/etc/shadow密码⽂文件 sudo gedit /etc/shadow
  • 注意$和#的变化,#表示你在最⾼高权限root⾥里里⾯面

hexo搭建blog常用命令

Posted on 2018-10-10 | In blog , hexo

常规搭建

常规指令

hexo new "blogname" #新建博客

hexo g #生成

hexo s #启动服务器预览

hexo d #部署

hexo clean #清除缓存

更换设备搭建

参考:https://www.zhihu.com/question/21193762/answer/103097754

  • 打开git bash,在用户主目录下运行:

ssh-keygen -t rsa -C "youremail@example.com"

把其中的邮件地址换成自己的邮件地址,然后一路回车

  • 最后完成后,会在用户主目录下生成.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH key密钥对,id_rsa是私钥,千万不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

  • 登陆GitHub,打开「Settings」->「SSH and GPG keys」,然后点击「new SSH key」,填上任意Title,在Key文本框里粘贴公钥id_rsa.pub文件的内容(千万不要粘贴成私钥了!),最后点击「Add SSH Key」,你就应该看到已经添加的Key。
    注意:不要在git版本库中运行ssh,然后又将它提交,这样就把密码泄露出去了。

  • 下载Node.js,并安装.
  • 打开git bash客户端,输入 npm install hexo-cli -g,开始安装hexo
  • 下面就将原来的文件拷贝到新电脑中,但是要注意哪些文件是必须的,哪些文件是可以删除的。

          1)讨论下哪些文件是必须拷贝的:首先是之前自己修改的文
          件,像站点配置_config.yml,theme文件夹里面的主题,
          以及source里面自己写的博客文件,这些肯定要拷贝的。除
          此之外,还有
          三个文件需要有,就是scaffolds文件夹(文章的模板)、
          package.json(说明使用哪些包)和.gitignore(限定在
          提交的时候哪些文件可以忽略)。其实,这三个文件不是我们
          修改的,所以即使丢失了,也没有关系,我们可以建立一个新
          的文件夹,然后在里面执行hexo init,就会生成这三个文
          件,我们只需要将它们拷贝过来使用即可。总结:
          _config.yml,theme/,source/,scaffolds/,
          package.json,.gitignore,是需要拷贝的。
    

     

          (2)再讨论下哪些文件是不必拷贝的,或者说可以删除的:
          首先是.git文件,无论是在站点根目录下,还是主题目录下
          的.git文件,都可以删掉。然后是文件夹
          node_modules(在用npm install会重新生成),
          public(这个在用hexo g时会重新生成),.deploy_git
          文件夹(在使用hexo d时也会重新生成),db.json文件。
          其实上面这些文件也就是.gitignore文件里面记载的可以忽
          略的内容。总结:.git/,node_modules/,
          public/,.deploy_git/,db.json文件需要删除。
    
  • 在git bash中切换目录到新拷贝的文件夹里,使用 npm install 命令,进行模块安装。很明显我们这里没用hexo init初始化,因为有的文件我们已经拷贝生成过来了,所以不必用hexo init去整体初始化,如果不慎在此时用了hexo init,则站点的配置文件_config.yml里面内容会被清空使用默认值,所以这一步一定要慎重,不要用hexo init。

  • 安装其他的一些必要组件,如果在node_modules里面有的,就不要重复安装了:

      (1)为了使用hexo d来部署到git上,需要安装
    

    npm install hexo-deployer-git --save

      (2)为了建立RSS订阅,需要安装
    

    npm install hexo-generator-feed --save

      (3)为了建立站点地图,需要安装
    

    npm install hexo-generator-sitemap --save

    插件安装后,有的需要对配置文件_config.yml进行配置,具体怎么配置,可以参考上面插件在github主页上的具体说明

  • 使用hexo g,然后使用hexo d进行部署,如果都没有出错,就转移成功了!

用CNN实现深度生成对抗网络GAN

Posted on 2018-09-10 | In machine learning , gan

GAN

生成对抗网络(Generative Adversarial Network,GAN)是近几年很热门的一种深度学习神经网络模型,是目前在复杂分布上进行无监督学习最前沿的模型之一,这个概念由Ian Goodfellow和Yoshua Bengio等人在2014年提出,GAN的核心思想源自博弈论,它通过构造生成器(Generator)和判别器(Discriminator)在训练过程中互相博弈学习,最终得到理想的结果。其中生成器的目的在于生成虚假的样本分布,判别器的目的在于判别出输入的样本是否真实。由于GAN模型“博弈”的这一特点,它已经开始被应用到语音和语言处理、电脑病毒监测、棋类比赛程序等问题的研究当中。另外,GAN最常用的领域还是图像处理和计算机视觉,进行图像生成,构成各种逼真的室内外场景。

GAN的基本模型

avatar

CNN实现GAN

GAN提出的是一种对抗模型的思想,而要实现它,目前流行的是使用感知器或者多层神经网络。而用CNN来实现,可以大大解决GAN难以训练和不够稳定的问题,并且可以提高生成样本的质量、收敛速度,以及拓展维度。
CNN实现的改进:

  • 去掉了G和D中的池化层(pooling layer),并用微步幅卷积替代,能够分别使得G和D的下采样和上采样效率更高。
  • 在G和D中使用批量规范化(Batch Normalization),通过将输入的每个样本单元标准化为0均值和单位方差来稳定学习,这有助于处理初始化不良导致的训练问题,也有助于梯度流向更深的网络层。
  • 去掉最后一层卷积层后面的全连接层(fully layer),将生成器和判别器直接相连,能够有效提高模型收敛速率。
  • 生成器中除了输出层采用Tanh激活函数,其余所有层都采用ReLU激活函数。
  • 判别器中所有层都采用Leaky ReLU激活函数。

模型设计

生成器模型

生成器的网络由4层卷积层构成

  • 第1层:卷积核大小为5”×” 5,步长2,“same”填充,深度512,输出样本尺寸8”×” 8,生成函数ReLU
  • 第2层:卷积核大小为5”×” 5,步长2,“same”填充,深度256,输出样本尺寸16”×” 16,生成函数ReLU
  • 第3层:卷积核大小为5”×” 5,步长2,“same”填充,深度128,输出样本尺寸32”×” 32,生成函数ReLU
  • 第4层:卷积核大小为5”×” 5,步长2,“same”填充,深度3,输出样本尺寸64”×” 64,生成函数Tanh

判别器模型

判别器的4层卷积层具体如下:

  • 第1层:卷积核大小为5”×” 5,步长2,“same”填充,深度64,输出样本尺寸32”×” 32,生成函数Leaky ReLU。
  • 第2层:卷积核大小为5”×” 5,步长2,“same”填充,深度128,输出样本尺寸16”×” 16,生成函数Leaky ReLU。
  • 第3层:卷积核大小为5”×” 5,步长2,“same”填充,深度256,输出样本尺寸8”×” 8,生成函数Leaky ReLU。
  • 第4层:卷积核大小为5”×” 5,步长2,“same”填充,深度512,输出样本尺寸4”×” 4,生成函数Sigmoid。

构建模型

  • 构建生成器模型

    def generator(self, z):
    self.z_, self.h0_w, self.h0_b = linear(z, self.gf_dim84*4,

                                         'g_h0_lin', with_w=True)
    

    self.h0 = tf.reshape(self.z_, [-1, 4, 4, self.gf_dim * 8])
    h0 = tf.nn.relu(self.g_bn0(self.h0))

//第1层微步幅卷积层
self.h1, self.h1_w, self.h1_b = conv2d_transpose(h0,[self.batch_size, 8, 8, self.gf_dim*4], name=’g_h1’, with_w=True)
h1 = tf.nn.relu(self.g_bn1(self.h1))

//第2层微步幅卷积层
h2, self.h2_w, self.h2_b = conv2d_transpose(h1,
[self.batch_size, 16, 16, self.gf_dim*2], name=’g_h2’, with_w=True)
h2 = tf.nn.relu(self.g_bn2(h2))

//第3层微步幅卷积层
h3, self.h3_w, self.h3_b = conv2d_transpose(h2,
[self.batch_size, 32, 32, self.gf_dim*1], name=’g_h3’, with_w=True)
h3 = tf.nn.relu(self.g_bn3(h3))

//第4层微步幅卷积层,4层微步幅卷积后,矩阵维度变为(64, 64, 3)
h4, self.h4_w, self.h4_b = conv2d_transpose(h3,
[self.batch_size, 64, 64, 3], name=’g_h4’, with_w=True)
return tf.nn.tanh(h4)

  • 构建判别器模型

    def discriminator(self, image, reuse=False):
    //第1层卷积
    h0 = lrelu(conv2d(image, self.df_dim, name=’d_h0_conv’))

//第2层卷积
h1 = lrelu(self.d_bn1(conv2d(h0, self.df_dim*2, name=’d_h1_conv’)))

//第3层卷积
h2 = lrelu(self.d_bn2(conv2d(h1, self.df_dim*4, name=’d_h2_conv’)))

//第4层卷积
h3 = lrelu(self.d_bn3(conv2d(h2, self.df_dim*8, name=’d_h3_conv’)))
h4 = linear(tf.reshape(h3, [-1, 8192]), 1, ‘d_h3_lin’)
return tf.nn.sigmoid(h4), h4

  • 构建优化器

    //判别器优化器,最小化损失函数
    d_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1) \
                  .minimize(self.d_loss, var_list=self.d_vars)
    
    //判别器优化器,最小化损失函数
    g_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1) \
                  .minimize(self.g_loss, var_list=self.g_vars)
    

123
Ted Qin

Ted Qin

Output is the best input

22 posts
13 categories
12 tags
GitHub DouBan ZhiHu
© 2017 - 2019 Ted Qin