美团前端一面手写面试题

news2024/11/15 21:33:56

实现斐波那契数列

// 递归
function fn (n){
    if(n==0) return 0
    if(n==1) return 1
    return fn(n-2)+fn(n-1)
}
// 优化
function fibonacci2(n) {
    const arr = [1, 1, 2];
    const arrLen = arr.length;

    if (n <= arrLen) {
        return arr[n];
    }

    for (let i = arrLen; i < n; i++) {
        arr.push(arr[i - 1] + arr[ i - 2]);
    }

    return arr[arr.length - 1];
}
// 非递归
function fn(n) {
    let pre1 = 1;
    let pre2 = 1;
    let current = 2;

    if (n <= 2) {
        return current;
    }

    for (let i = 2; i < n; i++) {
        pre1 = pre2;
        pre2 = current;
        current = pre1 + pre2;
    }

    return current;
}

判断是否是电话号码

function isPhone(tel) {
    var regx = /^1[34578]\d{9}$/;
    return regx.test(tel);
}

查找数组公共前缀(美团)

题目描述

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"

示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

答案

const longestCommonPrefix = function (strs) {
  const str = strs[0];
  let index = 0;
  while (index < str.length) {
    const strCur = str.slice(0, index + 1);
    for (let i = 0; i < strs.length; i++) {
      if (!strs[i] || !strs[i].startsWith(strCur)) {
        return str.slice(0, index);
      }
    }
    index++;
  }
  return str;
};

请实现 DOM2JSON 一个函数,可以把一个 DOM 节点输出 JSON 的格式

<div>
  <span>
    <a></a>
  </span>
  <span>
    <a></a>
    <a></a>
  </span>
</div>

把上面dom结构转成下面的JSON格式

{
  tag: 'DIV',
  children: [
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] }
      ]
    },
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] },
        { tag: 'A', children: [] }
      ]
    }
  ]
}

实现代码如下:

function dom2Json(domtree) {
  let obj = {};
  obj.name = domtree.tagName;
  obj.children = [];
  domtree.childNodes.forEach((child) => obj.children.push(dom2Json(child)));
  return obj;
}

字符串最长的不重复子串

题目描述

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。


示例 1:

输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

示例 4:

输入: s = ""
输出: 0

答案

const lengthOfLongestSubstring = function (s) {
  if (s.length === 0) {
    return 0;
  }

  let left = 0;
  let right = 1;
  let max = 0;
  while (right <= s.length) {
    let lr = s.slice(left, right);
    const index = lr.indexOf(s[right]);

    if (index > -1) {
      left = index + left + 1;
    } else {
      lr = s.slice(left, right + 1);
      max = Math.max(max, lr.length);
    }
    right++;
  }
  return max;
};

实现千位分隔符

// 保留三位小数
parseToMoney(1234.56); // return '1,234.56'
parseToMoney(123456789); // return '123,456,789'
parseToMoney(1087654.321); // return '1,087,654.321'
function parseToMoney(num) {
  num = parseFloat(num.toFixed(3));
  let [integer, decimal] = String.prototype.split.call(num, '.');
  integer = integer.replace(/\d(?=(\d{3})+$)/g, '$&,');
  return integer + '.' + (decimal ? decimal : '');
}

参考 前端进阶面试题详细解答

数组中的数据根据key去重

给定一个任意数组,实现一个通用函数,让数组中的数据根据 key 排重:

const dedup = (data, getKey = () => {} ) => {
  // todo
}
let data = [
  { id: 1, v: 1 },
  { id: 2, v: 2 },
  { id: 1, v: 1 },
];

// 以 id 作为排重 key,执行函数得到结果
// data = [
//   { id: 1, v: 1 },
//   { id: 2, v: 2 },
// ];

实现

const dedup = (data, getKey = () => { }) => {
    const dateMap = data.reduce((pre, cur) => {
        const key = getKey(cur)
        if (!pre[key]) {
            pre[key] = cur
        }
        return pre
    }, {})
    return Object.values(dateMap)
}

使用

