Vue面试相关问题_来说垃圾话啊的博客-程序员宅基地

技术标签: Vue  vue  

1、vue解决了什么问题

解决了用 DOM API 操作 UI 过于反人类的问题。

React 通过 UI = f(data) 解决。

Vue 通过 Reactive 响应式数据解决。

更多关于上述问题理解


2、MVVM的理解

MVVM分为Model、View、ViewModel三者。

  • Model:代表数据模型,数据和业务逻辑都在Model层中定义;
  • View:代表UI视图,负责数据的展示;
  • ViewModel:就是与界面(view)对应的Model。因为,数据库结构往往是不能直接跟界面控件一一对应上的,所以,需要再定义一个数据对象专门对应view上的控件。而ViewModel的职责就是把model对象封装成可以显示和接受输入的界面数据对象。

Model和View并无直接关联,而是通过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Model中同步。

简单的说,ViewModel就是View与Model的连接器,View与Model通过ViewModel实现双向绑定。


3、如何实现一个自定义组件,不同组件之间如何通信的?

组件需要注册后才可以使用,有全局注册和局部注册两种方式在实例创建前通过

<script>
Vue.component('自定义标签名称',{
    //选项
});
var app = new Vue({
    el:'#app'
})
</script>

来注册全局组件,不必把每个组件都注册到全局,在实例中,使用components选项可以局部注册组件,注册后的组件只有在该实例作用域下有效,组件中也可以使用components选项来注册组件,使组件可以嵌套。

<script>
  var Child = {
      template:'<div>局部注册组件内容</div>'
}
 var app = new Vue({
    el:'#app',
    components:{
        'my-component':Child
}
})
 
</script>

组件关系可分为父子组件通信、兄弟组件通信、跨级组件通信

父子组件通信:
父组件向子组件通信,通过props传递数据

子组件向父组件传递数据时,用到自定义事件,子组件用 e m i t ( ) 触 发 事 件 , 父 组 件 用 emit()触发事件,父组件用 emiton()监听子组件的事件,父组件也可以直接在子组件的自定义标签上使用v-on来监听

<div id="app">
    {
   {message}}
    <my-component></my-component>
</div>
<script>	
    Vue.component('my-component',{
        template:'<button @click="event"></button>',
		methods:{
			event:function() {
				this.$dispatch('on-message','来自内部组件的数据');
			}
		}
	})
	var app = new Vue({
	    el:'#app',
	    data:{
		message:''
		 },
	    events:{
		'on-message':function(msg) {
		    this.message = msg;
				}
		    }
			
		})
</script>

非父子组件通信:
在Vue.js 1.x中,提供 d i s p a t c h ( ) 和 dispatch()和 dispatch()broadcast()两个方法。 d i s p a t c h ( ) 用 于 向 上 级 派 发 事 件 , 只 要 是 它 的 父 级 ( 一 级 或 多 级 以 上 ) , 都 可 以 在 V u e 实 例 的 e v e n t s 选 项 内 接 收 . dispatch()用于向上级派发事件,只要是它的父级(一级或多级以上),都可以在Vue实例的events选项内接收. dispatch()Vueevents.broadcast()由上级向下级广播事件。

但在Vue.js 2.x中都废弃了(不能解决兄弟组件通信问题)

在Vue.js 2.x中,推荐使用一个空的vue实例作为中央事件总线(bus),也就是一个中介

<div id="app">
		{
   {message}}
		<component-a></component-a>
	</div>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<script>
		var bus = new Vue();
		Vue.component('component-a',{
			template:'<button @click="event">传递事件</button>',
			methods:{
				event:function() {
					bus.$emit('on-message','来自组件component-a的内容')
				}
			}
		})
		var app = new Vue({
			el:'#app',
			data:{
				message:''
			},
			mounted: function() {
				var _this = this;
				bus.$on('on-message',function(msg) {
					_this.message = msg;
				})
			}
		})
	</script>

这种方法实现了任何组件间的通信,如果深入使用,可以扩展bus实例,给它添加data、computed、methods等选项,这些都是可以公用的

除了bus外,还有两种方法可以实现组件间通信,父链和子组件索引

父链
在子组件中,使用this.$parent可以直接访问该组件的父实例或组件,父组件也可以通过this.$children访问它所有的子组件

