【前端面试题】前端面试题总结2023-7-13(七)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【前端面试题】前端面试题总结2023-7-13(七)

9、Vue组件传值

在 Vue 中,可以通过父组件向子组件传递值,以及通过事件机制实现子组件向父组件传递值。下面我将介绍两种常见的Vue组件传值方式:

  1. 父组件向子组件传递值:
    在父组件模板中,可以使用子组件的属性来向子组件传递值。子组件可以通过 props 属性接收父组件传递过来的值。
    父组件的示例代码:
<template>
  <div>
    <!-- 父组件 -->
    <child-component :message="parentMessage"></child-component>
  </div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent'  // 父组件的数据
    }
  }
}
</script>
  1. 子组件的示例代码:
<template>
  <div>
    <!-- 子组件 -->
    <p>{{ message }}</p>
  </div>
</template>
<script>
export default {
  props: {
    message: String  // 子组件接收父组件传递的值
  }
}
</script>
  1. 在上述示例中,父组件通过 :messageparentMessage 传递给子组件的 message 属性。子组件可以在模板中通过 {{ message }} 访问该属性的值。
  2. 子组件向父组件传递值:
    子组件可以通过 $emit 方法触发自定义事件,并传递值给父组件。父组件可以在模板中监听这些自定义事件,并在相应的方法中接收子组件传递的值。
    父组件的示例代码:
<template>
  <div>
    <!-- 父组件 -->
    <child-component @custom-event="handleCustomEvent"></child-component>
    <p>{{ childData }}</p>
  </div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      childData: ''  // 父组件接收子组件传递的值
    }
  },
  methods: {
    handleCustomEvent(data) {
      this.childData = data;  // 处理子组件触发的自定义事件,接收子组件传递的值
    }
  }
}
</script>
  1. 子组件的示例代码:
<template>
  <div>
    <!-- 子组件 -->
    <button @click="triggerCustomEvent">点击触发事件</button>
  </div>
</template>
<script>
export default {
  methods: {
    triggerCustomEvent() {
      const eventData = 'Hello from child';  // 要传递给父组件的值
      this.$emit('custom-event', eventData);  // 触发自定义事件并传递值给父组件
    }
  }
}
</script>
  1. 在上述示例中,子组件通过 this.$emit('custom-event', eventData) 触发名为 custom-event 的自定义事件,并传递了一个值 eventData。父组件监听了该自定义事件 @custom-event,并在相应的方法 handleCustomEvent 中接收子组件传递的值并进行处理。

这就是 Vue 中常用的两种组件传值方式:父组件向子组件传递值,以及子组件向父组件传递值。你可以根据实际需求选择适合的方式来进行组件之间的数据传递。

10、computed、methods、watch有什么区别?

在 Vue 中,computedmethodswatch 是用于处理数据的三种不同方式,它们的区别如下:

  1. computed:计算属性
  • computed 允许你基于已有的响应式数据计算出新的属性值,并以响应式的方式进行缓存。只有当依赖的响应式数据发生变化时,计算属性才会重新计算。
  • computed 的返回值会被缓存,多个组件访问相同的计算属性时,只会计算一次。
  • computed 适合用于多个依赖属性联动计算或需要复杂逻辑的场景。
  1. methods:方法
  • methods 是 Vue 实例中定义的普通方法,可以在模板中通过事件触发调用。
  • methods 每次调用都会重新执行其中的代码逻辑,因此不会像 computed 那样进行缓存。
  • methods 适合用于需要主动触发调用、或需要传递参数、或执行一些动态逻辑的场景。
  1. watch:侦听器
  • watch 可以监听一个特定的数据源,并在其发生变化时执行相应的回调函数。
  • watch 提供了更为细粒度的控制,可以对某个数据变化做出即时响应。
  • watch 适合用于需要在数据变化时执行异步操作、或执行较为复杂的逻辑(例如深度监听对象或数组变化)的场景。