let data = [
    { id: 1, v: 1 },
    { id: 2, v: 2 },
    { id: 1, v: 1 },
];
console.log(dedup(data, (item) => item.id))

// 以 id 作为排重 key,执行函数得到结果
// data = [
//   { id: 1, v: 1 },
//   { id: 2, v: 2 },
// ];

实现事件总线结合Vue应用

Event Bus(Vue、Flutter 等前端框架中有出镜)和 Event Emitter(Node中有出镜)出场的“剧组”不同,但是它们都对应一个共同的角色—— 全局事件总线

全局事件总线,严格来说不能说是观察者模式,而是发布-订阅模式。它在我们日常的业务开发中应用非常广。

如果只能选一道题,那这道题一定是 Event Bus/Event Emitter 的代码实现——我都说这么清楚了,这个知识点到底要不要掌握、需要掌握到什么程度,就看各位自己的了。

在Vue中使用Event Bus来实现组件间的通讯

Event Bus/Event Emitter 作为全局事件总线,它起到的是一个沟通桥梁的作用。我们可以把它理解为一个事件中心,我们所有事件的订阅/发布都不能由订阅方和发布方“私下沟通”,必须要委托这个事件中心帮我们实现。

在Vue中,有时候 A 组件和 B 组件中间隔了很远,看似没什么关系,但我们希望它们之间能够通信。这种情况下除了求助于 Vuex 之外,我们还可以通过 Event Bus 来实现我们的需求。

创建一个 Event Bus(本质上也是 Vue 实例)并导出:

const EventBus = new Vue()
export default EventBus

在主文件里引入EventBus,并挂载到全局:

import bus from 'EventBus的文件路径'
Vue.prototype.bus = bus

订阅事件:

// 这里func指someEvent这个事件的监听函数
this.bus.$on('someEvent', func)

发布(触发)事件:

// 这里params指someEvent这个事件被触发时回调函数接收的入参
this.bus.$emit('someEvent', params)

大家会发现,整个调用过程中,没有出现具体的发布者和订阅者(比如上面的PrdPublisherDeveloperObserver),全程只有bus这个东西一个人在疯狂刷存在感。这就是全局事件总线的特点——所有事件的发布/订阅操作,必须经由事件中心,禁止一切“私下交易”!

下面,我们就一起来实现一个Event Bus(注意看注释里的解析):

class EventEmitter {
  constructor() {
    // handlers是一个map,用于存储事件与回调之间的对应关系
    this.handlers = {}
  }

  // on方法用于安装事件监听器,它接受目标事件名和回调函数作为参数
  on(eventName, cb) {
    // 先检查一下目标事件名有没有对应的监听函数队列
    if (!this.handlers[eventName]) {
      // 如果没有,那么首先初始化一个监听函数队列
      this.handlers[eventName] = []
    }

    // 把回调函数推入目标事件的监听函数队列里去
    this.handlers[eventName].push(cb)
  }

  // emit方法用于触发目标事件,它接受事件名和监听函数入参作为参数
  emit(eventName, ...args) {
    // 检查目标事件是否有监听函数队列
    if (this.handlers[eventName]) {
      // 如果有,则逐个调用队列里的回调函数
      this.handlers[eventName].forEach((callback) => {
        callback(...args)
      })
    }
  }

  // 移除某个事件回调队列里的指定回调函数
  off(eventName, cb) {
    const callbacks = this.handlers[eventName]
    const index = callbacks.indexOf(cb)
    if (index !== -1) {
      callbacks.splice(index, 1)
    }
  }

  // 为事件注册单次监听器
  once(eventName, cb) {
    // 对回调函数进行包装,使其执行完毕自动被移除
    const wrapper = (...args) => {
      cb.apply(...args)
      this.off(eventName, wrapper)
    }
    this.on(eventName, wrapper)
  }
}

在日常的开发中,大家用到EventBus/EventEmitter往往提供比这五个方法多的多的多的方法。但在面试过程中,如果大家能够完整地实现出这五个方法,已经非常可以说明问题了,因此楼上这个EventBus希望大家可以熟练掌握。学有余力的同学