<div id="app">
		{
   {message}}
		<component-a></component-a>
	</div>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<script>
		var bus = new Vue();
		Vue.component('component-a',{
			template:'<button @click="event">传递事件</button>',
			methods:{
				event:function() {
					//访问到父链后,可以做任何操作,比如直接修改数据
					this.$parent.message = "来自组件component-a的内容"
				}
			}
		})
		var app = new Vue({
			el:'#app',
			data:{
				message:''
			}
			
		})
	</script>

父子组件最好还是通过props和$emit来通信

子组件索引


4、nextTick

vue官网中的释义nextTick

源码分析nextTick

5、Vue的生命周期

vue的生命周期里边有八个生命周期钩子函数分别是:

  • beforeCreat() 创建前
  • created()创建
  • beforeMount()挂载前
  • mounted()挂载
  • beforeupdate()更改前
  • updated()更改
  • beforeDestroy()销毁前
  • destroyed()销毁

先来一张官方的生命周期图镇贴
在这里插入图片描述生命周期函数理解

6、虚拟dom的原理

虚拟DOM的工作原理及详解


7、双向绑定的原理?数据劫持?

1.1 数据劫持

1.1.1 如何监控一个数据

vue可以直接通过v-model这个指令来实现双向绑定,这是react和小程序都没有,小程序是单向绑定,只能将data中的对象和基本数据类型展示在视图上,却没有办法通过视图来控制data中的数据,需要通过this.setData({})给出一个对象,重新设置数据,达到视图更新。
在这里插入图片描述要达到如图1-1的效果,就要对数据进行监控,只有监控了数据的变化,在数据变化之后,通知视图去自主更新,这就是双向绑定的思路。这个思路很明显涉及到“监控” “更新”两个关键词,就可以联想到观察者模式。

观察一个数据,一旦数据变化,就通知视图执行更新操作。

思路一下子就明了,数据变化还好说,就是拿出一个变量存储旧值,一旦获取到新值,新值与旧值不同时,数据就发生了变化。可问题在于,不可能随时随地对数据进行监控,每分每秒都在取得数据的值去与旧值做对比。

只有当这个数据在被使用时,我们才监控他,拿旧值与新值做对比。

这个过程叫做让数据变为可观察,是通过Object.defineProperty() 来实现。

1.1.2 如何使用Object的静态方法定义属性

Object.defineProperty(obj, prop, descriptor)

  • obj 要在其上定义属性的对象。
  • prop 要定义或修改的属性的名称。
  • descriptor 将被定义或修改的属性描述符。

被这样定义的属性,所有的数据描述符默认为false,也就是不可删除,不可写,不可枚举

属性描述符
MDN文档上有提到
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。

let obj = {
            name:1
        }
        Object.defineProperty(obj,'school',{
            configurable:true,//表示configurable可以被删除
            writable:true,//为true之后,便可以修改
            // enumerable:true,//修改之后才可以被枚举,在遍历时被访问到
            value:'zfpx'
        })
        // delete obj.school;
        obj.school = "修改值"
        console.log(obj)
        for(var key in obj){
            console.log(key)
        }

只有开启数据描述符为true之后,属性才可被删除,被写入,被枚举打印

getter-setter
这就是数据可监控的关键,使用Object.defineProperty(obj, prop, descriptor)定义的属性,一旦属性被使用,就会被读取,就会调用get函数,一旦属性被写入,就会调用set函数,即可以知道数据一旦发生写入,变化,就可以在set函数中通知视图更新。

由于,

存储描述符get set参数和数据描述符的writeable value存在冲突,二选其一

 Object.defineProperty(obj, "school", {
        configurable: true, //表示configurable可以被删除
        // writable: true, 
        enumerable: true, //修改之后才可以被枚举,在遍历时被访问到
        // value: "zfpx",
        get() {
          console.log("调用了get方法");
          return value;
        },
        set(newVal) {
          console.log("调用了set方法");
          value = newVal;
        }
      });

在这里插入图片描述如图 1-2

1.1.3 数据劫持
知道了get和set的妙用,就可以对数据进行劫持了。

劫持的概念

说白了,就是拿到某数据,持有这个数据,可以操作增删改,也可以不操作,重点在持有他

监听

一旦数据被传入Vue实例就需要对data整个对象实行监听,

这里需要对data中的数据类型进行判断

如果是data中的属性是基本数据类型,只需要监控就好了

如果data中的属性是对象,则需要遍历对象下的所有属性,进行监控