需要注意的是,尽量避免在 computedwatch 中进行复杂的计算或异步操作,这样可能会导致性能问题。如果涉及到比较耗时的操作,建议将其放在 methods 中进行。根据实际需求和场景,选择合适的方式来处理数据,能够更好地提高代码的可读性和维护性。

11、props和data优先级谁高?

在 Vue 中,propsdata 具有不同的作用和优先级。

  1. props:父组件传递给子组件的属性
  • props 是从父组件向子组件传递数据的方式。
  • Prop 是单向绑定的:当父组件的属性值发生变化时,会传递给子组件,并更新子组件的值。但是子组件不能直接修改来自父组件的 prop 值,只能接收和使用它。
  • props 是外部数据源,对于子组件来说是只读的。
  1. data:组件内部的数据
  • data 是组件内部的数据,用于存储和管理组件自身的状态。
  • data 的值可以在组件的模板中直接使用,并且组件可以在需要的时候修改 data 中的值。
  • 每个组件实例都有独立的 data 副本,互不影响。

在优先级方面,props 的优先级高于 data。当一个组件中既定义了 props 又定义了同名的 data 时,props 的值会覆盖 data 中的值。

这样设计的目的是为了确保组件的数据来源清晰明确,通过 props 传递的数据是外部传入的,而 data 存储的是组件内部的状态数据。这样可以提高组件的可维护性和代码的可读性,并且与单项数据流的原则保持一致。

需要注意的是,尽量避免在子组件中直接修改来自 props 的值,因为这会破坏了数据的单向流动性,导致代码难以维护和理解。如果需要对传入的 props 进行修改,应该通过在子组件中触发事件并通知父组件进行修改,从而保持数据流的清晰和可控性。

12、Vuex有哪些属性?

在 Vuex 中,有以下几个核心的属性:

  1. state:应用的状态
  • state 是存储应用级别的状态数据的地方。
  • state 中定义的数据可以被整个应用中的组件访问和使用。
  1. getters:计算属性
  • getters 类似于组件中的计算属性,用于从 state 中派生出一些新的状态值。
  • getters 的作用是对 state 中的数据进行包装和处理,并提供给组件使用。
  1. mutations:更改状态的方法
  • mutations 是用于修改 state 中数据的唯一方式。
  • mutations 必须是同步函数,用于单一状态的改变。
  1. actions:异步操作和提交mutations
  • actions 用于处理异步操作,例如发送网络请求、定时器等。
  • actions 可以包含任意异步操作,但是最终通过提交 mutations 来改变 state
  1. modules:模块化组织stategettersmutationsactions
  • modules 允许将大型的 Vuex 应用分割成更小的模块,每个模块都有自己的 stategettersmutationsactions
  • 这样可以更好地组织代码,便于维护和扩展。

这些属性共同组成了 Vuex 的核心,通过集中管理和操作应用的状态,使得状态更新更可追踪、可预测,从而提高应用的开发效率和可维护性。

13、Vuex是单向数据流还是双向数据流?

Vuex 是单向数据流。

单向数据流意味着数据的流动是单向的,只能由父级组件向子级组件传递。在 Vuex 中,数据的流动是从 state(状态)到视图(组件),通过 getters(计算属性)和 actions(异步操作)对数据进行处理和操作,最终通过 mutations(同步方法)来修改 state 的值。

这种单向数据流的设计有以下几个优点:

  1. 可预测性:数据的流动单一、明确,使得应用的状态更可预测和可跟踪。
  2. 易于调试:当数据的变化只能通过特定的路径改变时,出现问题时可以很容易地追踪到数据的修改来源。
  3. 数据的一致性:对数据的修改只能通过 mutations 来进行,保证了数据的一致性,避免了数据的混乱和不一致。
  4. 可维护性:单向数据流使得数据的变化路径清晰,代码的耦合度降低,使得应用的维护更加容易。

