2023前端面试题(硬货-持续更新)
创始人
2025-05-28 19:29:57
0

目录

1.CSS3 中伪元素 after 和 before

2.盒模型概念

3.元素居中方法

4.防抖和节流

5.深拷贝和浅拷贝?

6.forEach用什么方法结束?

7.怎么结束for循环的一层?

8.for in 和 for of ?

9.如果要取数组第100条数据,怎么取?

10.数组哪些方法改变原数组哪些方法不改变原数组?

11.SSR服务端渲染流程 及SEO,服务端渲染框架?

12.前端项目中环境变量怎么处理,怎么配置?

13.axios有封装过吗?

14.后台管理侧边栏权限管理?


1.CSS3 中伪元素 after 和 before

伪元素选择器可以帮助我们利用CSS创建新标签元素,而不需要HTML标签,从而简化HTML结构。两个重要的伪元素是::before、::after。伪元素前面是用两个冒号表示。

        :: before:在元素内部的前面插入内容

        :: after:在元素内部的后面插入内容

注:

        before 和 after 创建的元素属于行内元素

        before 和 after 创建的元素在文档树中找不到,所以称之为伪元素

        语法:element::before{}

        before 和 after 必须要有 content 属性

        伪元素选择器和标签选择器权重一样:0,0,0,1

2.盒模型概念

标准盒子模型和怪异盒模型

        1)一个盒子由外到内可以分成四个部分:margin(外边距)、border(边框)、padding(内边距)、content(内容)。会发现margin、border、padding是CSS属性,因此可以通过这三个属性来控制盒子的这三个部分。而content则是HTML元素的内容。

        2)width和height属性设置的就是盒子的宽度和高度。盒子的宽度和高度的计算方式由box-sizing属性控制。

        box-sizing属性值
        content-box:默认值,width和height属性分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距、边框、外边距。
        border-box:为元素设定的width和height属性决定了元素的边框盒。就是说,为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。通过从已设定的宽度和高度分别减去 边框 和 内边距 才能得到内容的宽度和高度。
        inherit:规定应从父元素继承box-sizing属性的值

        当box-sizing:content-box时,这种盒子模型成为标准盒子模型,当box-sizing: border-box时,这种盒子模型称为IE盒子模型(怪异盒模型)。

3.元素居中方法

        1)行内元素实现水平垂直居中:

        text-align: center;(text-align: center只能实现文本的垂直居中)

        line-height: 50px;(line-height不能实现多行文本的垂直居中)

        padding:50px;(不固定高度的垂直居中 通过设置padding实现)

        使用display设置为table,配合样式vertical-align设置为middle来实现,如下:        

    父元素{display:table;}子元素{display:table-cell;vertical-align:middle;}

        2)块级元素实现水平垂直居中:

        第一种方式:使用弹性盒模型实现水平垂直居中

display: flex;
justify-content: center;
align-items: center;

        第二种方式:采取绝对定位配合margin的方式实现(这种方式有缺陷 需要知道固定的宽度和高度才行)

position: absolute;
left:50%;
top:50%;
margin-left: -50px;(高度设置了100px,margin-left就是宽度的一半)
margin-top: -50px;(宽度也设置了100px,margin-top就是高度的一半)

        第三种方式:可以采取借助css3的变形属性transform来实现的方式实现

position: absolute;
left:50%;
top:50%;
transform: translate(-50%,-50%);(在当前位置偏移自身宽高的一半)

        第四种方式:需要盒子有宽高,但是不需要去计算偏移盒子的宽高

position: absolute;
left:0;
top:0;
right:0;
bottom:0;margin:auto;
height:100px;
width:100px;

4.防抖和节流

防抖(Debounce)和节流(Throttle)都是用来控制某个函数在一定时间内触发次数,两者都是为了减少触发频率,以便提高性能或者说避免资源浪费。毕竟JS操作DOM对象的代价还是十分昂贵的。

应用场景:处理一些频繁触发的事件,例如mousedown、mousemove、keyup、keydown等,不然的话,页面很可能会十分卡顿哦~

        1)防抖

防抖就是指触发事件后在 n 秒内函数只能执行一次,最后一次触发的函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

function debounce(fn, delay){let timerId = nullreturn function(){const context = thisif(timerId){window.clearTimeout(timerId)}timerId = setTimeout(()=>{fn.apply(context, arguments)timerId = null},delay)}}

        2)节流

节流就是指连续触发事件但是在 n 秒中只执行一次函数,第一次触发的函数。节流会稀释函数的执行频率