可又有一个疑问,data的属性是对象A,A的属性还包含对象B,B有对象C,所以不能是遍历,而是递归,递归整个对象属性树

​
<body>
    <div id="app">
      <p>姓名是{
   { name.firstName }}</p>
      <div>年龄是{
   { age }}</div>
      {
   { name }}
    </div>
    <script type="vue.js"></script>
    <script type="text/javascript">
      let vm = new Vue({
        el: "#app",
        data: {
          name: {
            firstName: "姓氏章",
            lastName: "名字"
          },
          age: 12 //通过Obj.defineProperty实现()或者Obj.defineProperties()实现
        }
      });
    </script>
 </body>
 

数据绑定(传入{ 对象的data挂载在vue实例上)

/**
*Vue入口
*@{options} 限定为一个对象,接受这个{}对象
* */
function Vue(options = {}) {
this.$options = options; // 将所有属性挂载在vue实例$options上
var data = (this._data = this.$options.data); //将{}对象的data挂载vue实例上
observe(data);
}
  /**
   *观察对象变化,如果最开始传入的data是基本数据类型,已经被劫持了,不需要递归再去对属性进行监控
   *@{data} 被观察的对象或属性
   */
  function observe(data) {
    if (typeof data !== "object") return null;
    return new Observe(data);
  }
 class Observe {
        constructor(data) {
          this.start(data);
        }
 
        start(data) {
          for (let key in data) {
            let val = data[key];
            // 如果data中包含属性是对象,则需要递归对象的中属性,进行数据劫持
            // 如果data中的属性就是普通数据类型,递归退出 -- 递归出口
            Object.defineProperty(data, key, {
              enumrable: true,
              get() {
                console.log("调用get方法");
 
                return val;
              },
              // 会在数据改变的时候直接设置
              set(newVal) {
                console.log("调用set方法");
 
                //数据并没有改变
                if (newVal === val) {
                  return;
                }
                val = newVal;
              }
            });
          }
        }
      }

上述代码实现了数据劫持和监控数据的功能

接下来是

数据代理(this代理传入的{ }对象去调用data)

编译模板(读取文本节点中的字符串,抽成属性名,通过字面量的形式访问到属性值,去掉双大括号,显示到节点上)

到编译模板这一步,是实现了单向绑定,也就是data中的数据被显示在网页上,如同又通过视图,譬如input输入框,改变data的值。


8、组件通信

在这里插入图片描述

1、父->子

方法一、props/$emit
父组件 A 通过 props 的方式向子组件 B 传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现。

接下来我们通过一个例子,说明父组件如何向子组件传递值:在子组件 Users.vue 中如何获取父组件 App.vue 中的数据
users:["Henry","Bucky","Emily"]

//App.vue父组件
<template>
  <div id="app">
    <users v-bind:users="users"></users>//前者自定义名称便于子组件调用,后者要传递数据名
  </div>
</template>
<script>
import Users from "./components/Users"
export default {
  name: 'App',
  data(){
    return{
      users:["Henry","Bucky","Emily"]
    }
  },
  components:{
    "users":Users
  }
}
//users子组件
<template>
  <div class="hello">
    <ul>
      <li v-for="user in users">{
   {user}}</li>//遍历传递过来的值,然后呈现到页面
    </ul>
  </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  props:{
    users:{           //这个就是父组件中子标签自定义名字
      type:Array,
      required:true
    }
  }
}
</script>

总结:父组件通过 props 向下传递数据给子组件。注:组件中的数据共有三种形式:data、props、computed

2、子->父

子组件向父组件传值(通过事件形式)

接下来我们通过一个例子,说明子组件如何向父组件传递值:当我们点击“Vue.js Demo”后,子组件向父组件传递值,文字由原来的“传递的是一个值”变成“子向父组件传值”,实现子组件向父组件值的传递。

在这里插入图片描述

// 子组件
<template>
  <header>
    <h1 @click="changeTitle">{
   {title}}</h1>//绑定一个点击事件
  </header>
</template>
<script>
export default {
  name: 'app-header',
  data() {
    return {
      title:"Vue.js Demo"
    }
  },
  methods:{
    changeTitle() {
      this.$emit("titleChanged","子向父组件传值");//自定义事件  传递值“子向父组件传值”
    }
  }
}
</script>
// 父组件
<template>
  <div id="app">
    <app-header v-on:titleChanged="updateTitle" ></app-header>//与子组件titleChanged自定义事件保持一致
   // updateTitle($event)接受传递过来的文字
    <h2>{
   {title}}</h2>
  </div>