需要注意的是,在 Vuex 中,虽然数据的流动是单向的,但是通过 actions 中的异步操作可以实现类似双向的效果,即在修改数据后,可以通过回调或 Promise 来返回结果给组件,这样可以实现视图更新或其他操作。但是数据流本身仍然是单向的,异步操作只是一种实现方式,并没有改变单向数据流的本质。

14、Vuex中的mutations和actions区别?

在 Vuex 中,mutationsactions 是用于修改状态的方法,它们的主要区别在于以下几个方面:

  1. 同步 vs 异步:mutations 是同步操作,而 actions 是异步操作。在 mutations 中修改状态的操作是立即执行的,而在 actions 中可以包含异步操作(如网络请求),通过提交 mutations 来修改状态。因此,actions 适合处理复杂的异步操作,而 mutations 适合处理简单的同步操作。
  2. 触发方式:mutations 可以直接被组件调用,通过 commit 方法来触发。而 actions 必须通过 dispatch 方法来触发,组件中不能直接调用 actions
  3. 修改状态的方式:mutations 是修改状态的地方,通过修改 state 中的数据来改变应用的状态。而 actions 则是通过触发 mutations 来间接地修改状态。actions 可以包含一系列的异步操作,并最终通过提交 mutations 来修改 state 中的数据。
  4. 异步操作和副作用: actions 适合处理异步操作,例如发送网络请求、定时器等。同时,actions 也可以用于处理一些具有副作用的操作,如改变路由、打印日志等。mutations 则应该保持简单且纯粹,只负责修改状态。

一般的开发实践是,当需要对状态进行同步操作时,使用 mutations;而需要进行异步操作时,使用 actions。通过这样的划分,可以更好地组织代码,提高应用的可维护性和扩展性。

15、Vuex如何做持久化存储

在 Vuex 中实现持久化存储的一种常见方式是使用插件。下面介绍一个使用 vuex-persistedstate 插件来实现持久化存储的示例:

  1. 首先,安装 vuex-persistedstate 插件:
npm install vuex-persistedstate
  1. 在你的 Vuex store 文件中,引入 vuex-persistedstatecreatePersistedState
import createPersistedState from 'vuex-persistedstate';
import * as Cookies from 'js-cookie'; // 如果要将状态保存在 cookie 中,需要同时安装并引入 js-cookie
// 导出 Vuex store 实例之前,使用 createPersistedState 插件创建持久化存储
export default new Vuex.Store({
  // ...
  plugins: [
    createPersistedState({
      // 可以设置存储的方式,默认为 localStorage
      storage: window.localStorage, 
      // 或者存储在 cookie 中
      // storage: {
      //   getItem: key => Cookies.get(key),
      //   setItem: (key, value) => Cookies.set(key, value, { expires: 365, secure: true }),
      //   removeItem: key => Cookies.remove(key)
      // },
    })
  ]
});

在上述代码中,我们通过 createPersistedState 创建了一个持久化存储的插件,并将其作为 Vuex store 的插件使用。

可以通过设置 storage 参数来指定持久化存储的方式,默认使用 window.localstorage,也可以选择使用 cookie。如果使用 cookie 存储,请确保安装和引入了 js-cookie

这样,当你的应用使用 Vuex 存储数据时,状态将自动在刷新页面或重新加载应用时从存储中恢复,并始终保持同步。

使用 vuex-persistedstate 插件可以方便地实现 Vuex 的持久化存储,避免数据丢失或重新初始化的问题,提供更好的用户体验。

16、Vue设置代理

在 Vue 中设置代理可以通过配置 vue.config.js 文件来实现。下面是一个简单示例:

  1. 在项目的根目录下创建一个名为 vue.config.js 的文件。
  2. vue.config.js 文件中添加以下内容:
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://api.example.com',  // 设置你要代理的目标 API 地址
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''  // 将请求地址中的 /api 替换为空字符串
        }
      }
    }
  }
}

