功能_功能图 - CSDN
  • Vue项目一些功能封装

    千次阅读 2020-08-16 11:47:57
    Vue项目中一些功能封装 src/utils/index.js // 返回context父实例componentName const findUpwardComponent = (context, componentName) => { let parent = context.$parent let name = parent.$options.name ...

    判断微信浏览器

    getWxClient() {
          // 判断微信环境
          var isMobile = /Android|webOS|iPhone|iPod|BlackBerry/i.test(
            navigator.userAgent
          )
          var ua = navigator.userAgent.toLowerCase()
          var isWx = !!/micromessenger/.test(ua)
          return isMobile && isWx
        },
    
    getWxClient() // 如果是返回true 不是返回false
    

    微信环境下禁止分享

    document.addEventListener('WeixinJSBridgeReady', (onBridgeReady) => {
       // 通过下面这个API隐藏右上角按钮
       // eslint-disable-next-line no-undef
       WeixinJSBridge.call('hideOptionMenu')
     })
    

    判断是否PC客户端

    export const isPC = () => {
      var userAgentInfo = navigator.userAgent;
      var Agents = ["Android", "iPhone",
        "SymbianOS", "Windows Phone",
        "iPad", "iPod"];
      var flag = true;
      for (var v = 0; v < Agents.length; v++) {
        if (userAgentInfo.indexOf(Agents[v]) > 0) {
          flag = false;
          break;
        }
      }
      return flag;
    }
    
    isPC() // 如果是返回true 不是返回false
    

    获取当前时间 (2020-03-28)

    getTime() {
      let date = new Date()
      let year = date.getFullYear()
      let month = date.getMonth() + 1
      let strDate = date.getDate()
      if (month >= 1 && month <= 9) {
        month = '0' + month
      }
      if (strDate >= 0 && strDate <= 9) {
        strDate = '0' + strDate
      }
      let currentdate = `${year}-${month}-${strDate}`
      return currentdate
    }
    
    // getTime() // 2020-03-28
    

    获取当前时间(“2020-08-16 11:35:06”)

    fixedTime(val) {
          return val < 10 ? '0' + val : val
        },
        getFormatDate() {
          var date = new Date()
          var currentDate = date.getFullYear() + '-' + this.fixedTime(date.getMonth() + 1) + '-' + this.fixedTime(date.getDate()) + ' ' + this.fixedTime(date.getHours()) + ':' + this.fixedTime(date.getMinutes()) + ':' + this.fixedTime(date.getSeconds())
          return currentDate
        },
    

    出生日期计算年龄 24Y5M

    getAge(‘1995-07-08’) 返回24Y5M

    export const getAge = (str) => {
    // str = '1995-07-08'
      var r = str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/);
      if (r == null) return false
      var d = new Date(r[1], r[3] - 1, r[4])
      if (d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4]) {
        var date = new Date()
        var Y = date.getFullYear() - r[1]
        var M = date.getMonth() + 1 - r[3]
        var D = date.getDate()
        if (parseInt(D) - parseInt(r[4]) < 0) {
          M--;
          if (M < 0) {
            Y--
            M = 11
          }
        }
        if (M < 0) {
          Y--
          M = 11
        }
        return (Y + "Y" + M + "M")
      }
    }
    
    getAge('1995-07-08') // "24Y5M"(即24周岁5个月)
    

    根据生日返回周岁(24)

    	// this.getAge(1995-07-08)  返回24  (2020-03-23)
        getAge(birthday) {
          // birthday = 1995-07-08
          var returnAge
          var birthdayArr = birthday.split('-')
          var birthYear = birthdayArr[0]
          var birthMonth = birthdayArr[1]
          var birthDay = birthdayArr[2]
          var d = new Date()
          var nowYear = d.getFullYear()
          var nowMonth = d.getMonth() + 1
          var nowDay = d.getDate()
          // 这里用了 === 号 要把类型都转为数字
          if (+nowYear === +birthYear) {
            returnAge = 0// 同年 则为0周岁
          } else {
            var ageDiff = nowYear - birthYear // 年之差
            if (ageDiff > 0) {
            // 这里用了 === 号 要把类型都转为数字
              if (+nowMonth === +birthMonth) {
                var dayDiff = nowDay - birthDay// 日之差
                if (dayDiff < 0) {
                  returnAge = ageDiff - 1
                } else {
                  returnAge = ageDiff
                }
              } else {
                var monthDiff = nowMonth - birthMonth// 月之差
                if (monthDiff < 0) {
                  returnAge = ageDiff - 1
                } else {
                  returnAge = ageDiff
                }
              }
            } else {
              returnAge = -1// 返回-1 表示出生日期输入错误 晚于今天
            }
          }
          return returnAge// 返回周岁年龄
        }
    

    获取保险生效日期、截止日期

        getTime() {
          // 获取保险生效日期 截止日期
          let date = new Date()
          let year = +date.getFullYear()
          let month = +date.getMonth() + 1 // getMonth()返回值是 0(一月) 到 11(十二月) 之间的一个整数
          let strDate = +date.getDate()
          let maxDate
          maxDate = new Date(year, month, 0).getDate()
          if (strDate + 1 > maxDate) {
            month += 1
            strDate = 1
            if (month > 12) {
              year++
              month = 1
              strDate = 31
            }
          } else {
            strDate += 1
          }
          // 个位数+0
          if (strDate > 0 && strDate <= 9) {
            strDate = '0' + strDate
          }
          if (month > 0 && month <= 9) {
            month = '0' + month
          }
          this.startDate = `${year}-${month}-${strDate}`
          if (+strDate === 1) {
            if (month === 1) {
              year--
              month = 12
              strDate = 31
            } else {
              month--
              strDate = new Date(year, month, 0).getDate()
            }
          } else {
            strDate--
          }
          year++
          // 个位数+0
          if (strDate > 0 && strDate <= 9) {
            strDate = '0' + +strDate
          }
          if (month > 0 && month <= 9) {
            month = '0' + +month
          }
          this.endDate = `${year}-${month}-${strDate}`
        }
    // getTime()  2020-04-07时调用
    // startDate = 2020-04-08
    // endDate = 2021-04-07
    

    数字每千位加逗号

    export const commafy = (num) => {
      return num && num.toString()
        .replace(/\d+/, function(s){
             return s.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
         })
    }
    
    commafy(19999999) // "19,999,999"
    

    手机号码中间四位隐藏星号显示

    export const hideMobile = (mobile) => {
      return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
    }
    
    hideMobile('13049997092') // "130****7092"
    

    获取URL链接参数

    根据参数名称获取参数值

    // name为参数名
    getUrlParam(name) {
        var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
        var result = window.location.search.substr(1).match(reg)
        return result ? decodeURIComponent(result[2]) : null
      }
    

    链接参数赋值到一个对象上

    const search = window.location.href.split('?')[1].split('&')
     search.forEach(item => {
       this.userInfo[item.split('=')[0]] = decodeURI(item.split('=')[1])
     })
    

    设置cookie

    // 设置指定cookie
    // name:cookie名称    value对应cookie的值    iDay有效期天数 如7表示7天
    export const setCookie = (name, value, iDay) => {
      let oDate = new Date()
      if (iDay) {
        oDate.setDate(oDate.getDate() + iDay)
      } else {
        console.log('iDay:' + iDay)
        oDate = iDay
      }
      // 域名domain=.ybj.com   .表示前面可以匹配所有   77.ybj.com 或者 75.ybj.com等都可以获取到该cookie
      document.cookie = `${name}=${value};expires=${oDate};domain=.ybj.com;path=/`
    }
    

    获取指定cookie

    // name:cookie名称
    export const getCookie = (name) => {
      let arr1 = document.cookie.split('; ')
      let i = 0;
      for (i = 0; i < arr1.length; i++) {
        var arr2 = arr1[i].split('=')
        if (arr2[0] == name) {
          return arr2[1]
        }
      }
      return ''
    }
    

    findUpwardComponent () 返回父组件

    findBrotherComponents() 返回兄弟组件

    findDownwardComponent() 返回子组件

    validator() 注册表单验证

    src/utils/index.js

    // 返回context父实例componentName
    import Validator from './validator'
    const findUpwardComponent = (context, componentName) => {
      let parent = context.$parent
      let name = parent.$options.name
      while (parent && (!name || !name.includes(componentName))) {
        parent = parent.$parent
        if (parent) name = parent.$options.name
      }
      return parent
    }
    // 返回context的兄弟实例componentName
    const findBrotherComponents = (ctx, componentName, exceptMe = true) => {
      const $brothers = ctx.$parent.$children.filter(item => {
        return item.$options.name && item.$options.name.includes(componentName)
      })
      const index = $brothers.findIndex(item => item._uid === ctx._uid)
      if (exceptMe && index > -1) $brothers.splice(index, 1)
      return $brothers
    }
    // 返回context的子实例componentName
    const findDownwardComponent = (context, componentName) => {
      const $children = context.$children
      let bean = null
      if ($children.length) {
        for (const child of $children) {
          const name = child.$options.name
          if (name && name.includes(componentName)) {
            bean = child
            break
          } else {
            bean = findDownwardComponent(child, componentName)
            if (bean) break
          }
        }
      }
      return bean
    }
    // 注册表单验证
    const validator = (rules, form) => {
      try {
        Object.keys(rules).forEach(key => {
          const value = rules[key]
          value.pattern.split('&').forEach((pattern, index) => {
            const result = new Validator({
              value: form[key],
              pattern,
              message: value.message.split('&')[index]
            }).test()
            if (!result.valid) {
              throw new Error(result.message)
            }
          })
        })
        return true
      } catch (e) {
        toast.info(e.message)
      }
    }
    
    
    export {
    	findUpwardComponent,
    	findBrotherComponents,
    	findDownwardComponent,
    	validator
    }
    

    src/utils/validator.js

    /* eslint-disable */
    export default class Validator {
      constructor(model) {
        this.value = model.value
        this.pattern = model.pattern
        this.message = model.message || '验证失败'
        this.valid = true
        this.init()
      }
      init() {
        switch (this.pattern) {
          case 'mobile':
            this.pattern = /^0?((13[0-9])|(14[0-9])|(15([0-3]|[5-9]))|(166)|(18[0-9])|(17[0-9])|(19[8-9]))[0-9]{8}$/
            break
          case 'idcard':
            this.pattern = /^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9X]$/
            break
          case 'name':
            this.pattern = /^[A-Za-z_\-\u4e00-\u9fa5]{2,20}$/
            break
          case 'email':
            this.pattern = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
            break
          case 'birthday':
            this.pattern = /^[1-9]\d{3}([-|\/|\.])?((0\d)|([1-9])|(1[0-2]))\1(([0|1|2]\d)|([1-9])|3[0-1])$/
            break
          case 'required':
            this.pattern = cb => {
              this.value ? cb() : cb(this.message)
            }
            break
          default:
            break
        }
      }
      callback(message) {
        this.valid = !message
        this.message = message
      }
      test() {
        if (typeof this.pattern === 'function') {
          this.pattern(this.callback.bind(this))
        } else {
          this.valid = this.value ? this.pattern.test(this.value) : true
        }
        return { valid: this.valid, message: this.valid ? undefined : this.message }
      }
    }
    
    

    调用

    import {findUpwardComponent, findBrotherComponents, findDownwardComponent} from '@/utils/index'
    console.log(findDownwardComponent(this, 'layer_0003'))
    

    也可以这样调用

    import * as utils from '@/utils/index'
    console.log(utils.findDownwardComponent(this, 'layer'))
    // utils.findDownwardComponent(this, 'layer') 相当于 当先实例的子实例layer 里面的this
    // 也相当于通过$refs.layer获取到的一样
    
    
    // 表单验证规则
    let fields = [
          {
            label: '姓名',
            prop: 'name',
            other: { placeholder: '', sex: { visible: 1, type: 0, text: '男/女' } }
          },
          {
            label: '生日',
            prop: 'birthday',
            other: { placeholder: '', maxAge: 50, minAge: 20, defaultAge: 30 }
          },
          {
            label: '手机',
            prop: 'mobile',
            other: {
              placeholder: '',
              captcha: { type: 0, activityId: '', callback: { type: 'none' } }
            }
          },
          {
            label: '协议',
            prop: 'agreecCall',
            other: {
              autoCheck: 1,
              autoCheckAfterFinish: 1,
              type: 0,
              company: '',
              product: '',
              text:
                '我已知晓并许可太平保险专线致电我沟通赠险领取事宜及<b>《服务协议》</b>'
            }
          }
        ]
    const rules = fields.reduce((rules, field) => {
            if (field.prop === 'name') {
              rules.name = { pattern: 'required&name', message: `请输入您的${field.label}&姓名格式错误` }
              field.other.sex.visible === 1 && (rules.sex = { 'pattern': 'required', 'message': '请选择性别' })
            } else if (field.prop === 'birthday') {
              rules.birthday = { pattern: 'required&birthday', message: `请选择您的${field.label}&生日格式错误` }
            } else if (field.prop === 'mobile') {
              rules.mobile = { pattern: 'required&mobile', message: `请输入您的${field.label}&手机号码格式错误` }
              field.other.captcha.type === 1 && (rules.mobileCode = { 'pattern': 'required', 'message': '请输入验证码' })
            } else if (field.prop === 'agreecCall') {
              rules.agreecCall = { pattern: 'required', message: '请勾选服务协议' }
            } else if (field.prop === 'email') {
              rules.email = { pattern: 'required&email', message: `请输入您的${field.label}&邮箱格式错误` }
            } else if (field.other.type === 'input') {
              rules[field.prop] = { pattern: 'required', message: `请输入${field.label}` }
            } else if (['select', 'radio'].includes(field.other.type)) {
              rules[field.prop] = { pattern: 'required', message: `请选择${field.label}` }
            }
            return rules
          },{})
        
      const userInfo = {
      	agreecCall: 1
    	birthday: "1989-10-11"
    	id: "id"
    	mobile: "130****7092"
    	mobileCode: "943499"
    	name: "测试"
    	sex:}
    utils.validator(rules, userInfo) // 返回布尔值
      
    

    rulesObject
    在这里插入图片描述


    谢谢你阅读到了最后
    期待你,点赞、评论、交流

    展开全文
  • 简化功能点系列之一 什么是功能

    千次阅读 2019-02-10 10:03:54
    简化功能点系列之一 什么是功能
                   

    这是简化功能点系列的第一篇。

    目标

    功能点的目标,是估算工作量,进而估算成本和造价。

    俗话说:“店大欺客,客大欺店”,银行这么大的客遇上IBM这么大的店,会发生什么呢?那就是功能点。

    大约在1979年左右,IBM发布了对功能点的基本定义,后来随着业界的发展,逐渐成为当前唯一被广泛认可的软件规模度量标准。

    功能点最大的特点,就是它和工作量的比例关系很好(应该是,功能点就是为了这个目标而设置的,因此这个不是偶然)。

    什么是功能点

    和我们平时说的“功能点”不同的是,标准功能点(Function Point)是一个被严格定义的概念,不会因为估算人员差异产生显著差别。

    下面的图展示了功能点中的“计数单元”,就是可以被数为功能点的东西。


    内部逻辑文件ILF,就是用户的业务数据,类似于UML中的Entity,或者业务类Business Class,或者数据库中的某些“主表”。

    外部接口文件EIF,就是要访问的外部数据(注意不是外部系统,而是外部系统中的一个ILF)。

    外部输入EI,主要目的是使ILF数据变化的一种操作,简单说增删改都是EI;还有一种“使行为发生变化”的EI,如“开始杀毒”。

    外部查询EQ,主要目的是查看原始数据,比如查看流水帐,查看余额。

    外部输出输出,主要目的是查看计算和派生的数据,比如查看年度报表;还有一种是“穿越系统界面”的,比如打印。

    这些功能点的定义,核心是“客户可以理解并识别”,比如图中灰色的那些“数据”和“操作”,是客户看不到的,因此不能计算为功能点。

    在计数过程中,各种功能点标准都做了一些细节定义,防止出现错误估算的情况。比如:

    1. “查询”有很多条件,算几个?

    2. 输出之前要先输入(输入查询日期范围),算几个?

    3. 有的复杂有的简单,怎么数?

    ……等等,总之各种一望而知的和想都想不到的问题,都能找到依据(但有的依据很难掌握)。

    IFPUG曾有报告指出,若两个人经过了标准功能点的培训,那么这两个独立计数相差不到10%。

    功能点标准

    现在世界上有5个功能点的ISO标准(值得注意的是,除了功能点,没有任何其他比如代码行、故事点、用例点……形成标准),分别是 (下面是俗称):

    IFPUG(澳大利亚,最大的功能点组织),NESMA(荷兰,世界第二大功能点组织,代表欧洲),MarkII,COSMIC(能用到嵌入式),FiSMA(芬兰)。

    功能点有各种简化方法,但基本上都“与功能点兼容”,就是说借用了功能点的定义和数值。

    各种组织、咨询公司收集的功能点项目数据在5万左右(其中一家就达到2万多),粗略估计企业内部的功能点数据可能超过50万。

    每年还能看到各种功能点的对比数据报告,这个也是其他估算方法所不能比拟的。

    标准功能点的局限性

    尽管功能点是一种“与技术无关”的“只需要需求就能数的”东西,但却很难在某些场景中应用,比如:
    1. 功能点的复杂度依赖于某些细节,无法早期获得。
    具体包括字段数DETs、影响到的表的数量FTRs、字段的排列组合情况RETs等信息,而这些信息只有在很详细的界面设计和数据库设计出现后,才能计算清楚。
    比如那个RETs,我本人现在还搞不懂。我可是不但听过功能点课程,还翻译过国外的课程(PPT加口译,还仔细查阅了英文原文中的定义),还和外国讲师额外请教了很多,搭上了去颐和园划船的时间,还是不能给出严格区分的方法。

    2. 功能点的很多概念与日常需求分析和描述差别很大

    一个资深产品经理,本来需求写的好好的,也足以给测试人员写用例,给设计人员写设计,做出来的产品客户也很满意,就差一个估算和度量不太懂,于是他就参加标准功能点培训……突然,他就像小学生误入微积分课堂一样,听到一大堆完全陌生的词汇、定义和判断准则,感觉自己完全像一个基础为零的菜鸟一样。

    实际上,需求分析资深人士和外行学功能点的速度一样快……或者说,一样慢,因为前面的积累几乎用不上。


    之后的几篇博客,将会介绍如何以一种无为而治的方法,对已有的需求描述方法略作改进,就能从中自动计数功能点。

    一篇看似平淡无奇的Word文档(甚至里边全是标题不需要文字),可以在几秒钟后算出功能点数值;而多数项目(2人年以下的),几个小时就能做完。

               

    再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

    展开全文
  • Burp Suite功能简单介绍

    万次阅读 2016-03-03 23:25:25
    Burp Suite功能简单介绍,不是教程,新手可以看看

    Burp Suite功能简单介绍

    0x00 前言

    之前虽然一直在用burpsuite,但是从来没有系统的学习它的使用,而且我一般只使用3、4个功能,像是proxy、repeater、spider、intruder,最近把它系统的研究了一下各个功能,写个文章留存一下。
    要是有什么错误的地方希望大家批评指正。
    哦还要说一下,这篇文章不是教程,教程网上很多,这个就是把大部分主要的功能进行了介绍,对这款软件有一个系统的了解。越往后写的越少,确实因为时间关系,以后会加以补充,例如使用非常频繁的repeater功能,几句话就带过了。毕竟是软件,有个初步的了解,实践中就渐渐的就会熟悉了。
    这里我使用的是BurpSuite V1.6.27
    附上百度网盘链接:http://pan.baidu.com/s/1pKuCuU3
    提取密码:7a1v

    这里写图片描述

    0x01 target

    site map

    这个主要是由spider功能模块爬出对应网站的一个站点地图,这里我通过spider功能扒取本地的一个74cms做测试。具体的怎么爬出站点地图在稍后的spider进行介绍。
    这里写图片描述
    如图所示的,
    区块1就是扫描整个网站的站点地图
    区块2就是递交的请求情况
    区块3就是请求头和响应头的详细信息,包括源码,参数,头,16进制码。
    区块4就是该网站存在的问题,这个spider功能能够扫描出网站一些比较明显的问题,当然肯定不全面,参考意义不是很大,漏洞扫描器推荐awvs,这个最开始还是比较好用的,不过到后来就会发现其实很多漏洞根本扫不出来。
    区块5就是对应问题的详细信息以及解决方法。

    然后可以看出区块上面还有一个filter的功能,这也是一个比较强大的功能,稍后做介绍。

    scope

    然后是target下的scope栏目,
    这里写图片描述
    分别就是在范围的显示和在范围内的不显示,而且可以看出是支持正则表达式的,这里增删改就不做详述了,应该能自己看懂的。

    0x02 Proxy

    这个代理抓包功能应该是使用最频繁的功能之一了,原理就是通过把127.0.0.1设置为代理服务器,由本机发起的请求都会通过127.0.0.1,然后我们就可以把请求和响应包都截取下来。
    首先要在浏览器的设置里添加一个代理,以火狐浏览器为例,点击选项,如下图
    这里写图片描述
    这里我设置的ip和端口分别是127.0.0.1和8080端口,然后在proxy下的Options一栏如下操作
    这里写图片描述
    注意这里端口号一定要与浏览器设定的代理服务器端口号一致,如果8080被其他应用占用,可以将二者均换掉也无所谓。
    这样,所有浏览器发出的请求和接受的响应都会被burpsuite拦截(PS:最后记得将浏览器的代理服务器勾选为不使用代理,否则一旦buresuite关了就可能上不了网了)
    现在来介绍功能:

    intercept

    这里写图片描述
    截取到包如下图:
    这里写图片描述
    Forward:通俗来说就是将包发送出去
    Drop:丢弃掉包
    action的功能如下,也可以右键点击空白处
    这里写图片描述
    1-7分别对应到发送到最上方的七个模块
    其他的英文应该都能读懂,自己试试就知道了,都比较清晰的

    HTTP history

    这里写图片描述
    这个就是截取包的历史记录
    然后我们来看看这个filter功能
    这里写图片描述
    1、三项对应的是
    - 只显示范围内的网址,这个主要在前面站点地图那里设置scope时的筛选
    - 隐藏没有响应的记录
    - 只展示有请求参数的记录
    2、这里手动输入筛选条件可以支持正则、大小写敏感等
    3、根据MIME类型进行筛选
    4、展示和隐藏那些类型的请求记录
    5、根据响应的HTTP状态码来筛选
    6、显示评论过的和高亮的记录。注意,这里通过对记录点击右键是可以附加自己的评论或者是某一条记录以一种颜色高亮的。
    7、端口筛选

    Option

    这里我主要截图介绍了一些常用的设置,其他不常用的就自己看吧。
    这里写图片描述
    这里就主要是Proxy功能的设置。
    这里写图片描述
    上图主要是设置监听的接口信息,以及证书的导入
    这里写图片描述
    上图主要是抓包的显示设置,截取的包符合什么规则就显示出来或是符合什么规则就不显示。
    这里写图片描述
    上图主要是一些替换功能,
    就是将数据包中的数据批量替换,比如说我勾选了第一个,意思就是将截取的请求中的user-agent全部替换为User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)。
    就是一个批量替换的功能。

    0x03 Spider

    control

    要使用该功能就要先通过Proxy功能抓包,然后右键send to spider就行了,然后spider就开会运行,下图是运行结束后的情形
    这里写图片描述
    我圈起来的部分就是spider的主体部分,第一个就是总共发送的请求,第二个就是总共传输的字节,第三个是请求传输队列,上面有一个按键可以清空该队列,第四个是表单队列。
    同样,再往下是扒取设置,爬虫递交的请求需要符合什么规则才进行抓取,或是符合什么规则就不抓取,自己add几条规则然后对比一下就知道什么情况了。

    Options

    这里截取几个个人较为常用的,其他一般不做修改,需要使用的时候自己看就行了。
    这里写图片描述
    爬虫设置。
    检查robots.txt,探测响应为not found等等。
    下面的两个数字分别是最深的探测深度以及最多传递多少个参数。
    这里写图片描述
    表单的提交设置。这个非常重要,就是爬虫遇到表单的时候怎么提交,显示是三个单选框,第一个就是不提交,第二个就弹出框体来由我们自己来填写并提交,第三个就是按照表中我们预先设定的值进行提交。
    为什么说这个非常重要,因为表单和漏洞息息相关。。。
    这里写图片描述
    爬虫的引擎设置。
    1、同时运行的线程数
    2、如果失败了重试次数
    3、重试延迟
    一般来说都选用默认值,另外错误的话会最后的alert处显示出来,随时要关注。
    这里写图片描述

    0x04 scanner

    这个模块我用的不多,这里我也省略掉了,大家想学也是先由Proxy抓包然后点击右键do a active scan就可以了,然后其他的就自己探索吧。

    0x05 intruder

    定义通过添加字典(XSS,SQLI等等)来实现一个自动化的攻击或是密码爆破
    这里写图片描述

    Target

    一般来说我们使用intruder功能都是由Proxy然后send过来的,所以该栏目会默认填写的,当然也可以自己填,主要就是ip和端口号。

    position

    这里写图片描述
    就是对HTTP请求进行操作了,定义通过添加字典(XSS,SQLI等等)来实现自动化。这里就是定义我们所选用的字典替换请求中的哪一部分需要被替换。然后至于那个attack type有四种
    这里写图片描述
    1、sniper,就是将字典一次赋给我们的多个参数,比如我们有三个参数,分别是a,b,c,字典里面有五个值(1,2,3,4,5),那么该模式下我们会先把a用字典替换,b、c保持原值,然后b用字典替换,a、c保持原值,以此类推。
    2、battering ram,就是同时将a,b,c都用字典替换,例如a,b,c都用1替换,都用2替换。
    3、pitchfork,那就是需要我们导入三个字典,依次对应进行替换。
    4、cluster bomb,这个说起来比较麻烦,也是导入三个字典,就是比如a,b,c三个,原本应该有字典1替换a,字典2替换b,字典3替换c,然后它还会继续排列组合,比如字典1替换b,字典2替换c,字典3替换a,知道尝试完所有可能。
    这个可以自己试一试然后观看一下结果就知道各个模式的作用了。
    同样这个对一部分文本右键也是有很多功能,这里不做详述。

    payload

    这里写图片描述
    这里就是字典的导入,可以手动添加,也可以文件导入。
    第一个数字就是第几本字典,第二个就是选择模式,有很多种

    simple list:就是最简单的,手动输入或是文件导入都可以,可以导入多个字典。一般较少的数据使用该模式。
    runtime file:这个应该主要就是针对较大批量的数据的字典把。
    number:就是设置from 和to从多少到多少,然后step是间隔,例如from为1,to为100,step为2,那么payload就是1,3,5….
    brute forcer:暴力破解,尝试你定义字符的所有组合,可以设置最小和最大长度,纯暴力破解。

    接下来是payload Processing一栏,主要是对payload进行统一的规则设置,
    这里写图片描述
    例如统一都加上前缀或者后缀等等。
    然后payload encoding一栏就不说了。

    Options

    最后就是一些设置,和之前的差不太多,什么线程啊,失败重传啊等等之类不做想说了。

    当所有一切设置好之后
    这里写图片描述
    点击右上角start attack就可以开始了。

    0x06 Repeater

    一般使用这个功能也是通过Proxy抓包然后send过来的。
    主要就是修改请求的各项参数等等然后点击左上角的go发送出去,然后在右边接受到请求,请求和响应都可以以不同的形式展示出来。
    这里写图片描述

    0x07 Decoder

    编码解码功能,没有太多可说的,自己随便试试就知道了。

    0x08 Comparer

    主要是一个比较功能。
    - 可以在Proxy处截包发送过来进行比较
    - 也可以直接加载文件进行比较
    用法比较简单个人使用频率也很高。

    0x09 Alerts

    这里展示警告信息。一定要随时关注这里。
    一般来说就是比如爬虫的时候递交请求频率过快而被服务器拒绝访问等等之类的。

    展开全文
  • 什么是功能安全

    万次阅读 2018-07-06 10:04:57
    什么是功能安全(FS)?在现代工业控制领域中,可编程电子硬件、软件系统的大量使用,大大提升了自动化程度。但由于设备设计中的缺失,以及开发制造中风险管理意识的不足,这些存在设计缺陷的产品大量流入相关行业的...

    什么是功能安全(FS)?

    在现代工业控制领域中,可编程电子硬件、软件系统的大量使用,大大提升了自动化程度。但由于设备设计中的缺失,以及开发制造中风险管理意识的不足,这些存在设计缺陷的产品大量流入相关行业的安全控制系统中,已经造成了人身安全、财产损失和环境危害等灾难频出。为此,世界各国历来对石化过程安全控制系统、电厂安全控制系统、核电安全控制系全领域的产品安全性设计技术非常重视,并且将电子、电气及可编程电子安全控制系统相关的技术发展为一套成熟的产品安全设计技术,即“功能安全”技术。

    欧美已经颁布了成套的功能安全相关产品指令和设计标准,并深入到各个领域,如:汽车(ISO26262)轨道控制(EN 5012X)、核电(EN 61513)、工业装备及机器控制(EN 62601, EN ISO 13849-1/2)、过程控制(EN 61511)等,国际上,IEC 形成的 IEC 61508,IEC 61511 等系列标准已经逐步成为各国家、行业广泛认可的基本功能安全标准,中国也仿效并形成了的相应国家标准,其他行业性功能安全标准也在参照并将逐步形成为国家行业性标准。

    ISO26262    

    ISO26262是从电子、电气及可编程器件功能安全基本标准IEC61508派生出来的,主要定位在汽车行业中特定的电气器件、电子设备、可编程电子器件等专门用于汽车领域的部件,旨在提高汽车电子、电气产品功能安全的国际标准。

    ISO26262从2005年11月起正式开始制定,经历了大约6年左右的时间,已于2011年11月正式颁布,成为国际标准。中国也正在积极进行相应国标的制定。

    安全在将来的汽车研发中是关键要素之一,新的功能不仅用于辅助驾驶,也应用于车辆的动态控制和涉及到安全工程领域的主动安全系统。将来,这些功能的研发和集成必将加强安全系统研发过程的需求,同时,也为满足所有预期的安全目的提供证据。

    随着系统复杂性的提高,软件和机电设备的应用,来自系统失效和随机硬件失效的风险也日益增加,制定ISO 26262标准的目的是使得人们对安全相关功能有一个更好的理解,并尽可能明确地对它们进行解释,同时为避免这些风险提供了可行性的要求和流程。。

    ISO 26262为汽车安全提供了一个生命周期(管理、开发、生产、经营、服务、报废)理念,并在这些生命周期阶段中提供必要的支持。该标准涵盖功能性安全方面的整体开发过程(包括需求规划、设计、实施、集成、验证、确认和配置)。

    ISO 26262标准根据安全风险程度对系统或系统某组成部分确定划分由A到D的安全需求等级(Automotive Safety Integrity Level 汽车安全完整性等级ASIL),其中D级为最高等级,需要最苛刻的安全需求。伴随着ASIL等级的增加,针对系统硬件和软件开发流程的要求也随之增强。对系统供应商而言,除了需要满足现有的高质量要求外还必须满足这些因为安全等级增加而提出的更高的要求。


    应用     

    系统安全可以从大量的安全措施中获得,包括各种技术的应用(如:机械,液压,气动,电力,电子,可编程电子元件)。尽管ISO26262是相关于E/E系统的,但它仍然提供了基于其他相关技术的安全相关系统的框架。

    ISO26262:

    -提供了汽车生命周期(管理,研发,生产,运行,服务,拆解)和生命周期中必要的改装活动。

    -提供了决定风险等级的具体风险评估方法(汽车安全综合等级,ASILs)

    -使用ASILs方法来确定获得可接受的残余风险的必要安全要求。

    -提供了确保获得足够的和可接受的安全等级的有效性和确定性措施。

    功能安全受研发过程(包括具体要求,设计,执行,整合,验证,有效性和配置),生产过程和服务流程以及管理流程的影响。

    安全事件总是和通常的功能和质量相关的研发活动及产品伴随在一起。ISO26262强调了研发活动和产品的安全相关方面。

    ISO26262主要用于安装在最大毛重不超过3.5吨的乘用车上的一个或多个E/E系统的安全相关系统。ISO26262唯一不适用于为残疾人设计的特殊目的车辆的E/E系统。系统研发早于ISO26262出版日期的,也不在标准的要求之内。ISO26262表述了由E/E安全相关系统,包括这些系统的互相影响,故障导致的可能的危险行为,不包括电击,火灾,热,辐射,有毒物质,可燃物质,反应物质,腐蚀性物质,能量释放及类似的危险,除非这些危险是由于E/E安全相关系统故障导致的。


    行各业都会制定标准,指导未来发展并限定最低准入门槛。在汽车电子行业,这一标准就是ISO 26262,它将功能安全定义为:

    “避免因电气/电子系统故障而导致的不合理风险”。

    不同领域的标准并不完全一致,例如针对电气和电子系统的IEC 61508以及飞行器电子硬件的DO-254都有各自的定义方式。更需值得注意的是,它们都拥有专用术语,并提供了包括目标参数在内的工程研发指导。因此,开始产品研发前确定目标市场并制定合适的流程至关重要,因为中途修改研发流程必然会导致效率低下。图1展示了硅片IP的不同应用标准。实际操作中,如果需要满足多套标准,则可以求同存异,先列出专属需求,再执行质量管理等通用准则;最一开始就要做到安全第一。

    什么是功能安全?汽车功能安全的设计方案

    图1:硅片IP的功能安全标准

    实际操作中,功能安全系统必须由独立评估员认证,符合所有安全标准。实现功能安全需要具备预测能力的故障模式,实时判断系统状态是功能完整,部分功能损坏,还是系统必须关闭进行重启或重置。

    并不是所有故障都会立刻引发严重事故。比如,汽车动力转向系统故障可能会导致突发性的错误转向,但是由于电气和机械设计天然的时间延迟,故障并不会马上产生后果,这一延迟通常是几毫秒以上,ISO 26262将之定义为容错时间间隔,间隔长短取决于潜在的事故类型和系统设计。所以,不难理解,对系统安全要求越高,产生不安全事件的故障就越应该避免。

    理想情况下,功能安全不会影响系统性能;但现实生活中,现行的许多安全措施都会严重影响系统性能、功率和面积(PPA)。如何在保证功能安全的前提下减轻对系统性能的不利影响以及设计制造成本的上升,是设计师们面临的一大难题。

    为什么需要功能安全?

    芯片IP的功能安全曾是非常小众的领域,只有少数汽车、工业、航空航天和其他类似市场的芯片与系统开发商感兴趣。然而,随着过去几年各类汽车应用的兴起,情况已经发生巨大变化。除了汽车外,还有很多其他行业也能从电子器件的增加受益,当然保障功能安全是大前提。医疗电子和航空就是两个典型例子。

    自动驾驶过去几年吸引了不少人的眼球,但一直是雾里看花;如今,随着高级驾驶辅助系统(ADAS)及富媒体车载信息娱乐系统(IVI)的普及,尽管高度自动化驾驶的时代依然遥远,但自动驾驶汽车的前景已变得愈发清晰。尺寸形状各异的无人机和日益普及的物联网也是亟需功能安全的领域,ARM 的技术将成为一大助力。

    ARM功能安全技术

    与其他技术市场一样,新兴的功能安全应用也需要半导体的驱动;这并不是纸上谈兵,日新月异的产品创新已经引起了ARM合作伙伴的浓厚兴趣。多数功能安全嵌入式系统都需要具备安全防护及实时处理两大核心要素,ARM Cortex-R系列处理器为此需求量身定制,为嵌入式系统提供高性能运算解决方案,确保产品的高可靠性、高可用性、容错、以及/或强大实时自主判断能力。这些特性为实现ADAS和IVI系统的高安全完整性打下基础,不仅可以执行关键行为处理,应对安全相关的中断事件,与其他系统通讯,还可以对集成度较低的复杂功能进行监管。

    什么是故障?

    故障可能是系统性的(如规范制定和设计过程中的人为因素);也有可能与使用的工具有关。减少故障的一种方法是执行严苛的质量管控流程,必须包括详细的规划、审查和量化评估。合理的规划使用工具认证非常重要,管理与追踪需求变更的能力也同样关键。ARM的Compiler 5编译器已经通过南德集团(TÜV SÜD)认证,助力安全研发,客户无需对编译器进行额外认证。

    还有一种故障类型被称为随机硬件故障。它们可能是图2显示的永久性故障,比如短路;也有可能是由于天然辐射而造成的软性故障。这类故障可以利用集成在软硬件的方案进行处理,因此系统级的技术也同样重要。举例来说,逻辑内建自测试(BIST)可以应用于系统启动和关闭,区分软性和永久性故障。

    什么是功能安全?汽车功能安全的设计方案

    图2:故障类型

    应对措施

    故障检测和控制措施的选择和设计是流程设计师最喜欢的环节,因为他们可以同时用系统级和微架构级的技术大展手脚。建立故障模式概念和效果分析(FMEA)是个不错的开始,列举出所有可能出现的故障模式及其后果的严重程度。有了这些信息,加上设计师对复杂系统的深入理解,即可鉴别出最严重的故障模式,并设计出应对措施。

    应对潜在故障的方法较多,下面列出了一些最常用的技术:

    ·多样化检查器:使用另一条电路检查主电路是否发生故障。举个例子,检查器可以为中断控制器计数,持续记录人为及系统引起的中断总数。

    ·完整锁步复制:该技术主要用于Cortex-R5处理器,对一个IP元件(如一个处理器)进行多次实例化,利用循环产生操作延迟,生成时间和空间冗余。大容量存储通常由多个实例共享,以降低所需面积。尽管这一技术非常可靠,但也极为昂贵。

    ·选择性硬件冗余:这个方案里,只有硬件的关键部分可以复制,如仲裁器。

    ·软件冗余:硬件冗余通常非常复杂,而且会产生间接成本,是对资源的不合理使用。硬件运算的替代方法就是,在多个处理器内核上运行同一次计算,检查结果是否匹配。

    ·错误检测和校正码是另一种为人熟知的技术,通常被用于保护存储器和总线。代码类型多种多样,但目标只有一个,既通过少量附加位获得更高冗余,无需复制所有底层数据。汽车系统中,这一尖端技术可以利用足够多的冗余检测出一个存储字的2位错误;并支持错误修正。

    故障日志

    检测出故障后就必须进行记录,以帮助监管软件判断系统的健康和安全状况。安全故障(如存储器修正)和危险故障(如不能挽回的硬件故障)必须分别记录。

    故障记录通常从故障计数开始,可以由系统级架构记录有信号事件(类似于中断)的数量;或者由IP计数器记录。为了解这些事件发生的原因,最好还能将过去的事件作为参考,判断当前时间的发生原因。为支持这一需求并进行调试纠错,可以允许一些IP捕捉额外信息,如被侦查的存储地址。因为该地址通常会由软复位保存,所以可以在系统启动和系统自检过程中被读取。

    有一点需要牢记,故障也可能发生在安全架构本身。与硬件故障不同的地方是,后者通常可以在使用过程中被很快发现,但安全检查器中的故障可能是潜伏的,它已经无法侦测危险故障,但故障却已经悄悄地蔓延开了。这样的故障被称为潜伏故障,定期测试检查器是个不错的方法。

    安全完整性等级

    不同的标准体系反应安全等级的方法也各不相同,但其主要目的是直观的反映功能的关键性。比如说,控制挡风玻璃雨刮、安全气囊或制动器的ECU,完整性必须高于控制车速表或泊车传感器的ECU,因为前方视野至关重要,突然刹车或气囊充气可能造成致命后果,驾驶员也会凶多吉少;而车速表或泊车传感器对安全停车的重要性就低得多了。

    换句话说,安全完整性等级是与人避免危险情况的必要性和能力相关的;而各项标准的作用就是指导人们如何定义安全完整性等级,并提供相关参数,帮助其对系统完整性进行量化。

    IEC 61508将安全完整性等级(SIL)分成4级,第4级为最高完整性。与之相似,ISO 26262提出了汽车安全完整性等级(ASIL),最低为ASIL A,最高为ASIL D。此外,就表二所示,针对ASIL B到ASIL D,ISO 26262分别就单点故障、潜伏故障和硬件故障概率指标(PMHF,业内也称及时故障)提出了建议参数。可检测故障的比例被称为诊断覆盖率。

    什么是功能安全?汽车功能安全的设计方案

    表1. ISO 26262的推荐标准

    尽管这些指标通常被视为标准要求,但在实际应用中,它们一般只被视为建议,供应商可以自行制定目标参数。最重要的目标是打造安全的产品,而不是在产品参数表上多加几个数字。让我们再次借用前面提到过的例子——挡风玻璃雨刮、制动器和安全气囊,这些元件的安全级别可能达到ASIL D,而车速表和泊车传感器可能是ASIL B或更低,具体级别取决于整体系统安全设计。

    无论诊断覆盖率多高,打造功能安全应用的时候都必须遵循合适的流程——这也是标准体系最大的益处。此外,无论采用何种功能安全措施,严格的质量流程都可以提升任何应用的整体质量。

    功能安全IP的设计流程

    开发功能安全应用IP时,“循规蹈矩”非常重要。这个过程必须从一开始就将安全纳入考虑,而且还必须营造支持安全的文化。

    完整的开发流程必须包含以下几个重要方面:

    ·安全管理:包括团队组织架构,具体内容如:明确不同职位的定义和职责、打造安全文化、定义安全生命周期,定义功能安全支持级别。安全生命周期的设定包括制定一份成功计划,选择合适的开发工具,确保团队接受充分的培训。

    ·需求管理和故障检测及控制措施(应对措施)的可追溯性。为精确实现需求追溯,需求本身定义必须要明确,精准,且具备唯一性。追溯等级取决于完整性的要求,文件可以高等级;产品则需要从故障检测到验证等各个环节面面俱到——计划过程不得空穴来风,必须经过详细验证。

    ·质量管理是需求追溯的拓展和延伸。勘误表必须得到妥善管理和使用。ARM在这一领域拥有丰富的经验。此外,流程的记录和传达也同样重要。

    安全文件包

    IP开发是ARM支持合作伙伴的一种途径,我们的合作关系并不会止于客户收到IP的那一刻。就功能安全相关的IP开发,ARM定义了2个安全文件包等级:

    ·最高至ASIL B的标准支持

    ·最高至ASIL D的延伸支持

    每个安全文件包都包含一份安全手册,详细说明遵循的流程、故障检测及控制功能、适用场景和其他信息。我们同时提供“故障模式及效果分析报告”,并提供案例分析,阐述如何用IP实现更高的诊断覆盖率;我们也为客户的独立分析提供芯片级的更多支持。此外,文件包也就ARM和被授权方的开发接口做出了明确定义。

    独立安全单元

    安全状况报告的建立和使用需要步步递进。该报告由芯片开发商提供信息,所有厂商的信息都必须综合考虑,最后交付客户使用,层层递进。获许可最多的芯片IP被称为“独立安全单元”(SEooC),其设计师们无需了解该芯片后续的使用方式。因此,安全手册必须说明 IP开发商对芯片使用建议和说明,避免误用。同样,OEM的1级控制器供应商也可以使用SEooC模型开发安全功能。因此,IP级的安全文件包可用于整个价值链,是 IP开发的重要部分。

    功能安全将逐渐成为硬性要求

    从汽车到医疗再到工业设备,依赖电子器件的应用越来越多,功能安全正变得更加重要,并将成为常规要求。功能安全是IP厂商必须达成的要求,也是让基于该IP建造的模型顺利运行的必要条件,因此IP厂商必须将每项研究成果授予尽可能多的芯片合作伙伴,反之亦然。有了坚实的质量和可靠性,功能安全才能带来更广泛的好处,进而推动全行业的质量和可靠性提升。包括驾驶员安全、燃油经济性、舒适度和车载信息娱乐系统等,功能安全是芯片设计师解决更高级别汽车难题的基础。


    展开全文
  • PDCP层功能

    千次阅读 2018-09-14 11:20:42
    PDCP层功能  LTE系统PDCP协议层的主要目的是发送或接收对等PDCP实体的分组数据。该子层主要完成以下几方面的功能:IP包头压缩与解压缩、数据与信令的加密,以及信令的完整性保护。下图给出了PDCP层用户平面与控制...
  • 功能性需求和非功能性需求

    万次阅读 2018-12-05 14:22:18
    功能需求 (functional requirement规定开发人员必须在产品中实现的软件功能,用户利用这些功能来完成任务,满足业务需求。功能需求有时也被称作行为需求 (behavīoral requirement),因为习惯上总是用“应该”对...
  • C++11常用的14个功能

    千次阅读 2016-11-21 13:31:38
    // C++11常用的14个功能 // // C11 特性总结 #include #include #include #include #include #include //#include #include #include #include #include void 性质1() {  // 类型自动推导
  • 什么是测试计划测试计划是对测试过程的整体设计,测试计划确定了测试产品所需的资源,确定了我们将测试什么,测试将怎样进行。测试计划的输出是一份或多份文档。为什么要制定测试计划项目的成败由四大要素决定:时间...
  • 简单几步开启手机OTG功能

    万次阅读 2017-08-03 14:39:44
    说到安卓手机,越来越多的功能方便了我们日常使用。如投影到高清电视的无线投屏功能、NFC功能,以及与周边设备数据交换的OTG功能。本文重点讲下OTG功能。 OTG功能是on the go的简写,让手机等移动设备实现与其他...
  • 一个奇鸽船新体验又叫一只奇鸽,跟之前火热的多功用助手是相同的软件。都是集成了许多实用功用的工具箱,这些运用功用日常用的少,可是关键时刻仍是得用,...软件跟多功能助手APP各有千秋,除了一些基础功用更有解...
  • 数据库设计——评论回复功能

    万次阅读 多人点赞 2017-05-03 02:45:35
    1、概述评论功能已经成为APP和网站开发中的必备功能。本文主要介绍评论功能的数据库设计。评论功能最主要的是发表评论和回复评论(删除功能在后台)。评论功能的拓展功能体现有以下几方面: (1)单篇文章的评论...
  • 软件需求分析——非功能性需求

    万次阅读 多人点赞 2019-05-17 16:41:39
    前言:需求分为功能需求和非功能性需求,常常会因为注重功能需求而忽略了非功能性需求,以下是对常见几类非功能性需求的小小总结,以后再慢慢补充。 非功能性需求 1、定义:软件产品为满足用户业务需求而必须具有...
  • 一行 Python 代码能实现什么丧心病狂的功能

    万次阅读 多人点赞 2019-12-10 13:48:46
    你在 python 使用过程中用一行代码实现过哪些激动人心的功能呢?欢迎留言讨论。手头有 109 张头部 CT 的断层扫描图片,我打算用这些图片尝试头部的三维重建。基础工作之一,就是要把这些图片数据读出来,织成一个三...
  • 评论回复功能的实现

    万次阅读 多人点赞 2020-05-13 01:44:07
    最后的效果图如上,大家不难发现这个回复的想法和知乎的回复模式差不多(因为我就是照着那个思路实现的 :) ),只是这里少实现了查看对话的功能。下面说说我实现这个过程中遇到的一些困难。 首先讲讲我的数据库的...
  • 本人电脑为Lenovo win10系统,常常会遇见很多与win7,win8不同的地方,所以经常会遇到困惑,今天的一个困惑是:Win10系统笔记本电脑上的F1-F12键上都变成了开关系统功能开关的快捷键,而失去了F1-F12键本身的快捷键...
  • 电商网站后台九大功能模块详解

    万次阅读 多人点赞 2018-07-18 01:21:33
    电商网站后台九大功能模块详解  随着电子商务的发展,网上购物正在趋于一种时尚,电子商务网站也逐渐成为企业顺应潮流的标配。大多数人知道可能在电子商务网站前端有查询,注册登录,购物车等等功能。可是您知道...
  • CSDN产品公告第4期:移动端写博客功能上线!

    万次阅读 多人点赞 2019-12-24 15:01:08
    付费专栏功能上线 博主可自由选择 之前不少博主问菌菌,他们写了这么多文章、并且吸引了这么多粉丝关注,有什么用呢?他们能够获得些什么呢? 有些博主写文章是为了记笔记,记录自己的成长历程,有些博主是为了分享...
  • python实现复制文件功能

    万次阅读 2018-08-27 22:21:59
    写程序,实现复制文件功能 要求: 1) 要考虑关闭文件问题 2) 要考虑超大文件复制问题 3) 要能复制二进制文件(如: / usr / bin / python3 等文件) def copy_file(): file=input(‘源文件’) file1=input(...
  • 微服务应该具备哪些功能

    千次阅读 2018-09-21 11:48:26
    文章目录微服务应该具备哪些功能1、服务的注册和发现2、服务的容错3、服务配置的统一管理4、微服务的特点5、微服务的功能体现在哪些方面 微服务应该具备哪些功能 1、服务的注册和发现 微服务系统由很多个单一职责的...
  • springmvc实现留言回复功能

    万次阅读 多人点赞 2020-06-13 14:56:35
    很多网站都提供了留言,评论回复功能,而我做的一个分享圈项目同样要实现的功能。思路:1.可以只创建一个留言表,用户的留言和回复功能都插进这张表,这样建议在网页显示效果用爬楼形式,因为数据都在一张表,划分...
1 2 3 4 5 ... 20
收藏数 7,233,462
精华内容 2,893,384
关键字:

功能