</template>
<script>
import Header from "./components/Header"
export default {
  name: 'App',
  data(){
    return{
      title:"传递的是一个值"
    }
  },
  methods:{
    updateTitle(e){   //声明这个函数
      this.title = e;
    }
  },
  components:{
   "app-header":Header,
  }
}
</script>

总结:子组件通过 events 给父组件发送消息,实际上就是子组件把自己的数据发送到父组件。

组件通信的其他方式

3、非父子组件


9、Proxy 相比于 defineProperty 的优势

vue3.0尝鲜 – 摒弃Object.defineProperty,基于 Proxy 的观察者机制探索


10、watch computed区别

computed:计算属性
1、计算属性是由data中的已知值,得到的一个新值。
2、这个新值只会根据已知值的变化而变化,其他不相关的数据的变化不会影响该新值。
3、计算属性不在data中,计算属性新值的相关已知值在data中。
4、别人变化影响我自己。

watch:监听数据的变化
1、监听data中数据的变化
2、监听的数据就是data中的已知值
3、我的变化影响别人

little-demo:演示watch和computed的区别

<div id="app">
    <input type="text" v-model="name" />
    <span v-show="isShow">请输入3-6个字符</span>
    <br />
    <input type="text" v-model="todoName" />
</div>

<script src="./vue.js"></script>
<script>
    const vm = new Vue({
        el: "#app",
        data: {
            name: "zs",
            todoName: "ls"
        },
        computed: {
            isShow() {
                //当this.name的长度小于3或者大于6时显示提示内容(我根据name的变化而变化)
                if (this.name.length >= 3 && this.name.length <= 6) {
                    return false;
                } else {
                    return true;
                }
            }
        },
        watch: {
            //监听data中的name,如果发生了变化,就把变化的值给data中的todoName(我影响了别人)
            name(newVal) {
                this.todoName = newVal;
            }
        }
    });
</script>

11、virtual dom 原理实现

virtual dom实现原理及详解

12、vue-router(hash, HTML5 新增的 pushState

从Vue-router到html5的pushState

最近在用vue的时候突然想到一个问题

首先,我们知道vue实现的单页应用中一般不会去刷新页面,因为刷新之后页面中的vuex数据就不见了。
其次,我们也知道一般情况下,url变更的时候,比如指定location.href、history.push、replace等,页面就会刷新。

那么问题来了,vue页面的页面跳转时怎么实现的?没刷新页面么?没刷新页面,又要改变url,加载新内容怎么做的?

去翻了一下vue-router的源码,找到这样一段

export class HTML5History extends History {
   ...
 
  push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
    const { current: fromRoute } = this
    this.transitionTo(location, route => {
      pushState(cleanPath(this.base + route.fullPath))
      handleScroll(this.router, route, fromRoute, false)
      onComplete && onComplete(route)
    }, onAbort)
  }
 
  replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
    const { current: fromRoute } = this
    this.transitionTo(location, route => {
      replaceState(cleanPath(this.base + route.fullPath))
      handleScroll(this.router, route, fromRoute, false)
      onComplete && onComplete(route)
    }, onAbort)
  }
  ...
}

再看看方法内部

export function pushState (url?: string, replace?: boolean) {
  saveScrollPosition()
  // try...catch the pushState call to get around Safari
  // DOM Exception 18 where it limits to 100 pushState calls
  const history = window.history
  try {
    if (replace) {
      history.replaceState({ key: _key }, '', url)
    } else {
      _key = genKey()
      history.pushState({ key: _key }, '', url)
    }
  } catch (e) {
    window.location[replace ? 'replace' : 'assign'](url)
  }
}

答案就是html5在history中新增加的方法:pushState和replaceState。这两个又是干啥的呢?(两个十分类似,以下以pushState为例说明,区别和push与replace一致)

HTML5的pushState()
首先看看这个是干什么的

  • pushState方法就是向history中push一条记录,更改页面url,但是不刷新页面,不刷新页面,不刷新页面。不刷新页面,这点很关键,这和下面的操作很相似
    window.location.href = window.location.href + '#a=b

知道干嘛的了,再看看API怎么用的
history.pushState(state, title, url);