上述代码将所有以 /api 开头的请求代理到 http://api.example.com 目标 API 地址。

  • target 参数指定了目标 API 地址,将请求代理到该地址。
  • changeOrigin 参数用于控制是否改变请求头中的 Origin 字段,设置为 true 表示启用。
  • pathRewrite 参数用于修改请求路径,上述示例中将 /api 替换为空字符串,即将 /api/users 重写为 /users
  1. 保存并关闭 vue.config.js 文件。
  2. 重新运行开发服务器,并访问以 /api 开头的请求。例如,如果你有一个请求地址为 /api/users,那么它会被代理到 http://api.example.com/users

通过以上步骤,你就可以在 Vue 项目中设置代理,将请求转发到其他服务器或服务端 API 上。这对于解决跨域请求或在开发环境中与后端进行交互非常有用。

17、Vue项目打包上线

在将 Vue 项目打包并上线之前,你需要进行以下步骤:

  1. 确保你的 Vue 项目已经完成并可以正常运行。
  2. 首先,你需要对项目进行打包。在项目根目录下运行以下命令:
npm run build

这将在项目的 dist 目录下生成一个生产环境的打包文件。

  1. 将生成的打包文件部署到服务器或托管服务上。你可以使用任何适合你的方式,例如将文件上传到服务器,使用云服务提供商(如阿里云、腾讯云等)的对象存储,将静态文件托管到 GitHub Pages 或 Netlify 等。
  2. 配置服务器或托管服务,以便正确处理路由。默认情况下,Vue Router 使用的是history模式,这将导致在刷新页面或直接访问指定路由时出现 404 错误。为了解决这个问题,你需要配置服务器以始终返回index.html文件。
  • 如果你使用的是 Nginx,可以在配置文件中添加以下内容:
location / {
  try_files $uri $uri/ /index.html;
}
  • 如果你使用的是 Apache,可以利用 .htaccess 文件,在你的项目根目录下创建一个名为 .htaccess 的文件,并将以下内容复制粘贴进去:
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>
  1. 这样,无论用户直接访问哪个路由或刷新页面,都会返回 index.html 文件,然后由 Vue Router 来处理。
  2. 测试部署是否成功。你可以访问你的域名或提供的托管服务的 URL,确保应用在生产环境下运行正常。

以上就是将 Vue 项目打包并上线的一般步骤。请根据你的具体情况和需求进行相应的调整。

18、Vue路由模式

Vue 路由提供了两种模式:hash 模式和 history 模式。

  1. Hash 模式(默认):
  • 在 hash 模式下,URL 中会带有一个 # 符号,例如:http://example.com/#/home
  • 使用 hash 模式时,路由的改变不会导致浏览器向服务器发送请求,而是通过监听 URL 中的 hash 变化来切换视图。
  • 这种模式对于简单的项目或不支持服务端配置的静态文件托管非常方便。
  • 可以通过在 router 对象的配置中设置 mode: 'hash' 来启用该模式(默认)。
  1. History 模式:
  • 在 history 模式下,URL 不会带有额外的符号,例如:http://example.com/home
  • 使用 history 模式时,需要服务器的支持来处理路由请求。服务器需要配置,以始终返回主页 index.html,从而允许前端路由来处理页面切换。
  • 这种模式更加友好,没有额外的符号,并且对 SEO 更友好。
  • 可以通过在 router 对象的配置中设置 mode: 'history' 来启用该模式。

你可以根据实际需求选择适合的路由模式。如果你需要更简单的配置或不需要服务端配置,那么使用默认的 hash 模式即可。如果你需要去掉 URL 中的 # 符号或对 SEO 更加友好,那么可以选择 history 模式,并确保服务器正确配置。

