iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >面试官:你了解axios的原理吗?有看过它的源码吗?
  • 574
分享到

面试官:你了解axios的原理吗?有看过它的源码吗?

react.jsjavascript前端githubtypescript原力计划 2023-10-11 11:10:52 574人浏览 泡泡鱼
摘要

面试官:你了解axiOS的原理吗?有看过它的源码吗? 一、axios的基本使用 关于 axios 的基本使用,上篇文章已经有所涉及,这里再稍微回顾一下: 发送请求 import axios from

在这里插入图片描述

面试官:你了解axiOS的原理吗?有看过它的源码吗?

一、axios的基本使用

关于 axios 的基本使用,上篇文章已经有所涉及,这里再稍微回顾一下:

发送请求

import axios from 'axios';axios(config) // 直接传入配置axios(url[, config]) // 传入url和配置axios[method](url[, option]) // 直接调用请求方式方法,传入url和配置axios[method](url[, data[, option]]) // 直接调用请求方式方法,传入data、url和配置axios.request(option) // 调用 request 方法const axiosInstance = axios.create(config)// axiosInstance 也具有以上 axios 的能力axios.all([axiosInstance1, axiosInstance2]).then(axios.spread(response1, response2))// 调用 all 和传入 spread 回调

请求拦截器

axios.interceptors.request.use(function (config) {    // 这里写发送请求前处理的代码    return config;}, function (error) {    // 这里写发送请求错误相关的代码    return Promise.reject(error);});

响应拦截器

axios.interceptors.response.use(function (response) {    // 这里写得到响应数据后处理的代码    return response;}, function (error) {    // 这里写得到错误响应处理的代码    return Promise.reject(error);});

取消请求

// 方式一const CancelToken = axios.CancelToken;const source = CancelToken.source();axios.get('xxxx', {  cancelToken: source.token})// 取消请求 (请求原因是可选的)source.cancel('主动取消请求');// 方式二const CancelToken = axios.CancelToken;let cancel;axios.get('xxxx', {  cancelToken: new CancelToken(function executor(c) {    cancel = c;  })});cancel('主动取消请求');

二、实现一个简易版axios

构建一个 Axios 构造函数,核心代码为 request 方法:

class Axios {    constructor() {    }    request(config) {        return new Promise(resolve => {            const {url = '', method = 'get', data = {}} = config;            // 发送ajax请求            const xhr = new XMLHttpRequest();            xhr.open(method, url, true);            xhr.onload = function() {                console.log(xhr.responseText)                resolve(xhr.responseText);            }            xhr.send(data);        })    }}

导出 axios 实例:

// 最终导出axios的方法,即实例的request方法function CreateAxiosFn() {    let axios = new Axios();    let req = axios.request.bind(axios);    return req;}// 得到最后的全局变量axioslet axios = CreateAxiosFn();

上述就已经能够实现 axios({ }) 这种方式的请求。下面是来实现下 axios.method() 这种形式的请求:

// 定义get,post...方法,挂在到Axios原型上const methodsArr = ['get', 'delete', 'head', 'options', 'put', 'patch', 'post'];methodsArr.forEach(met => {    Axios.prototype[met] = function() {        console.log('执行'+met+'方法');        // 处理单个方法        if (['get', 'delete', 'head', 'options'].includes(met)) { // 2个参数(url[, config])            return this.request({                method: met,                url: arguments[0],                ...arguments[1] || {}            })        } else { // 3个参数(url[,data[,config]])            return this.request({                method: met,                url: arguments[0],                data: arguments[1] || {},                ...arguments[2] || {}            })        }    }})

Axios.prototype 上的方法搬运到 request 上。首先实现一个工具类,实现将 b 方法混入到 a,并且修改 this 指向:

const utils = {  extend(a,b, context) {    for(let key in b) {      if (b.hasOwnProperty(key)) {        if (typeof b[key] === 'function') {          a[key] = b[key].bind(context);        } else {          a[key] = b[key]        }      }          }  }}

修改导出的方法:

function CreateAxiosFn() {  let axios = new Axios();    let req = axios.request.bind(axios);  // 增加代码  utils.extend(req, Axios.prototype, axios)    return req;}

构建拦截器的构造函数:

class InterceptorsManage {  constructor() {    this.handlers = [];  }  use(fullfield, rejected) {    this.handlers.push({      fullfield,      rejected    })  }}

实现 axios.interceptors.response.useaxios.interceptors.request.use

class Axios {    constructor() {        // 新增代码        this.interceptors = {            request: new InterceptorsManage,            response: new InterceptorsManage        }    }    request(config) {        ...    }}

执行语句 axios.interceptors.response.useaxios.interceptors.request.use 的时候,实现获取 axios 实例上的 interceptors 对象,然后再获取 responserequest 拦截器,再执行对应的拦截器的 use 方法。

Axios 上的方法和属性搬到 request 过去:

function CreateAxiosFn() {  let axios = new Axios();    let req = axios.request.bind(axios);  // 混入方法, 处理axios的request方法,使之拥有get,post...方法  utils.extend(req, Axios.prototype, axios)  // 新增代码  utils.extend(req, axios)  return req;}

现在 request 也有了 interceptors 对象,在发送请求的时候,会先获取 request 拦截器的 handlers 的方法来执行。

首先将执行 ajax 的请求封装成一个方法:

request(config) {    this.sendAjax(config)}sendAjax(config){    return new Promise(resolve => {        const {url = '', method = 'get', data = {}} = config;        // 发送ajax请求        console.log(config);        const xhr = new XMLHttpRequest();        xhr.open(method, url, true);        xhr.onload = function() {            console.log(xhr.responseText)            resolve(xhr.responseText);        };        xhr.send(data);    })}

获得 handlers 中的回调:

request(config) {    // 拦截器和请求组装队列    let chain = [this.sendAjax.bind(this), undefined] // 成对出现的,失败回调暂时不处理    // 请求拦截    this.interceptors.request.handlers.forEach(interceptor => {        chain.unshift(interceptor.fullfield, interceptor.rejected)    })    // 响应拦截    this.interceptors.response.handlers.forEach(interceptor => {        chain.push(interceptor.fullfield, interceptor.rejected)    })    // 执行队列,每次执行一对,并给promise赋最新的值    let promise = Promise.resolve(config);    while(chain.length > 0) {        promise = promise.then(chain.shift(), chain.shift())    }    return promise;}

chains 大概是 ['fulfilled1','reject1','fulfilled2','reject2','this.sendAjax','undefined','fulfilled2','reject2','fulfilled1','reject1'] 这种形式。这样就能够成功实现一个简易版 axios

三、源码分析

首先看看目录结构:

目录结构

axios 发送请求有很多实现的方法,实现入口文件为 axios.js

function createInstance(defaultConfig) {  var context = new Axios(defaultConfig);  // instance指向了request方法,且上下文指向context,所以可以直接以 instance(option) 方式调用   // Axios.prototype.request 内对第一个参数的数据类型判断,使我们能够以 instance(url, option) 方式调用  var instance = bind(Axios.prototype.request, context);  // 把Axios.prototype上的方法扩展到instance对象上,  // 并指定上下文为context,这样执行Axios原型链上的方法时,this会指向context  utils.extend(instance, Axios.prototype, context);  // Copy context to instance  // 把context对象上的自身属性和方法扩展到instance上  // 注:因为extend内部使用的forEach方法对对象做for in 遍历时,只遍历对象本身的属性,而不会遍历原型链上的属性  // 这样,instance 就有了  defaults、interceptors 属性。  utils.extend(instance, context);  return instance;}// Create the default instance to be exported 创建一个由默认配置生成的axios实例var axios = createInstance(defaults);// Factory for creating new instances 扩展axios.create工厂函数,内部也是 createInstanceaxios.create = function create(instanceConfig) {  return createInstance(mergeConfig(axios.defaults, instanceConfig));};// Expose all/spreadaxios.all = function all(promises) {  return Promise.all(promises);};axios.spread = function spread(callback) {  return function wrap(arr) {    return callback.apply(null, arr);  };};module.exports = axios;

主要核心是 Axios.prototype.request,各种请求方式的调用实现都是在 request 内部实现的,简单看下 request 的逻辑:

Axios.prototype.request = function request(config) {  // Allow for axios('example/url'[, config]) a la fetch api  // 判断 config 参数是否是 字符串,如果是则认为第一个参数是 URL,第二个参数是真正的config  if (typeof config === 'string') {    config = arguments[1] || {};    // 把 url 放置到 config 对象中,便于之后的 mergeConfig    config.url = arguments[0];  } else {    // 如果 config 参数是否是 字符串,则整体都当做config    config = config || {};  }  // 合并默认配置和传入的配置  config = mergeConfig(this.defaults, config);  // 设置请求方法  config.method = config.method ? config.method.toLowerCase() : 'get';  };// 在 Axios 原型上挂载 'delete', 'get', 'head', 'options' 且不传参的请求方法,实现内部也是 requestutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {  Axios.prototype[method] = function(url, config) {    return this.request(utils.merge(config || {}, {      method: method,      url: url    }));  };});// 在 Axios 原型上挂载 'post', 'put', 'patch' 且传参的请求方法,实现内部同样也是 requestutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {  Axios.prototype[method] = function(url, data, config) {    return this.request(utils.merge(config || {}, {      method: method,      url: url,      data: data    }));  };});

request 入口参数为 config,可以说 config 贯彻了 axios 的一生。axios 中的 config 主要分布在这几个地方:

  • 默认配置 defaults.js
  • config.method 默认为 get
  • 调用 createInstance 方法创建 axios 实例,传入的 config
  • 直接或间接调用 request 方法,传入的 config
// axios.js// 创建一个由默认配置生成的axios实例var axios = createInstance(defaults);// 扩展axios.create工厂函数,内部也是 createInstanceaxios.create = function create(instanceConfig) {  return createInstance(mergeConfig(axios.defaults, instanceConfig));};// Axios.js// 合并默认配置和传入的配置config = mergeConfig(this.defaults, config);// 设置请求方法config.method = config.method ? config.method.toLowerCase() : 'get';

从源码中,可以看到优先级:默认配置对象 default < method:get < Axios的实例属性 this.default < request参数。

下面重点看看 request 方法:

Axios.prototype.request = function request(config) {    // Hook up interceptors middleware 创建拦截器链。dispatchRequest 是重中之重,后续重点  var chain = [dispatchRequest, undefined];  // push各个拦截器方法 注意:interceptor.fulfilled 或 interceptor.rejected 是可能为undefined  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {    // 请求拦截器逆序 注意此处的 forEach 是自定义的拦截器的forEach方法    chain.unshift(interceptor.fulfilled, interceptor.rejected);  });  this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {    // 响应拦截器顺序 注意此处的 forEach 是自定义的拦截器的forEach方法    chain.push(interceptor.fulfilled, interceptor.rejected);  });  // 初始化一个 promise 对象,状态为 resolved,接收到的参数为已经处理合并过的 config 对象  var promise = Promise.resolve(config);  // 循环拦截器的链  while (chain.length) {    promise = promise.then(chain.shift(), chain.shift()); // 每一次向外弹出拦截器  }  // 返回 promise  return promise;};

拦截器 interceptors 是在构建 axios 实例化的属性:

function Axios(instanceConfig) {  this.defaults = instanceConfig;  this.interceptors = {    request: new InterceptORManager(), // 请求拦截    response: new InterceptorManager() // 响应拦截  };}

InterceptorManager 构造函数:

// 拦截器的初始化 其实就是一组钩子函数function InterceptorManager() {  this.handlers = [];}// 调用拦截器实例的 use 时就是往钩子函数中 push 方法InterceptorManager.prototype.use = function use(fulfilled, rejected) {  this.handlers.push({    fulfilled: fulfilled,    rejected: rejected  });  return this.handlers.length - 1;};// 拦截器是可以取消的,根据 use 的时候返回的 ID,把某一个拦截器方法置为 null// 不能用 splice 或者 slice 的原因是 删除之后 id 就会变化,导致之后的顺序或者是操作不可控InterceptorManager.prototype.eject = function eject(id) {  if (this.handlers[id]) {    this.handlers[id] = null;  }};// 这就是在 Axios 的 request 方法中 中循环拦截器的方法 forEach 循环执行钩子函数InterceptorManager.prototype.forEach = function forEach(fn) {  utils.forEach(this.handlers, function forEachHandler(h) {    if (h !== null) {      fn(h);    }  });}

请求拦截器方法是被 unshift 到拦截器中,响应拦截器是被 push 到拦截器中的。最终它们会拼接上一个叫 dispatchRequest 的方法被后续的 promise 顺序执行:

var utils = require('./../utils');var transformData = require('./transformData');var isCancel = require('../cancel/isCancel');var defaults = require('../defaults');var isAbsoluteURL = require('./../helpers/isAbsoluteURL');var combineURLs = require('./../helpers/combineURLs');// 判断请求是否已被取消,如果已经被取消,抛出已取消function throwIfCancellationRequested(config) {  if (config.cancelToken) {    config.cancelToken.throwIfRequested();  }}module.exports = function dispatchRequest(config) {  throwIfCancellationRequested(config);  // 如果包含 baseUrl,并且不是 config.url 绝对路径,组合 baseUrl 以及 config.url  if (config.baseURL && !isAbsoluteURL(config.url)) {    // 组合 baseURL 与 url 形成完整的请求路径    config.url = combineURLs(config.baseURL, config.url);  }  config.headers = config.headers || {};  // 使用 /lib/defaults.js 中的 transformRequest 方法,对 config.headers 和 config.data 进行格式化  // 比如将 headers 中的 Accept,Content-Type 统一处理成大写  // 比如如果请求正文是一个 Object 会格式化为 JSON 字符串,并添加 application/json;charset=utf-8 的 Content-Type  // 等一系列操作  config.data = transformData(    config.data,    config.headers,    config.transformRequest  );  // 合并不同配置的 headers,config.headers 的配置优先级更高  config.headers = utils.merge(    config.headers.common || {},    config.headers[config.method] || {},    config.headers || {}  );  // 删除 headers 中的 method 属性  utils.forEach(    ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],    function cleanHeaderConfig(method) {      delete config.headers[method];    }  );  // 如果 config 配置了 adapter,使用 config 中配置 adapter 的替代默认的请求方法  var adapter = config.adapter || defaults.adapter;  // 使用 adapter 方法发起请求(adapter 根据浏览器环境或者 node 环境会有不同)  return adapter(config).then(    // 请求正确返回的回调    function onAdapterResolution(response) {      // 判断是否已经取消了请求,如果取消了请求抛出已取消      throwIfCancellationRequested(config);      // 使用 /lib/defaults.js 中的 transformResponse 方法,对服务器返回的数据进行格式化      // 例如,使用 JSON.parse 对响应正文进行解析      response.data = transformData(        response.data,        response.headers,        config.transformResponse      );      return response;    },    // 请求失败的回调    function onAdapterRejection(reason) {      if (!isCancel(reason)) {        throwIfCancellationRequested(config);        if (reason && reason.response) {          reason.response.data = transformData(            reason.response.data,            reason.response.headers,            config.transformResponse          );        }      }      return Promise.reject(reason);    }  );};
  • dispatchRequest 中首先判断是否已经取消了请求,如果已取消,抛出已取消
  • 合并不同配置的 headers,config.headers 的配置优先级更高
  • 使用 config.adapter 发起请求(adapter 根据浏览器环境或者 Node 环境会有不同)

源码中有一个比较有趣的点是 transformData 这个方法:

var utils = require('./../utils');var defaults = require('../defaults');module.exports = function transformData(data, headers, fns) {    utils.forEach(fns, function transform(fn) {    data = fn(data, headers);  });  return data;};

transformData 其实就是执行 config.transformRequestconfig.transformResponse

// 使用 /lib/defaults.js 中的 transformRequest 方法,对 config.headers 和 config.data 进行格式化// 比如将 headers 中的 Accept,Content-Type 统一处理成大写// 比如如果请求正文是一个 Object 会格式化为 JSON 字符串,并添加 application/json;charset=utf-8 的 Content-Type// 等一系列操作config.data = transformData(  config.data,  config.headers,  config.transformRequest);// 使用 /lib/defaults.js 中的 transformResponse 方法,对服务器返回的数据进行格式化// 例如,使用 JSON.parse 对响应正文进行解析response.data = transformData(  response.data,  response.headers,  config.transformResponse);

四、总结

axios 是一个基于 Promise 的 HTTP 请求客户端,具有强大的拦截器功能,支持请求和响应的拦截处理,同时提供了丰富的配置选项。在实际开发中,可以利用 axios 来发起 HTTP 请求,处理响应数据,实现前后端的数据交互。通过深入理解 axios 的原理和源码,可以更好地使用和扩展它,满足复杂的业务需求。

参考文献

  • https://juejin.cn/post/6856706569263677447#heading-4
  • https://juejin.cn/post/6844903907500490766
  • https://GitHub.com/axios/axios

来源地址:https://blog.csdn.net/weixin_52898349/article/details/133267717

--结束END--

本文标题: 面试官:你了解axios的原理吗?有看过它的源码吗?

本文链接: https://www.lsjlt.com/news/428326.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 面试官:你了解axios的原理吗?有看过它的源码吗?
    面试官:你了解axios的原理吗?有看过它的源码吗? 一、axios的基本使用 关于 axios 的基本使用,上篇文章已经有所涉及,这里再稍微回顾一下: 发送请求 import axios from...
    99+
    2023-10-11
    react.js javascript 前端 github typescript 原力计划
  • 你真的了解 PHP 面试和 JavaScript npm 吗?
    PHP和JavaScript是两种广泛应用于前端和后端的编程语言。由于其强大的功能和灵活性,它们在现代Web开发中已成为不可或缺的部分。在这篇文章中,我们将深入探讨PHP面试和JavaScript npm,以帮助您更好地了解它们的特点和用法...
    99+
    2023-09-17
    面试 javascript npm
  • 面试官会问到的 Laravel 文件管理问题:你准备好了吗?
    作为 Laravel 开发者,你可能会在面试中被问到与文件管理相关的问题。这些问题通常涉及到如何在 Laravel 中管理文件、如何上传和下载文件、如何处理文件路径等等。在本文中,我们将讨论一些面试官可能会问到的 Laravel 文件管理问...
    99+
    2023-06-23
    面试 文件 laravel
  • PHP 对象容器和 Shell:你了解它们的工作原理吗?
    在 PHP 中,对象容器和 Shell 是两个非常重要的概念。本文将介绍它们的工作原理,并演示一些代码示例。 对象容器 对象容器是一个用于存储和管理对象的容器。在 PHP 中,我们可以使用 SPL(标准 PHP 库)中的 ArrayObj...
    99+
    2023-06-23
    对象 容器 shell
  • 你准备好了吗?面试官会问你关于 Go 打包 NumPy 的问题!
    随着人工智能和大数据技术的飞速发展,Python 作为一种广泛使用的高级编程语言,被越来越多的人所熟知和应用。在 Python 中,NumPy 是一个十分重要的第三方库,它提供了高效的多维数组操作、数学函数和随机数生成等功能。 然而,在实际...
    99+
    2023-08-24
    打包 面试 numpy
  • Java的三大版本,你有了解过吗?
    目录 一、JavaSE 二、JavaME 三、JavaEE   一、JavaSE JavaSE是Java平台的标准版,它提供了Java语言的核心API和基本功能,适用于开发普通的桌面应用程序、命令行工具和服务器端应用程序等。下面是一个简...
    99+
    2023-09-14
    java 开发语言
  • Vue的diff算法原理你真的了解吗
    目录思维导图0. 从常见问题引入1. 生成虚拟dom1. h方法实现2. render方法实现3. 再次渲染2. diff算法1. 对常见的dom做优化情况1:末尾追加一个元素(头和...
    99+
    2024-04-02
  • PHP面试:你真的理解对象和Unix吗?
    在PHP开发领域,面试官往往会问到关于对象和Unix的问题,这些问题看似简单,但是却需要你对PHP的底层有深入的理解。本文将帮助你更好地理解这些问题。 对象 PHP是一种面向对象的语言,面向对象的编程思想是将数据和操作数据的方法封装在一个...
    99+
    2023-07-06
    面试 对象 unix
  • PHP 数组面试:你真的了解这些函数吗?
    PHP 是一种常用的服务器端编程语言,而数组则是 PHP 中最常用的数据结构之一。在 PHP 面试中,经常会涉及到数组相关的问题。因此,今天我们来探讨一下 PHP 数组的一些常用函数,以及它们的用法和作用。 array() 函数 ar...
    99+
    2023-06-18
    数组 面试 函数
  • Python 内存管理的工作原理,你了解吗?
    Python 为开发者提供了许多便利,其中最大的便利之一是其几乎无忧的内存管理。开发者无需手动为 Python 中的对象和数据结构分配、跟踪和释放内存。运行时会为你完成所有这些工作,因此你可以专注于解决实际问题,而不是争论机器级细节。尽管如...
    99+
    2023-05-14
    Python 内存管理
  • 你了解 PHP 面试中常见的索引问题吗?
    PHP 是一种广泛使用的服务器端编程语言,因其易于学习和使用而受到广泛欢迎。在 PHP 面试中,常常会问到与索引相关的问题。在本文中,我们将介绍一些 PHP 面试中常见的索引问题,并提供相应的代码演示。 一、什么是索引? 在数据库中,索引是...
    99+
    2023-08-19
    面试 索引 开发技术
  • Java接口面试:你真的了解如何打包吗?
    在Java开发中,接口是一种非常常见的程序设计模式,它能够让代码更加灵活和可扩展。不过,在面试中,考官往往会深入探讨接口的打包问题,因此,掌握如何打包接口是非常重要的。 接下来,本文将从以下几个方面介绍Java接口打包的相关知识: 什...
    99+
    2023-08-18
    接口 面试 打包
  • 面试官可能会问到 Java 中的索引缓存,你准备好了吗?
    Java 中的索引缓存是开发人员在进行数据库开发时经常需要面对的问题。索引缓存是指数据库中使用的一种技术,通过将经常使用的索引存储在内存中,可以大大提高数据库的查询效率。在面试中,面试官可能会问到 Java 中的索引缓存,所以作为一名开发人...
    99+
    2023-10-29
    索引 缓存 面试
  • 从编程算法角度看ASP和Laravel的面试:你能通过吗?
    ASP和Laravel是两种广泛应用于网络开发的框架,而作为开发人员,我们需要在面试中展示自己对这两种框架的深刻理解和应用能力。本文将从编程算法角度,探讨ASP和Laravel的面试,希望能够帮助读者在面试中更好地展现自己。 一、ASP和L...
    99+
    2023-07-06
    laravel 面试 编程算法
  • Java编程中的Path类:你了解它的所有应用场景吗?
    在Java编程中,Path类是一个非常重要的类,它用来表示文件或目录的路径。Path类提供了许多方法来操作文件系统中的路径,包括路径的解析、规范化、比较、转换等等。在本文中,我们将深入探讨Path类的所有应用场景,并演示一些实际的代码示例...
    99+
    2023-07-29
    编程算法 异步编程 path
  • ASP、索引、二维码、Laravel:你真的了解它们之间的联系吗?
    在现代的软件开发中,不同的技术和工具被用来实现各种不同的功能。ASP、索引、二维码和Laravel是其中的一些。但是,你是否知道这些技术之间的联系和交互?在本文中,我们将深入探讨这些技术之间的关系,并通过演示代码来帮助你更好地理解它们。 ...
    99+
    2023-06-19
    索引 二维码 laravel
  • 二维码和NPM:Java面试中的高频考点,你掌握了吗?
    在Java开发中,二维码和NPM是两个常见的概念,也是Java面试中的高频考点。本文将介绍二维码和NPM的基本概念和用法,并提供相关的演示代码,帮助读者更好地掌握这两个知识点。 一、二维码 1.概念 二维码是一种可以储存大量信息的矩阵条码...
    99+
    2023-09-11
    面试 二维码 npm
  • 你真的了解Python日志打包load的工作原理吗?
    Python是一门广泛应用于各种领域的编程语言。在日志处理方面,Python也提供了很多的库和工具。其中,日志打包和load是日志处理中常用的操作之一。本文将深入讲解Python中日志打包和load的工作原理,并演示一些实用的代码。 一、日...
    99+
    2023-10-29
    日志 打包 load
  • 你对Python和Unix同步有多了解?面试官会如何考察你的知识?
    Python和Unix是两种非常重要的计算机科学技术。Python是一种高级编程语言,它被广泛应用于各种领域,包括科学计算、数据分析、机器学习等。Unix是一种操作系统,它被广泛应用于服务器、超级计算机等领域。在现代计算机科学中,Pytho...
    99+
    2023-06-25
    unix 同步 面试
  • 你了解Python响应文件框架的工作原理吗?
    Python是一种高级编程语言,它被广泛用于Web开发、数据分析、机器学习等领域。Python的一个重要特性是其丰富的库和框架,其中之一就是响应文件框架。这个框架非常有用,因为它可以帮助我们处理HTTP请求和响应,本文将介绍Python响应...
    99+
    2023-07-20
    响应 文件 框架
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作