实现reduce方法

  • 初始值不传怎么处理
  • 回调函数的参数有哪些,返回值如何处理。
Array.prototype.myReduce = function(fn, initialValue) {
  var arr = Array.prototype.slice.call(this);
  var res, startIndex;

  res = initialValue ? initialValue : arr[0]; // 不传默认取数组第一项
  startIndex = initialValue ? 0 : 1;

  for(var i = startIndex; i < arr.length; i++) {
    // 把初始值、当前值、索引、当前数组返回去。调用的时候传到函数参数中 [1,2,3,4].reduce((initVal,curr,index,arr))
    res = fn.call(null, res, arr[i], i, this); 
  }
  return res;
}

对象数组如何去重

根据每个对象的某一个具体属性来进行去重

const responseList = [
  { id: 1, a: 1 },
  { id: 2, a: 2 },
  { id: 3, a: 3 },
  { id: 1, a: 4 },
];
const result = responseList.reduce((acc, cur) => {
    const ids = acc.map(item => item.id);
    return ids.includes(cur.id) ? acc : [...acc, cur];
}, []);
console.log(result); // -> [ { id: 1, a: 1}, {id: 2, a: 2}, {id: 3, a: 3} ]

解析 URL Params 为对象

let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
parseParam(url)
/* 结果
{ user: 'anonymous',
  id: [ 123, 456 ], // 重复出现的 key 要组装成数组,能被转成数字的就转成数字类型
  city: '北京', // 中文需解码
  enabled: true, // 未指定值得 key 约定为 true
}
*/


function parseParam(url) {
  const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 将 ? 后面的字符串取出来
  const paramsArr = paramsStr.split('&'); // 将字符串以 & 分割后存到数组中
  let paramsObj = {};
  // 将 params 存到对象中
  paramsArr.forEach(param => {
    if (/=/.test(param)) { // 处理有 value 的参数
      let [key, val] = param.split('='); // 分割 key 和 value
      val = decodeURIComponent(val); // 解码
      val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判断是否转为数字

      if (paramsObj.hasOwnProperty(key)) { // 如果对象有 key,则添加一个值
        paramsObj[key] = [].concat(paramsObj[key], val);
      } else { // 如果对象没有这个 key,创建 key 并设置值
        paramsObj[key] = val;
      }
    } else { // 处理没有 value 的参数
      paramsObj[param] = true;
    }
  })

  return paramsObj;
}


实现数组的乱序输出

主要的实现思路就是:

  • 取出数组的第一个元素,随机产生一个索引值,将该第一个元素和这个索引对应的元素进行交换。
  • 第二次取出数据数组第二个元素,随机产生一个除了索引为1的之外的索引值,并将第二个元素与该索引值对应的元素进行交换
  • 按照上面的规律执行,直到遍历完成