function throttle(fn, delay){let canUse = truereturn function(){if(canUse){fn.apply(this, arguments)canUse = falsesetTimeout(()=>canUse = true, delay)}}}

5.深拷贝和浅拷贝?

        1)浅拷贝

        创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是值类型和string类型,拷贝的就是基本类型的值;如果属性是引用类型,拷贝的就是内存地址(string类型除外),所以修改其中一个对象,就会影响到另一个对象。

                1   Object.assign(target, source)

                2   = 赋值

        2)深拷贝

        将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象和原对象的修改不会相互影响.

                1   JSON.parse(JSON.stringify(obj1))

                2   递归

                3   **jquery**  $.extent(true,{},sourceObj)

                4   **es5写法** require('lodash')

                5   **es6写法** [object/array].cloneDeep(sourceObj)

        3)二者区别

        最根本的区别在于是否真正获取一个对象的复制实体,而不是引用,假设B复制了A,修改A的时候,看B是否发生变化:

        (1).如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)

        (2).如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)

简单的来说:

如果拷贝的时候共享被引用的对象就是浅拷贝,如果被引用的对象也拷贝一份出来就是深拷贝。(深拷贝就是说重新new一个对象,然后把之前的那个对象的属性值在重新赋值给这个用户)

6.forEach用什么方法结束?

正常终止for循环,我们可以使用break关键字来实现;

forEach循环,不能使用break和continue这两个关键字;

因为这两个关键字要在循环中使用,而forEach中所执行的是callback,callback是个函数所以不能使用;

使用 return 的话,只能跳出本次循环执行下一次循环,并不会终止forEach循环;

运用抛出异常(try catch)throw new Error('error message');

7.怎么结束for循环的一层?

        1)continue

当程序运行到 continue; 语句时,会终止当前的这一次循环,进入下一次的循环中。

        2)break

当程序运行到 break; 语句时,会结束当前的循环,执行循环后面(外边)的语句。

如果多层循环,只会退出当前的循环,执行该循环后的语句,外循环不受影响。

一般配合判断语句使用

        3)return

当程序运行到 return; 语句时,会终止循环,结束当前方法。

8.for in 和 for of ?

for in 和 for of 简单来说就是它们两者都可以用于遍历。

for in 和 for of 的本质区别

        1)使用的目标不一样

        1-1、for in 适用于 可枚举属性,例如 对象、数组、字符串。

可枚举属性:属性的 enumerable 值为 true 就为可枚举的,通过Object.getOwnPropertyDescriptors() 或 Object.prototype.propertyIsEnumerable() 进行查看 / 验证 

        1-2、for of 适用于 可迭代对象,像Array、String、Map、Set、函数的arguments对象、nodeList对象

可迭代:ES6中,具有Symbol.iterator 属性,它对应的值是一个函数,调用这个函数后可得到一个对象,每次调用这个对象的next() 方法能得到目标的每一项,只要符合这个特点就是可迭代的

        2)遍历的范围不一样

for in 能遍历自身的可枚举属性 && 原型上的可枚举属性

for of 一般只能遍历自身的可枚举属性(具体和迭代器内部的实现有关)

        3)得到的结果不一样

for in 得到的是key(并且不能保证顺序)

for of 一般得到的是value(具体和迭代器内部的实现有关)

9.如果要取数组第100条数据,怎么取?

  1. Array[100]
  2. for / for in / for of / forEach,但是循环到第一百条之后的数据就白跑了,需要结束循环,节省性能

10.数组哪些方法改变原数组哪些方法不改变原数组?

1)会改变原数组的方法

        1.1 push

作用:push 方法往数组里面添加元素,返回数组的长度,原数组会发生改变。

        1.2 unshift

作用:unshift 方法会在数组的开头添加一个元素,它会返回数组新的长度,原数组会发生改变。

        1.3 pop

作用:pop() 方法从数组中删除最后一个元素,并返回该元素的值,原数组会发生改变。        

        1.4 shift

作用:shift() 方法从数组中删除第一个元素,并返回该元素的值原数组会发生改变。

        1.5 sort

作用:sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的。它返回的就是排序后的数组,原数组会发生改变。

注意:因为 sort 的默认排序是将元素转化为字符串后排序的,所以上述代码中的排序结果可能不是我们想要的,想要获得正确的排序结果,我们可以传入一个函数,来规定排序的规则。例:arr5.sort((a, b) => a - b);

        1.6 splice