在这里插入图片描述popstate中的
在这里插入图片描述

  • title这个参数目前没什么用处,可能是给以后预留的参数,暂时用null就好了
  • url很明显,就是替换后的url了。url可以接受绝对地址和相对地址,设置绝对地址的时候,要保证域名和当前域名一致,否则汇报如下错误
Uncaught DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'https://www.baidu.com/' cannot be created in a document with origin 'https://mocard-aliyun1.chooseway.com:8443' and URL 'https://mocard-aliyun1.chooseway.com:8443/views/h5/indexasdasd'.
    at History.pushState (https://aixuedaiimg.oss-cn-hangzhou.aliyuncs.com/static/m/js/alog/v1.0.0/alog.min.js:1:23259)
    at <anonymous>:1:9

HTML5的popstate()

  • popstate与pushState相对应,主要在页面url变更的时候触发,一般绑定在window对象下
window.addEventListener('popstate', e => {
  console.log('popstate', )
})

前面pushState中传入的state对象,可以在这边接收到,并根据需要去做一些处理。

说到这,vue-router是怎么实现页面“刷新”但不刷新的就知道了吧。
vue-router就是利用pushState这个属性,在页面前进的时候动态改变history的内容,添加一条记录,接着location跟着改变。同时根据router前往的路由获取对应的js资源文件并挂载到目标dom上实现页面内容的更新,但是页面本身并没有刷新。

单页应用,如何实现其路由功能—路由原理

单页面路由即在前端单页面实现的一种路由,由于React,Vue等框架的火热,我们可以很容易构建一个用户体验良好的单页面应用,但是如果我们要在浏览器改变路由的时候,在不请求服务器的情况下渲染不同的内容,就要类似于后端的路由系统,在前端也实现一套完整的路由系统

vue-router如何做用户登录权限等

你在项目中怎么实现路由的嵌套


13、vuex的理解

前端性能优化汇总

页面DOM节点太多,会出现什么问题?如何优化?

前端性能监测

seo与语义化理解一

seo与语义化理解二及处理方式

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42241357/article/details/108614347

智能推荐

JeecgBoot数据缓存V2.0_大强012的博客-程序员宅基地_jeecgboot菜单缓存

基于JeecgBoot框架,通过属性文件和AOP注解,实现常用数据缓存半自动化存储。1、数据缓存属性文件src/main/resources/dataCache.properties# 数据缓存属性文件# 第1列为表名(例如:wr_season_b),# 第2列为Key(例如:season_nm),# 第3列以后为Value(例如:start_date,end_date等等)。datacache.list[0]=wr_season_b,season_nm,start_date,end_

pygame 贪吃蛇_weixin_408的博客-程序员宅基地_pygame蛇身体移动

pygame 贪吃蛇思路:1.把蛇分成蛇的身体和蛇的头部两部分,蛇用三个小方块表示;2.食物目标随机生成,要避免蛇的食物与蛇重合;3.通过键盘事件控制蛇的移动,当蛇向右移动时,不能控制其向左移动,向上移动时不能控制其向下移动,向左,向下同理;4.初始化时要给蛇一个移动方向,蛇一直在移动,我们只是控制方向,蛇的移动实现:通过在蛇头添加一个方块实现移动效果,因为只有在蛇吃到食物时蛇的身体才能增加,所以添加之后要判断蛇是否吃到食物,如果吃到此时刚好达到添加的效果,如果没有吃到,则删掉蛇身末尾的方块,达

python中dpi_python matplotlib 绘图 和 dpi对应关系详解_贺开的博客-程序员宅基地

我就废话不多说啦!dpi=1     600×400dpi=2    1200×800dpi=3    1800×1200........dpi=21    (21×600)×(21×400) ---&gt; 12600×8400示例代码: ..............................plt_temp=y_axisplt_temp.resize(len(y_axis) , 1)pl...

第四篇——是什么让我们勇往直前? 兴趣使然_diqindian4669的博客-程序员宅基地

与几个室友聊天发现,她们长期积累的对考研的兴趣已经随着时间慢慢消磨殆尽。实际上没有人对考研感兴趣,诱惑我们的通常是逃避社会的避难所、深造科研的圣殿或者是高校的环境,但是这样一个简单的欲望会在长期的巨大压力中崩溃,我们常常迷茫,我们常常患得患失,在付出的精力和实际的收获之间作比较,希望生活会给我们正面的回馈。可惜时间就是像温水煮青蛙,当我们发现我们真实想法的时候往往为时晚矣。曾经的...

OpenWrite插件上架Google商店,插件安装更加容易!用户安全更有保障!_程序猿DD的博客-程序员宅基地

随着越来越多用户加入OpenWrite写作与快速发布文章到各大技术社区,不少非程序员童鞋经常会卡在插件安装这一步。这是因为之前我们没有把插件上架到Google商店,所以需要用比较硬核的方式来安装。同时,由于缺少Google商店的审核,可能有些用户对于安全上有所顾忌。因此,我们折腾、折腾、再折腾,终于把插件上架到Google商店啦!安装步骤第一步:点击进入Google商店安装![](h...

离散数学笔记整理(个人向)_diosmai_kingso的博客-程序员宅基地_离散数学笔记

复习离散数学整理出来的笔记(主要便于自己记忆)

随便推点

sdut oj 数据结构实验之二叉树五:层序遍历(数组模拟)_Kirie_的博客-程序员宅基地

链表二叉树链接如下sdut oj 数据结构实验之二叉树五:层序遍历 (链表).数组模拟方式见下文Description已知一个按先序输入的字符序列,如abd,eg,cf,(其中,表示空结点)。请建立二叉树并求二叉树的层次遍历序列。Input输入数据有多行,第一行是一个整数t (t&lt;1000),代表有t行测试数据。每行是一个长度小于50个字符的字符串。Output输出二叉树的层次遍历序列。SampleInput2abd,,eg,,,cf,,,xnl,,i,,u,,Outpu

定点数、浮点数类型运算的说明_Tiger-Li的博客-程序员宅基地_q24定点数范围

处理器在进行数值运算的时候包括整数以及小数的运算:处理器在操作小数的时候有两种表示方式:浮点运算和定点运算!1.1定点数(fixed-point):字面意思看,小数点位置是固定的,即约定机器中所有数据的小数点位置是不变的。在计算机中通常有两种简单的约定:将小数点的位置固定放在数据的最高位之前,或者固定在最低位数据之后,一般称前者为定点小数,后者为定点整数!在对小数点位置作出选择之后(即...

spark08--kafka组件,面试题,常用命令,可视化,api,Streaming简介,DStream,nc服务,Streaming实现Wordcount_forever428的博客-程序员宅基地_spark streaming + kafka + 可视化

kafka重要组件1. producer:生产者负责将数据传入kafka, 比如flume, java后台服务, logstash生产者可以有多个, 并且可以同时往一个topic中写数据, 也可以同时往同一个partition中写数据每一个生产者都是一个独立的进程, 而且单个生产者就具有分发数据的能力一个生产者可以同时往多个topic中分发数据2. kafka cluster:...

手把手讲解 Android Hook-Activity的启动流程_饭小粒的博客-程序员宅基地_hook 启动首页过程

前言手把手讲解系列文章,是我写给各位看官,也是写给我自己的。文章可能过分详细,但是这是为了帮助到尽量多的人,毕竟工作5,6年,不能老吸血,也到了回馈开源的时候.这个系列的文章:1、用通俗易懂的讲解方式,讲解一门技术的实用价值2、详细书写源码的追踪,源码截图,绘制类的结构图,尽量详细地解释原理的探索过程3、提供Github 的 可运行的Demo工程,但是我所提供代码,更多是提供思路,抛砖引玉,请酌情cv4、集合整理原理探索过程中的一些坑,或者demo的运行过程中的注意事项5、用gif图,最直

JS 动态生成节点_li_Johnson_llguo的博客-程序员宅基地

&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;var ul = document.getElementById(&quot;ul&quot;);li = document.createElement(&quot;li&quot;); txt = document.createTextNode(&quot;txt&quot;);li.className = 'className';li.on...

[模拟+二分]zoj 3470:Magic Squares_sdau_09j1_xcy的博客-程序员宅基地

大致题意:    如题目中给出的图片对于这样的一个无线扩展出去的图,输入一个数n,求出数字上下左右的4个数字,按造升序输出。 大致思路:    突破点在,对于每一圈右下角的数字都是(a*2-1)*(a*2-1),a为当前在第a圈。如此,通过二分枚举判定出这个点在第几个圈内。然后在推导这个点和上下左右点的关系。 #include&amp;lt;iostream&amp;gt;#...

推荐文章

热门文章

相关标签