例如,要切换到 history 模式,你可以进行以下步骤:

  1. 在 Vue 项目的 router/index.js 文件中,添加 mode: 'history' 配置:
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
  history: createWebHistory(),
  routes: [
    // 路由配置...
  ],
});
export default router;
  1. 在服务器配置中,确保所有路由请求都返回主页 index.html。具体服务器配置的方法取决于你使用的具体服务器软件,例如 Nginx 或 Apache,请根据相应的文档进行配置。

请根据你的项目需求和服务器环境选择适合的路由模式,并根据需要进行相应的配置。

19、介绍一下SPA以及SPA有什么缺点

SPA (单页应用)是一种在 Web 开发中常见的应用架构模式。相比传统的多页应用,SPA 只有一个 HTML 页面,它使用 JavaScript 进行动态加载内容和路由导航,提供了更流畅的用户体验。

SPA 的特点包括:

  1. 单页面:SPA 只有一个初始的 HTML 页面,内容通过 AJAX 或 WebSocket 进行异步加载和渲染,用户交互时只更新页面的一部分而不是整个页面的重新加载。
  2. 动态加载:SPA 使用异步加载技术,按需从服务器请求数据或页面片段,并以 JSON 或其他格式传递数据,然后通过前端 JavaScript 渲染到页面上。
  3. 前后端分离:SPA 使用前后端分离的架构,后端只提供数据接口,前端负责处理数据和渲染页面。
  4. 路由导航:SPA 使用前端路由来管理不同的页面状态,通过 URL 的变化实现页面间的切换,避免了整页刷新。

优点:

  1. 更好的用户体验:由于只更新页面的局部内容,SPA 提供了更流畅的用户体验,无需频繁的页面刷新,用户感觉更快、更接近原生应用。
  2. 减少服务器负载:SPA 仅需要加载初始页面一次,并通过异步加载数据和页面片段,减轻了服务器的负载。
  3. 前后端分离:SPA 的前后端分离架构,使得前端开发和后端开发可以并行进行,提高了开发效率和代码的可维护性。
  4. 更好的可扩展性:由于前后端分离,可以独立优化和扩展前端和后端的功能,更容易实现跨平台、跨设备的应用。

缺点:

  1. 首次加载耗时:由于 SPA 需要加载整个应用的 JavaScript 代码和初始数据,首次加载时可能会较慢,尤其在移动网络环境下。
  2. SEO 不友好:由于 SPA 的内容是通过 JavaScript 动态生成的,搜索引擎爬虫可能无法正确解析和索引页面,对 SEO 不利。需要额外的工作来改善 SEO。
  3. 内存占用较大:由于 SPA 在运行时需要保持整个应用的状态,包括路由状态和页面状态,因此可能占用较多的内存。
  4. 安全性考虑:由于前端负责渲染页面和处理数据,需要特别关注前端安全性,避免恶意代码或攻击者获取敏感信息。

对于具体的项目和需求,可以根据以上的优点和缺点来选择是否使用 SPA 架构。

20、Vue路径传值

在 Vue 中,可以使用路由参数来传递数值或其他数据。以下是一种常见的方式来实现路径传值:

  1. 在路由配置中定义动态路由参数:
    router/index.js 文件中,可以定义带有参数的路由,通过冒号 : 来标记参数部分。例如,定义一个名为 id 的参数:
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
  {
    path: '/user/:id',
    name: 'User',
    component: UserComponent
  },
  // 其他路由...
];
const router = createRouter({
  history: createWebHistory(),
  routes,
});
export default router;
  1. 在组件中获取路由参数:
    在目标组件中,可以通过 $route.params 对象来获取路由参数的值。例如,在上面的例子中,可以在 UserComponent 组件中获取 id 参数:
<template>
  <div>
    <h2>User Page</h2>
    <p>User ID: {{ $route.params.id }}</p>
  </div>
</template>
<script>
export default {
  // ...
};
</script>
  1. 通过路由链接传递参数:
    在其他组件或模板中,可以通过 <router-link> 标签来生成带有参数的路由链接。例如,在一个用户列表页面中,可以生成带有特定用户 ID 的链接:
<template>
  <div>
    <h2>User List</h2>
    <ul>
      <li v-for="user in userList" :key="user.id">
        <router-link :to="'/user/' + user.id">{{ user.name }}</router-link>
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  data() {
    return {
      userList: [
        { id: 1, name: 'John' },
        { id: 2, name: 'Jane' },
        // ...
      ]
    };
  }
};
</script>

通过以上步骤,你可以在 Vue 中实现路径传值,将参数从一个组件传递到另一个组件,并在目标组件中获取和使用这些参数。请根据实际需求,在路由配置和组件中适当地使用路径传值的方式。

21、路由导航守卫有哪些

在 Vue Router 中,路由导航守卫用于在路由跳转前后执行一些逻辑。它们提供了一种方式来控制路由的访问权限、处理未保存的表单数据、执行加载指示等操作。以下是 Vue Router 中常用的路由导航守卫:

  1. 全局前置守卫 (beforeEach):在路由切换开始之前执行,常用于进行全局权限验证或拦截。
router.beforeEach((to, from, next) => {
  // 验证用户登录状态
  if (to.meta.requiresAuth && !isAuthenticated()) {
    next('/login');
  } else {
    next();
  }
});
  1. 全局解析守卫 (beforeResolve):在路由解析之前触发,用于确保异步路由组件被解析完毕。
router.beforeResolve((to, from, next) => {
  // 确保异步组件加载完毕
  if (to.name === 'AsyncComponent' && !to.meta.loaded) {
    // 执行异步加载逻辑
    asyncLoadComponent()
      .then(() => {
        to.meta.loaded = true; // 标记组件已加载
        next();
      })
      .catch(() => {
        // 加载失败处理
        next({ name: 'Error' });
      });
  } else {
    next();
  }
});
  1. 全局后置钩子 (afterEach):在路由切换完成之后执行,常用于执行一些与路由无关的操作,如页面标题设置等。
router.afterEach((to, from) => {
  // 设置页面标题
  document.title = to.meta.title || 'My App';
});
  1. 路由内部守卫 (beforeEnter):在路由配置中单独定义的守卫,用于限制访问某个特定路由。
const routes = [
  {
    path: '/admin',
    component: AdminComponent,
    beforeEnter: (to, from, next) => {
      // 验证用户是否具有管理员权限
      if (isAdmin()) {
        next();
      } else {
        next('/login');
      }
    },
  },
];
  1. 组件内的守卫:在组件中定义的 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave 等守卫,分别在组件被添加、更新和离开路由时触发,用于执行组件相关的逻辑。
export default {
  // 进入路由前的守卫
  beforeRouteEnter(to, from, next) {
    // ...
    next();
  },
  // 路由更新前的守卫
  beforeRouteUpdate(to, from, next) {
    // ...
    next();
  },
  // 离开路由前的守卫
  beforeRouteLeave(to, from, next) {
    // ...
    next();
  },
};

以上是常用的路由导航守卫。你可以根据实际需求,在 Vue Router 中使用这些守卫来控制路由访问权限、处理异步加载、设置页面标题等操作。





相关文章
|
1月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
66 1
|
3月前
|
Web App开发 前端开发 Linux
「offer来了」浅谈前端面试中开发环境常考知识点
该文章归纳了前端开发环境中常见的面试知识点,特别是围绕Git的使用进行了详细介绍,包括Git的基本概念、常用命令以及在团队协作中的最佳实践,同时还涉及了Chrome调试工具和Linux命令行的基础操作。
「offer来了」浅谈前端面试中开发环境常考知识点
|
4月前
|
存储 XML 移动开发
前端大厂面试真题
前端大厂面试真题
|
2月前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
4月前
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
【8月更文挑战第18天】
58 2
|
4月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
46 0
|
4月前
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
44 个 React 前端面试问题
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?