zoukankan      html  css  js  c++  java
  • 插件及工具相关,前端性能优化,原生通信,算法相关

    1. babel和polyfill

    • Babel: Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码。注意:Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API
    • Polyfill: Polyfill的准确意思为,用于实现浏览器并不支持的原生API的代码。

    2. jpg, jpeg和png区别

    • jpg是jpeg的缩写, 二者一致
    • PNG就是为取代GIF而生的, 无损压缩, 占用内存多
    • jpg牺牲图片质量, 有损, 占用内存小
    • PNG格式可编辑。如图片中有字体等,可利用PS再做更改。JPG格式不可编辑

    3. git rebase和merge区别

    8.png

    9.png

    前端性能优化

    1. 减少HTTP请求(合并css、js,雪碧图/base64图片)
    2. 压缩(css、js、图片皆可压缩,使用webpack uglify和 svg)
    3. 样式表放头部,脚本放底部
    4. 使用CDN(这部分,不少前端都不用考虑,负责发布的兄弟可能会负责搞好)
    5. http缓存
    6. bosify图片压缩: 根据具体情况修改图片后缀或格式 后端根据格式来判断存储原图还是缩略图
    7. 懒加载, 预加载
    8. 替代方案: 骨架屏, SSR
    9. webpack优化

    原生通信

    1.JSBridge通信原理, 有哪几种实现的方式?

    JsBridge给JavaScript提供了调用Native功能,Native也能够操控JavaScript。这样前端部分就可以方便使用地理位置、摄像头以及登录支付等Native能力啦。JSBridge构建 Native和非Native间消息通信的通道,而且是 双向通信的通道。

    • JS 向 Native 发送消息 : 调用相关功能、通知 Native 当前 JS 的相关状态等。
    • Native 向 JS 发送消息 : 回溯调用结果、消息推送、通知 JS 当前 Native 的状态等。

    2.实现一个简单的 JSBridge,设计思路?

    算法相关

    1. 二分查找和冒泡排序

    • 二分查找: 递归(分左右, 传递start,end参数)和非递归(使用while(l < h))
    • 冒泡排序: 两个for循环

    2. 快速排序

    function quickSort (arr) {
      if (arr.length < 2) return arr
      var middle = Math.floor(arr.length / 2)
      var flag = arr.splice(middle, 1)[0]
      var left = [],
            right = []
      for (var i = 0; i < arr.length; i++) {
        if (arr[i] < flag) {
          left.push(arr[i])
        } else {
          right.push(arr[i])
        }
      }
      return quickSort(left).concat([flag], quickSort(right))
    }

    3. 最长公共子串

    function findSubStr(str1, str2) {
            if (str1.length > str2.length) {
              [str1, str2] = [str2, str1]
            }
            var result = ''
            var len = str1.length
            for (var j = len; j > 0; j--) {
              for (var i = 0; i < len - j; i++) {
                result = str1.substr(i, j)
                if (str2.includes(result)) return result
              }
            }
     }
       console.log(findSubStr('aabbcc11', 'ppooiiuubcc123'))

    4. 最长公共子序列(LCS动态规划)

    // dp[i][j] 计算去最大长度,记住口诀:相等左上角加一,不等取上或左最大值
    function LCS(str1, str2){
            var rows =  str1.split("")
            rows.unshift("")
            var cols =  str2.split("")
            cols.unshift("")
            var m = rows.length 
            var n = cols.length 
            var dp = []
            for(var i = 0; i < m; i++){ 
                dp[i] = []
                for(var j = 0; j < n; j++){ 
                    if(i === 0 || j === 0){
                        dp[i][j] = 0
                        continue
                    }
    
                    if(rows[i] === cols[j]){ 
                        dp[i][j] = dp[i-1][j-1] + 1 //对角+1
                    }else{
                        dp[i][j] = Math.max( dp[i-1][j], dp[i][j-1]) //对左边,上边取最大
                    }
                }
                console.log(dp[i].join(""))//调试
            } 
            return dp[i-1][j-1]
        }
    //!!!如果它来自左上角加一,则是子序列,否则向左或上回退。
    //findValue过程,其实就是和 就是把T[i][j]的计算反过来。
    // 求最长子序列
    function findValue(input1,input2,n1,n2,T){
        var i = n1-1,j=n2-1;
        var result = [];//结果保存在数组中
        console.log(i);
        console.log(j);
        while(i>0 && j>0){
            if(input1[i] == input2[j]){
                result.unshift(input1[i]);
                i--;
                j--;
            }else{
                //向左或向上回退
                if(T[i-1][j]>T[i][j-1]){
                    //向上回退
                    i--;
                }else{
                    //向左回退
                    j--;
                }
            }
    
        }
    
        console.log(result);
    }

    5. 数组去重,多种方法

    • 双for循环, splice剔除并i--回退
    • indexOf等于index
    • filter indexOf === index
    • 新数组indexOf === index
    • 使用空对象等

    6. 实现一个函数功能:sum(1,2,3,4..n)转化为 sum(1)(2)(3)(4)…(n)

    // 使用柯里化 + 递归
    function curry ( fn ) {
      var c = (...arg) => (fn.length === arg.length) ? 
              fn (...arg) : (...arg1) => c(...arg, ...arg1)
      return c
    }

    7. 反转二叉树

    var invertTree = function (root) {
      if (root !== null) {
        [root.left, root.right] = [root.right, root.left]
        invertTree(root.left)
        invertTree(root.right)
      }
      return root
    }

    8. 贪心算法解决背包问题

    var items = ['A','B','C','D']
    var values = [50,220,60,60]
    var weights = [5,20,10,12]
    var capacity = 32 //背包容积
    
    greedy(values, weights, capacity) // 320
    
    function greedy(values, weights, capacity) {
            var result = 0
            var rest = capacity
            var sortArray = []
            var num = 0
            values.forEach((v, i) => {
              sortArray.push({
                value: v,
                weight: weights[i],
                ratio: v / weights[i]
              })
            })
            sortArray.sort((a, b) => b.ratio - a.ratio)
            sortArray.forEach((v, i) => {
              num = parseInt(rest / v.weight)
              rest -= num * v.weight
              result += num * v.value
            })
            return result
          }

    9. 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

    function FindNumbersWithSum(array, sum)
    {
        var index = 0
        for (var i = 0; i < array.length - 1 && array[i] < sum / 2; i++) {
            for (var j = i + 1; j < array.length; j++) {
                if (array[i] + array[j] === sum) return [array[i], array[j]]
            }
            //index = array.indexOf(sum - array[i], i + 1)
           // if (index !== -1) {
           //     return [array[i], array[index]]
            //}
        }
        return []

    10. 二叉树各种(层序)遍历

    深度广度遍历

    // 根据前序和中序重建二叉树
    /* function TreeNode(x) {
        this.val = x;
        this.left = null;
        this.right = null;
    } */
    function reConstructBinaryTree(pre, vin)
    {
        var result = null
        if (pre.length === 1) {
            result = {
                val: pre[0],
                left: null,
                right: null
            }
        } else if (pre.length > 1) {
            var root = pre[0]
            var vinRootIndex = vin.indexOf(root)
            var vinLeft = vin.slice(0, vinRootIndex)
            var vinRight = vin.slice(vinRootIndex + 1, vin.length)
            pre.shift()
            var preLeft = pre.slice(0, vinLeft.length)
            var preRight = pre.slice(vinLeft.length, pre.length)
            result = {
                val: root,
                left: reConstructBinaryTree(preLeft, vinLeft),
                right: reConstructBinaryTree(preRight, vinRight)
            }
        }
        return result
    }
    
    // 递归
    // 前序遍历
    function prevTraverse (node) {
      if (node === null) return;
    
      console.log(node.data);
      prevTraverse(node.left);
      prevTraverse(node.right);
    }
    
    // 中序遍历
    function middleTraverse (node) {
      if (node === null) return;
    
      middleTraverse(node.left);
      console.log(node.data);
      middleTraverse(node.right);
    }
    
    // 后序遍历
    function lastTraverse (node) {
      if (node === null) return;
    
      lastTraverse(node.left);
      lastTraverse(node.right);
      console.log(node.data);
    }
    
    // 非递归
    // 前序遍历
    function preTraverse(tree) {
            var arr = [],
              node = null
            arr.unshift(tree)
            while (arr.length) {
              node = arr.shift()
              console.log(node.root)
              if (node.right) arr.unshift(node.right)
              if (node.left) arr.unshift(node.left)
            }
          }
    
    // 中序遍历
    function middleTraverseUnRecursion (root) {
      let arr = [],
          node = root;
    
      while (arr.length !== 0 || node !== null) {
        if (node === null) {
          node = arr.shift();
          console.log(node.data);
          node = node.right;
        } else {
          arr.unshift(node);
          node = node.left;
        }
      }
    
    }
    
    // 广度优先-层序遍历
    // 递归
    var result = []
    var stack = [tree]
    var count = 0
    var bfs = function () {
      var node = stack[count]
      if (node) {
        result.push(node.value)
        if (node.left) stack.push(node.left)
        if (node.right) stack.push(node.right)
        count++
        bfs()
      }
    }
    bfs()
    console.log(result)
    // 非递归
    function bfs (node) {
      var result = []
      var queue = []
      queue.push(node)
      while (queue.length) {
        node = queue.shift()
        result.push(node.value)
        node.left && queue.push(node.left)
        node.right && queue.push(node.right)
      }
      return result
    }

    11. 各种排序

    // 插入排序
    function insertSort(arr) {
            var temp
            for (var i = 1; i < arr.length; i++) {
              temp = arr[i]
              for (var j = i; j > 0 && temp < arr[j - 1]; j--) {
                arr[j] = arr[j - 1]
              }
              arr[j] = temp
            }
            return arr
          }
          console.log(insertSort([3, 1, 8, 2, 5]))
    
    // 归并排序
    function mergeSort(array) {
            var result = array.slice(0)
            function sort(array) {
              var length = array.length
              var mid = Math.floor(length * 0.5)
              var left = array.slice(0, mid)
              var right = array.slice(mid, length)
              if (length === 1) return array
              return merge(sort(left), sort(right))
            }
            function merge(left, right) {
              var result = []
    
              while (left.length || right.length) {
                if (left.length && right.length) {
                  if (left[0] < right[0]) {
                    result.push(left.shift())
                  } else {
                    result.push(right.shift())
                  }
                } else if (left.length) {
                  result.push(left.shift())
                } else {
                  result.push(right.shift())
                }
              }
              return result
            }
            return sort(result)
          }
          console.log(mergeSort([5, 2, 8, 3, 6]))
    
    // 二分插入排序
    function twoSort(array) {
            var len = array.length,
              i,
              j,
              tmp,
              low,
              high,
              mid,
              result
            result = array.slice(0)
            for (i = 1; i < len; i++) {
              tmp = result[i]
              low = 0
              high = i - 1
              while (low <= high) {
                mid = parseInt((high + low) / 2, 10)
                if (tmp < result[mid]) {
                  high = mid - 1
                } else {
                  low = mid + 1
                }
              }
              for (j = i - 1; j >= high + 1; j--) {
                result[j + 1] = result[j]
              }
              result[j + 1] = tmp
            }
            return result
          }
          console.log(twoSort([4, 1, 7, 2, 5]))

    12. 使用尾递归对斐波那契优化

    递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。

    // 传统递归斐波那契, 会造成超时或溢出
    function Fibonacci (n) {
      if ( n <= 1 ) {return 1};
    
      return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
    
    Fibonacci(10) // 89
    Fibonacci(100) // 超时
    Fibonacci(500) // 超时
    
    // 使用尾递归优化, 可规避风险
    function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
      if( n <= 1 ) {return ac2};
    
      return Fibonacci2 (n - 1, ac2, ac1 + ac2);
    }
    
    Fibonacci2(100) // 573147844013817200000
    Fibonacci2(1000) // 7.0330367711422765e+208
    Fibonacci2(10000) // Infinity

    13. 两个升序数组合并为一个升序数组

    function sort (A, B) {
      var i = 0, j = 0, p = 0, m = A.length, n = B.length, C = []
      while (i < m || j < n) {
        if (i < m && j < n) {
          C[p++] = A[i] < B[j] ? A[i++] : B[j++]
        } else if (i < m) {
          C[p++] = A[i++]
        } else {
          C[p++] = B[j++]
        }
      }
      return C
    }
  • 相关阅读:
    IT开发者对Mac钟爱
    POJ 3486 &amp; HDU 1913 Computers(dp)
    基础排序算法
    LeetCode 70:Climbing Stairs
    Qt自己定义事件实现及子线程向主线程传送事件消息
    maven自己主动编译,解决你每次代码改动须要又一次编译的繁琐
    Unity定制 Image、Text的对象生成
    iOS学习4_UITableView的使用
    GTK+重拾--09 GTK+中的组件(一)
    Architecting Android…The clean way?
  • 原文地址:https://www.cnblogs.com/wuxu-dl/p/14434476.html
Copyright © 2011-2022 走看看