var arr = [1,2,3,4,5,6,7,8,9,10];
for (var i = 0; i < arr.length; i++) {
  const randomIndex = Math.round(Math.random() * (arr.length - 1 - i)) + i;
  [arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
}
console.log(arr)

还有一方法就是倒序遍历:

var arr = [1,2,3,4,5,6,7,8,9,10];
let length = arr.length,
    randomIndex,
    temp;
  while (length) {
    randomIndex = Math.floor(Math.random() * length--);
    temp = arr[length];
    arr[length] = arr[randomIndex];
    arr[randomIndex] = temp;
  }
console.log(arr)

实现 getValue/setValue 函数来获取path对应的值

// 示例
var object = { a: [{ b: { c: 3 } }] }; // path: 'a[0].b.c'
var array = [{ a: { b: [1] } }]; // path: '[0].a.b[0]'

function getValue(target, valuePath, defaultValue) {}

console.log(getValue(object, "a[0].b.c", 0)); // 输出3
console.log(getValue(array, "[0].a.b[0]", 12)); // 输出 1
console.log(getValue(array, "[0].a.b[0].c", 12)); // 输出 12

实现

/**
 * 测试属性是否匹配
 */
export function testPropTypes(value, type, dev) {
  const sEnums = ['number', 'string', 'boolean', 'undefined', 'function']; // NaN
  const oEnums = ['Null', 'Object', 'Array', 'Date', 'RegExp', 'Error'];
  const nEnums = [
    '[object Number]',
    '[object String]',
    '[object Boolean]',
    '[object Undefined]',
    '[object Function]',
    '[object Null]',
    '[object Object]',
    '[object Array]',
    '[object Date]',
    '[object RegExp]',
    '[object Error]',
  ];
  const reg = new RegExp('\\[object (.*?)\\]');

  // 完全匹配模式,type应该传递类似格式[object Window] [object HTMLDocument] ...
  if (reg.test(type)) {
    // 排除nEnums的12种
    if (~nEnums.indexOf(type)) {
      if (dev === true) {
        console.warn(value, 'The parameter type belongs to one of 12 types:number string boolean undefined Null Object Array Date RegExp function Error NaN');
      }
    }

    if (Object.prototype.toString.call(value) === type) {
      return true;
    }

    return false;
  }
}
const syncVarIterator = {
  getter: function (obj, key, defaultValue) {
    // 结果变量
    const defaultResult = defaultValue === undefined ? undefined : defaultValue;

    if (testPropTypes(obj, 'Object') === false && testPropTypes(obj, 'Array') === false) {
      return defaultResult;
    }

    // 结果变量,暂时指向obj持有的引用,后续将可能被不断的修改
    let result = obj;

    // 得到知道值
    try {
      // 解析属性层次序列
      const keyArr = key.split('.');

      // 迭代obj对象属性
      for (let i = 0; i < keyArr.length; i++) {
        // 如果第 i 层属性存在对应的值则迭代该属性值
        if (result[keyArr[i]] !== undefined) {
          result = result[keyArr[i]];

          // 如果不存在则返回未定义
        } else {
          return defaultResult;
        }
      }
    } catch (e) {
      return defaultResult;
    }

    // 返回获取的结果
    return result;
  },
  setter: function (obj, key, val) {
    // 如果不存在obj则返回未定义
    if (testPropTypes(obj, 'Object') === false) {
      return false;
    }

    // 结果变量,暂时指向obj持有的引用,后续将可能被不断的修改
    let result = obj;

    try {
      // 解析属性层次序列
      const keyArr = key.split('.');

      let i = 0;

      // 迭代obj对象属性
      for (; i < keyArr.length - 1; i++) {
        // 如果第 i 层属性对应的值不存在,则定义为对象
        if (result[keyArr[i]] === undefined) {
          result[keyArr[i]] = {};
        }

        // 如果第 i 层属性对应的值不是对象(Object)的一个实例,则抛出错误
        if (!(result[keyArr[i]] instanceof Object)) {
          throw new Error('obj.' + keyArr.splice(0, i + 1).join('.') + 'is not Object');
        }

        // 迭代该层属性值
        result = result[keyArr[i]];
      }

      // 设置属性值
      result[keyArr[i]] = val;

      return true;
    } catch (e) {
      return false;
    }
  },
};

使用promise来实现

创建 enhancedObject 函数

const enhancedObject = (target) =>
  new Proxy(target, {
    get(target, property) {
      if (property in target) {
        return target[property];
      } else {
        return searchFor(property, target); //实际使用时要对value值进行复位
      }
    },
  });

let value = null;
function searchFor(property, target) {
  for (const key of Object.keys(target)) {
    if (typeof target[key] === "object") {
      searchFor(property, target[key]);
    } else if (typeof target[property] !== "undefined") {
      value = target[property];
      break;
    }
  }
  return value;
}

使用 enhancedObject 函数

const data = enhancedObject({
  user: {
    name: "test",
    settings: {
      theme: "dark",
    },
  },
});

console.log(data.user.settings.theme); // dark
console.log(data.theme); // dark

以上代码运行后,控制台会输出以下代码:

dark
dark

通过观察以上的输出结果可知,使用 enhancedObject 函数处理过的对象,我们就可以方便地访问普通对象内部的深层属性。

Promise并行限制

就是实现有并行限制的Promise调度器问题

class Scheduler {
  constructor() {
    this.queue = [];
    this.maxCount = 2;
    this.runCounts = 0;
  }
  add(promiseCreator) {
    this.queue.push(promiseCreator);
  }
  taskStart() {
    for (let i = 0; i < this.maxCount; i++) {
      this.request();
    }
  }
  request() {
    if (!this.queue || !this.queue.length || this.runCounts >= this.maxCount) {
      return;
    }
    this.runCounts++;

    this.queue.shift()().then(() => {
      this.runCounts--;
      this.request();
    });
  }
}

const timeout = time => new Promise(resolve => {
  setTimeout(resolve, time);
})

const scheduler = new Scheduler();

const addTask = (time,order) => {
  scheduler.add(() => timeout(time).then(()=>console.log(order)))
}


addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');
scheduler.taskStart()
// 2
// 3
// 1
// 4

用Promise实现图片的异步加载

let imageAsync=(url)=>{
            return new Promise((resolve,reject)=>{
                let img = new Image();
                img.src = url;
                img.οnlοad=()=>{
                    console.log(`图片请求成功,此处进行通用操作`);
                    resolve(image);
                }
                img.οnerrοr=(err)=>{
                    console.log(`失败,此处进行失败的通用操作`);
                    reject(err);
                }
            })
        }

imageAsync("url").then(()=>{
    console.log("加载成功");
}).catch((error)=>{
    console.log("加载失败");
})

实现数组元素求和

  • arr=[1,2,3,4,5,6,7,8,9,10],求和
let arr=[1,2,3,4,5,6,7,8,9,10]
let sum = arr.reduce( (total,i) => total += i,0);
console.log(sum);

  • arr=[1,2,3,[[4,5],6],7,8,9],求和
var = arr=[1,2,3,[[4,5],6],7,8,9]
let arr= arr.toString().split(',').reduce( (total,i) => total += Number(i),0);
console.log(arr);

递归实现:

let arr = [1, 2, 3, 4, 5, 6] 

function add(arr) {
    if (arr.length == 1) return arr[0] 
    return arr[0] + add(arr.slice(1)) 
}
console.log(add(arr)) // 21

类数组转化为数组的方法

const arrayLike=document.querySelectorAll('div')

// 1.扩展运算符
[...arrayLike]
// 2.Array.from
Array.from(arrayLike)
// 3.Array.prototype.slice
Array.prototype.slice.call(arrayLike)
// 4.Array.apply
Array.apply(null, arrayLike)
// 5.Array.prototype.concat
Array.prototype.concat.apply([], arrayLike)

实现防抖函数(debounce)

防抖函数原理:把触发非常频繁的事件合并成一次去执行 在指定时间内只执行一次回调函数,如果在指定的时间内又触发了该事件,则回调函数的执行时间会基于此刻重新开始计算

防抖动和节流本质是不一样的。防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行

eg. 像百度搜索,就应该用防抖,当我连续不断输入时,不会发送请求;当我一段时间内不输入了,才会发送一次请求;如果小于这段时间继续输入的话,时间会重新计算,也不会发送请求。

手写简化版:

// func是用户传入需要防抖的函数
// wait是等待时间
const debounce = (func, wait = 50) => {
  // 缓存一个定时器id
  let timer = 0
  // 这里返回的函数是每次用户实际调用的防抖函数
  // 如果已经设定过定时器了就清空上一次的定时器
  // 开始一个新的定时器,延迟执行用户传入的方法
  return function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      func.apply(this, args)
    }, wait)
  }
}