作用:splice() 方法用于添加或删除数组中的元素,如果删除一个元素,则返回一个元素的数组。 如果未删除任何元素,则返回空数组,原数组会发生改变。

        1.7 reverse

作用:reverse() 方法用于颠倒数组中元素的顺序,原数组会发生改变。

2)不会改变原数组的方法

        2.1 concat

作用:concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本,不会改变原数组。

        2.2 join

作用:join() 方法用于把数组中的所有元素转换一个字符串,元素是通过指定的分隔符进行分隔的,不会改变原数组。

        2.3 reduce

作用:reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。reduce 方法的使用情况稍微复杂,不熟悉的小伙伴建议去官网好好学学,它的应用范围还是挺宽泛的,不会改变原数组。

        2.4 map

作用:map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值,不会改变原数组。

        2.5 forEach

作用:forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数,不会改变原数组。

注意:forEach 方法没有返回值,而且它也不会改变原数组,有些同学误以为 forEach 会改变原数组,通常是因为在 forEach 方法的回调函数中,我们自己做了更改原数组的操作。

        2.6 filter

作用:filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,不会改变原数组。

        2.7 slice

作用:slice() 方法可从已有的数组中返回选定的元素。slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分,不会改变原数组。

        2.8 findIndex

作用:findIndex 接收一个测试函数,也可以叫做条件函数,最终返回满足该测试函数的元素的索引位置,如果没有找到符合条件的元素,则返回-1。如果满足条件的有多个,那么只会返回第一个满足条件的元素索引。

总结

数组方法基本上每一版本的 JS 中都会增加一些,本篇文章主要总结了我们开发中比较常用而且容易混淆的。至于为什么要区分是否更改原数组,那就得根据实际情况来决定了。打个比方,如果有一道算法题,可以用数组方法中的 unshift 和 slice 来解决,那么选用哪一个呢?首先 unshift 会改变原数组,它的事件复杂度是 O(n),而 slice 方法不会改变原数组,它的时间复杂度是 O(1),改用哪个一目了然。

11.SSR服务端渲染流程 及SEO,服务端渲染框架?

页面渲染的流程:

        浏览器通过请求得到一个HTML文本

        渲染进程解析HTML文本,构建DOM树

        解析HTML的同时,如果遇到内联样式或者样式脚本,则下载并构建样式规则(stytle rules),若遇到JavaScript脚本,则会下载执行脚本。

        DOM树和样式规则构建完成之后,渲染进程将两者合并成渲染树(render tree)

        渲染进程开始对渲染树进行布局,生成布局树(layout tree)

        渲染进程对布局树进行绘制,生成绘制记录

        渲染进程的对布局树进行分层,分别栅格化每一层,并得到合成帧

        渲染进程将合成帧信息发送给GPU进程显示到页面中

服务端渲染(SSR):服务端渲染就是在浏览器请求页面URL的时候,服务端将我们需要的HTML文本组装好,并返回给浏览器,这个HTML文本被浏览器解析之后,不需要经过 JavaScript 脚本的执行,即可直接构建出希望的 DOM 树并展示到页面中。这个服务端组装HTML的过程,叫做服务端渲染。

SSR:

        利:首屏渲染快、利于SEO、可以生成缓存片段,生成静态化文件、节能(对比客户端渲染的耗电)

        弊:用户体验较差、不容易维护,通常前端改了部分html或者css,后端也需要修改。

服务端渲染的模式下,当用户第一次请求页面时,由服务器把需要的组件或页面渲染成 HTML 字符串,然后把它返回给客户端。客户端拿到手的,是可以直接渲染然后呈现给用户的 HTML 内容,不需要为了生成 DOM 内容自己再去跑一遍 JS 代码。使用服务端渲染的网站,可以说是“所见即所得”,页面上呈现的内容,我们在 html 源文件里也能找到。

由于需要在页面加载之前就加载所有页面需要的 JavaScript 库,这使得首次打开页面所需要的时间比较久;

        需要研发专门针对于 SPA 的 Web 框架(各种具备 SSR 能力的框架,包括 Next.js 等)

        搜索引擎爬虫

        浏览器历史记录的问题(基于 pushState 的各种 router)

        首屏加载快: 相比于加载单页应用,我只需要加载当前页面的内容,而不需要像 React 或者 Vue 一样加载全部的 js 文件

        SEO 优化: 对于单页应用,搜索引擎并不能收录到 ajax 爬取数据之后然后再动态 js 渲染出来的页面。

SSR怎么做:开箱即用的SSR脚手架

        目前前端流行的三种技术栈 React, Vue 和 Angula ,已经孵化出对应的服务端渲染框架,开箱即用

        React: Next.js

        Vue: Nuxt.js

        Angula: Nest.js

12.前端项目中环境变量怎么处理,怎么配置?

1)为什么要配置环境变量

在公司,一个项目一般会有开发版本、测试版本、灰度版本和线上版本,每个版本会对应相同或不同的数据库、API地址。为了方便管理,我们通常做成配置文件的形式,根据不同的环境,加载不同的文件。如果手动修改代码中加载配置文件的路径也可以,但是太麻烦,最重要的是很low(无形装逼,最为致命)。

2)实现原理

采用nodejs顶层对象中的process.env(进程环境,返回一个包含用户环境信息的对象。)属性,根据各个环境的配置文件区分和切换环境

3)具体操作(以vue项目为例)

        1、安装依赖:npm install process

        2、在根目录新增五个文件(根据自身情况增减), .env 和 .env.dev 和 .env.pre和 .env.prod和 .env.sit和 .env.uat,分别为默认配置、本地开发配置、灰度配置、生产配置、测试配置1、测试配置2,(ps: VUE_APP是统一标志,后面的拓展名可以任取)

        .env

VUE_APP_TITLE='dev'

        .dev

NODE_ENV = 'development'
VUE_APP_TITLE = 'development'/*请求接口地址*/
VUE_APP_INTERFACE_URL="https://xxx"/*首页地址*/
VUE_APP_URL="http://xxx"/*proxy代理地址*/
VUE_APP_PROXYURL='http://xxx'

        .prod

NODE_ENV = production
VUE_APP_TITLE = 'prod'/*请求接口地址*/
VUE_APP_INTERFACE_URL="https://xxx"/*首页地址*/
VUE_APP_URL="http://xxx"

        3、设置项目启动时默认的环境

只需要在项目启动命令后面修改需要的环境就行,例如我这是npm run dev,把–mode dev改成–mode uat就行了

package.json

"scripts": {"dev": "vue-cli-service serve --mode dev","build": "vue-cli-service build --mode dev","lint": "vue-cli-service lint","build-sit": "vue-cli-service build --mode sit","build-uat": "vue-cli-service build --mode uat","build-pre": "vue-cli-service build --mode pre","build-prod": "vue-cli-service build --mode prod"},

        4、查看环境是否配置成功

在main.js里打印当前环境,输出就成功了

console.log(process.env.NODE_NEV)

13.axios有封装过吗?

1)axios是什么

axios 是一个轻量的 HTTP客户端

基于 XMLHttpRequest 服务来执行 HTTP 请求,支持丰富的配置,支持 Promise,支持浏览器端和 Node.js 端。自Vue2.0起,尤大宣布取消对 vue-resource 的官方推荐,转而推荐 axios。现在 axios 已经成为大部分 Vue 开发者的首选

特性        

从浏览器中创建 XMLHttpRequests

        从 node.js 创建 http请求

        支持 Promise API

        拦截请求和响应

        转换请求数据和响应数据

        取消请求

        自动转换JSON 数据

        客户端支持防御XSRF

基本使用

安装

// 项目中安装

npm install axios --S

// cdn 引入

导入

import axios from 'axios'

发送请求

axios({        url:'xxx',    // 设置请求的地址method:"GET", // 设置请求方法params:{      // get请求使用params进行参数凭借,如果是post请求用datatype: '',page: 1}
}).then(res => {  // res为后端返回的数据console.log(res);   
})//并发请求axios.all([])
function getUserAccount() {return axios.get('/user/12345');
}function getUserPermissions() {return axios.get('/user/12345/permissions');
}axios.all([getUserAccount(), getUserPermissions()]).then(axios.spread(function (res1, res2) {// res1第一个请求的返回的内容,res2第二个请求返回的内容// 两个请求都执行完成才会执行
}));

2)为什么要封装

axios 的 API 很友好,你完全可以很轻松地在项目中直接使用。

不过随着项目规模增大,如果每发起一次HTTP请求,就要把这些比如设置超时时间、设置请求头、根据项目环境判断使用哪个请求地址、错误处理等等操作,都需要写一遍

这种重复劳动不仅浪费时间,而且让代码变得冗余不堪,难以维护。为了提高我们的代码质量,我们应该在项目中二次封装一下 axios 再使用

如果每个页面都发送类似的请求,都要写一堆的配置与错误处理,就显得过于繁琐了