适用场景:

  • 文本输入的验证,连续输入文字后发送 AJAX 请求进行验证,验证一次就好
  • 按钮提交场景:防止多次提交按钮,只执行最后提交的一次
  • 服务端验证场景:表单验证需要服务端配合,只执行一段连续的输入事件的最后一次,还有搜索联想词功能类似

实现防抖函数(debounce)

防抖函数原理:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

那么与节流函数的区别直接看这个动画实现即可。

手写简化版:

// 防抖函数
const debounce = (fn, delay) => {
  let timer = null;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};

适用场景:

  • 按钮提交场景:防止多次提交按钮,只执行最后提交的一次
  • 服务端验证场景:表单验证需要服务端配合,只执行一段连续的输入事件的最后一次,还有搜索联想词功能类似

生存环境请用lodash.debounce

实现Array.isArray方法

Array.myIsArray = function(o) {
  return Object.prototype.toString.call(Object(o)) === '[object Array]';
};

console.log(Array.myIsArray([])); // true

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/356337.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vulnhub Kioptrix4

总结&#xff1a;sql注入&#xff0c;受限shell绕过&#xff0c;mysql提权 目录 下载地址 漏洞分析 信息收集 sql注入 ssh登录绕过受限shell 提权 下载地址 Kioptrix4_Hyper_v.rar (Size: 210 MB)Download: http://www.kioptrix.com/dlvm/Kioptrix4_Hyper_v.rarDownload …