这时候我们就需要对axios进行二次封装,让使用更为便利

举个例子:

axios('http://localhost:3000/data', {// 配置代码method: 'GET',timeout: 1000,withCredentials: true,headers: {'Content-Type': 'application/json',Authorization: 'xxx',},transformRequest: [function (data, headers) {return data;}],// 其他请求配置...
})
.then((data) => {// todo: 真正业务逻辑代码console.log(data);}, (err) => {// 错误处理代码  if (err.response.status === 401) {// handle authorization error}if (err.response.status === 403) {// handle server forbidden error}// 其他错误处理.....console.log(err);
});

3)如何封装

        封装的同时,你需要和 后端协商好一些约定,请求头,状态码,请求超时时间.......

        设置接口请求前缀:根据开发、测试、生产环境的不同,前缀需要加以区分

        请求头 :  来实现一些具体的业务,必须携带一些参数才可以请求(例如:会员业务)

        状态码:   根据接口返回的不同status , 来执行不同的业务,这块需要和后端约定好

        请求方法:根据get、post等方法进行一个再次封装,使用起来更为方便

        请求拦截器:  根据请求的请求头设定,来决定哪些请求可以访问

        响应拦截器:这块就是根据 后端`返回来的状态码判定执行不同业务

        设置接口请求前缀

利用node环境变量来作判断,用来区分开发、测试、生产环境

if (process.env.NODE_ENV === 'development') {axios.defaults.baseURL = 'http://dev.xxx.com'
} else if (process.env.NODE_ENV === 'production') {axios.defaults.baseURL = 'http://prod.xxx.com'
}

在本地调试的时候,还需要在vue.config.js文件中配置devServer实现代理转发,从而实现跨域

devServer: {proxy: {'/proxyApi': {target: 'http://dev.xxx.com',changeOrigin: true,pathRewrite: {'/proxyApi': ''}}}}

设置请求头与超时时间

大部分情况下,请求头都是固定的,只有少部分情况下,会需要一些特殊的请求头,这里将普适性的请求头作为基础配置。当需要特殊请求头时,将特殊请求头作为参数传入,覆盖基础配置

const service = axios.create({...timeout: 30000,  // 请求 30s 超时headers: {get: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'// 在开发中,一般还需要单点登录或者其他功能的通用请求头,可以一并配置进来},post: {'Content-Type': 'application/json;charset=utf-8'// 在开发中,一般还需要单点登录或者其他功能的通用请求头,可以一并配置进来}},
})

封装请求方法

先引入封装好的方法,在要调用的接口重新封装成一个方法暴露出去

// get 请求
export function httpGet({url,params = {}
}) {return new Promise((resolve, reject) => {axios.get(url, {params}).then((res) => {resolve(res.data)}).catch(err => {reject(err)})})
}// post请求
export function httpPost({url,data = {},params = {}
}) {return new Promise((resolve, reject) => {axios({url,method: 'post',transformRequest: [function (data) {let ret = ''for (let it in data) {ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'}return ret}],// 发送的数据data,// url参数params}).then(res => {resolve(res.data)})})
}

把封装的方法放在一个api.js文件中

import { httpGet, httpPost } from './http'export const getorglist = (params = {}) => httpGet({ url: 'apps/api/org/list', params })

页面中就能直接调用

// .vueimport { getorglist } from '@/assets/js/api'getorglist({ id: 200 }).then(res => {console.log(res)
})

这样可以把api统一管理起来,以后维护修改只需要在api.js文件操作即可

请求拦截器

请求拦截器可以在每个请求里加上token,做了统一处理后维护起来也方便

// 请求拦截器
axios.interceptors.request.use(config => {// 每次发送请求之前判断是否存在token// 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况,此处token一般是用户完成登录后储存到localstorage里的token && (config.headers.Authorization = token)return config},error => {return Promise.error(error)})

响应拦截器

响应拦截器可以在接收到响应后先做一层操作,如根据状态码判断登录状态、授权

// 响应拦截器
axios.interceptors.response.use(response => {// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据// 否则的话抛出错误if (response.status === 200) {if (response.data.code === 511) {// 未授权调取授权接口} else if (response.data.code === 510) {// 未登录跳转登录页} else {return Promise.resolve(response)}} else {return Promise.reject(response)}
}, error => {// 我们可以在这里对异常状态作统一处理if (error.response.status) {// 处理请求失败的情况// 对不同返回码对相应处理return Promise.reject(error.response)}
})

14.后台管理侧边栏权限管理?

核心想法:

        1.登陆后获得用户角色,通过角色获得用户的权限,注入权限对应的路由。

        2.刷新页面,从localStorage用角色(更好的方式是通过token)再次获得所属权限,再次注入路由。在管理界面左端循环权限对应的路由菜单。

        3.localStorage存用户的信息(token),权限路由不会存。

所有的路由分为2种:

        公共路由:所有用户可以查看。

        权限路由:当前用户权限所属的路由。

实现控制的方式分两种:

        通过 vue-router addRoutes 方法注入路由实现控制

        通过 vue-router beforeEach 钩子限制路由跳转

一般来讲,需要采用第一种方式,addRoutes注入的方式,第二种每次判断,开销比较大,而且一次性拿不到角色对应的所有路由列表。这个列表需要再登陆后立即渲染在左边。

权限的控制分为好几种:

        一级菜单的权限控制,

        二级菜单的权限控制,

        按钮级别的权限控制。

        前后端约定控制方式有2种:

        后端返回路由控制列表

        前后端约定路由控制列表

15.Vue项目运行后查看网页源代码可以看到页面代码吗?

        1)查看网页源代码是看不到相关页面代码的,能看到的只有:

        html、meta、title、link、script、style

        

        2)F12/右键检查 是可以看到相关代码的

         这里有很多子标签页面元素

相关内容

热门资讯

领导干部述职报告 领导干部述职报告(通用11篇)  人生天地之间,若白驹过隙,忽然而已,回顾这段时间的工作,取得的收获...
历史系提氏起源与分布社会实践... 历史系提氏起源与分布社会实践报告范文  随着社会不断地进步,报告的使用成为日常生活的常态,我们在写报...
关于大学生消费情况调查报告 关于大学生消费情况调查报告  什么是调查报告?  调查报告是一种说明性的文体,兼有通讯和评论的某些特...
盐城师范学院校徽 盐城师范学院校徽  盐城师范学院,是江苏省属高等师范本科院校,坐落在江苏沿海开放城市盐城市。  学校...
资金申请报告 资金申请报告(通用18篇)  在经济飞速发展的今天,报告不再是罕见的东西,报告根据用途的不同也有着不...
文印店实习报告 文印店实习报告5篇  随着社会不断地进步,报告的使用成为日常生活的常态,不同种类的报告具有不同的用途...
关于街头广告牌错别字的调查报...   一、调查背景  汉字是世界上最古老的文字之一,也是世界上使用人数最多的文字。汉字的数量很多,总数...
财务预算实习报告 财务预算实习报告  实习时学生接触实践的教学过程,每个学生都应该通过财务管理的模拟设计实习,了解财务...
采风报告 采风报告推荐度:安全报告推荐度:消防报告推荐度:述职报告推荐度:调研报告推荐度:相关推荐
医保自查自纠整改报告 医保自查自纠整改报告范文  随着人们自身素质提升,报告使用的频率越来越高,报告具有双向沟通性的特点。...
医生述职报告 【实用】医生述职报告模板汇总六篇  在现实生活中,越来越多的事务都会使用到报告,不同种类的报告具有不...
个人征信报告 个人征信报告  报告的基本要求  1、总结必须有情况的概述和叙述,有的比较简单,有的比较详细。这部分...
班主任培训简报 班主任培训简报  班主任培训简报(一)  根据修文县教育局文件《关于组织参加“中国教育梦之立德树人大...
青花瓷研究开题报告 青花瓷研究开题报告研究性学习开题报告课题名称青花瓷开题时间2010年4月9日星期五结题时间2010....
地质地貌实习报告 地质地貌实习报告(精选14篇)  时间过得真快,一段时间的实习生活已经结束了,回顾过去这段时间的实习...
会计综合实训报告范文 会计综合实训报告范文  会计实训涉及的领域:  1、有会计上岗证但缺乏实际全盘账务税务操作者。  2...
员工思想动态分析报告 员工思想动态分析报告  一、分析报告的主体  主体是分析报告的主要部分,一般是写调查分析的主要情况、...
生产事故处理分析报告范文30... 生产事故处理分析报告范文 第一篇一、质量问题发生时间:20xx年3月19日、23日二、质量问题发生部...
大学生毕业实习报告 大学生毕业实习报告范文3000字(通用9篇)  紧张而又充实的实习生活结束了,想必我们吸收了许多新的...
初一自我陈述报告 初一自我陈述报告300字(通用12篇)  在现在社会,越来越多的事务都会使用到报告,其在写作上具有一...