Linux驱动开发详细解析

Linux驱动开发详细解析 驱动概念 驱动与底层硬件直接打交道&#xff0c;充当了硬件与应用软件中间的桥梁。 具体任务 读写设备寄存器&#xff08;实现控制的方式&#xff09;完成设备的轮询、中断处理、DMA通信&#xff08;CPU与外设通信的方式&#xff09;进行物理内存向虚…

关于字符设备驱动的通用概念和写法

概述 设备驱动程序可以使用模块的方式动态加载到内核中去。加载模块的方式与以往的应用程序开发有很大的不同。以往在开发应用程序时都有一个 main()函数作为程序的入口点&#xff0c;而在驱动开发时却没有 main()函数&#xff0c;模块在调用 insmod 命令时被加载&#xff0c;…

JVM学习笔记一:类加载子系统

目录 前言 类加载子系统的作用 类加载器角色的位置 类加载器分类 虚拟机自带的加载器 启动类加载器&#xff08;引导类加载器&#xff09; 扩展类加载器 系统类加载器 用户自定义类加载器 什么时候需要自定义类加载器&#xff1f; 如何自定义类加载器&#xff1f; …

【验证码的识别】—— 极验验证码的识别

前言 &#xff08;结尾有彩蛋欧&#xff09; 目前&#xff0c;许多网站采取各种各样的措施来反爬虫&#xff0c;其中一个措施便是使用验证码。随着技术的发展&#xff0c;验证码的花样越来越多。验证码最初是几个数字组合的简单的图形验证码&#xff0c;后来加入了英文字母和混…

《计算机系统基础》——计算机系统导论

文章目录《计算机系统基础》——计算机系统导论计算机的基本组成程序开发与执行过程机器语言汇编语言高级语言程序的转换处理程序的数据流动计算机系统层次结构早期计算机系统1GL2GL现代计算机系统3GL4GL指令集体系结构《计算机系统基础》——计算机系统导论 &#x1f680;接下…

LaTeX中表格过宽解决方案

最近使用LaTeX处理表格时遇到了一件十分棘手的问题&#xff0c;由于内容较多将表格分成了好多列&#xff0c;但将内容填入表格时由于表格宽度过大&#xff0c;导致表格右边溢出了页面无法查看&#xff0c;查阅大量资料与博文后给出如下解决方案&#xff0c;全文代码已部署在Ove…

C#基础练习题,编程题汇总

C#基础练习题&#xff0c;编程题汇总一、C#提取输入的最大整数二、秒数换算为相应的时、分、秒三、C#计算电梯运行用时demo四、C#用一维数组求解问题五、C#程序教小学生学乘法六、C#winfrm简单例题七、C#类继承习题八、C#绘图例子一、C#提取输入的最大整数 编程实现在一行内输…

分布式任务调度(XXL-JOB)

什么是分布式任务调度&#xff1f; 任务调度顾名思义&#xff0c;就是对任务的调度&#xff0c;它是指系统为了完成特定业务&#xff0c;基于给定时间点&#xff0c;给定时间间隔或者给定执行次数自动执行任务。通常任务调度的程序是集成在应用中的&#xff0c;比如&#xff1a…

[译]PostgreSQL16-新特性-新增IO统计视图:pg_stat_io

PostgreSQL16-新特性-新增IO统计视图&#xff1a;pg_stat_io我们DBA常遇到的问题是&#xff1a;如何优化数据库的IO操作&#xff1f;获取PG服务产生的所有IO情况历来都是一个挑战。首先&#xff0c;PG将IO行为范围内为写WAL和读写数据目录(也就是数据文件)。真正的挑战是&#…

解决实际项目中stalled时间过久的问题

背景 在公司参与了一个做度量统计的项目&#xff0c;该项目的特点是页面上的表格、卡片、图标非常多。项目经常出现一种情况&#xff1a;页面加载速度较慢&#xff0c;开始怀疑是由于计算量较大&#xff0c;后端接口相应速度较慢。优化了一版后端接口后&#xff08;加缓存、优…

方法区和元空间有什么关系?

一.什么是方法区&#xff1f; 方法区属于是 JVM 运行时数据区域的一块逻辑区域&#xff0c;是各个线程共享的内存区域。 《Java 虚拟机规范》只是规定了有方法区这么个概念和它的作用&#xff0c;方法区到底要如何实现那就是虚拟机自己要考虑的事情了。也就是说&#xff0c;在…

电子技术——分析放大器的高频响应的有用工具

电子技术——分析放大器的高频响应的有用工具 在前几章我们使用米勒效应估计了CS和CE放大器模型的高频响应 fHf_HfH​ &#xff0c;以及分析了其限制和影响因素。然而&#xff0c;这个方法不能有效的处理负载是容性负载 CLC_LCL​ 的情况。同时&#xff0c;这个方法不能扩展到更…

【FPGA】Verilog:实现十六进制七段数码管显示 | 7-Segment Display

写在前面&#xff1a;本章主要内容为理解七点数码管显示的概念&#xff0c;并使用 Verilog 实现。生成输入信号后通过仿真确认各门的动作&#xff0c;通过 FPGA 检查在 Verilog 中实现的电路的操作。 Ⅰ. 前置知识 七段数码管是利用多重输出功能的非常有用的元件。该元件用于字…

spring+springboot+mybatis志愿者报名系统 ssm java

本盐城疫情防控志愿者报名系统以SSM作为框架&#xff0c;B/S模式以及MySql作为后台运行的数据库。本系统主要包括以下功能模块&#xff1a;防疫视频、优秀事迹、报名条件、在线报名等模块&#xff0c;通过这些模块的实现能够基本满足日常盐城疫情防控的操作。 根据盐城疫情防控…

基于微信小程序的中国各地美食推荐平台小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.…

【js】export default也在影响项目性能呢

这里写目录标题介绍先说结论分析解决介绍 无意间看到一个关于export与exprot default对比的话题&#xff0c; 于是对二者关于性能方面&#xff0c;有了想法&#xff0c;二者的区别&#xff0c;仅仅是在于写法吗&#xff1f; 于是&#xff0c;有了下面的测试。 先说结论 太长…

.NET3.5安装步骤及相关问题。

.NET3.5全称 Microsoft.NETFramework3.5 最新版本-.NET4.8 第一步打开控制面板 windows系统打开控制面板 选择程序 选择.NET3.5安装。 可能会出现问题。 解决方案&#xff1a; 报错代码80240438的常用解决办法&#xff1a; 方法一&#xff1a;检测windows update servic…

【NLP实战】Python字符串处理

一、Python字符串基本操作 1. 去掉前后的特殊字符&#xff08;strip&#xff09; Python的strip操作可以去除字符串前后的空格&#xff08;不改变原串&#xff09;下例将前后的空格均删掉&#x1f447; str 人工智能 str.strip() # OUT:人工智能rstrip删除右边的空格&a…

linux016之安装JDK

linux上安装JDK&#xff1a; 一&#xff1a;首先检查一下linux上是否已经安装有jdk rpm -qa | grep jdk &#xff1a;查询目前系统已安装的jdk&#xff0c;直接复制该命令执行&#xff0c;如下图就是系统已经安装好的JDK rpm -qa | grep -i java | xargs -n1 rpm -e --nodeps &…