最后
看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面
小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>
针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺
全都是一丢一丢的收集整理纯手打出来的
更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~
字符串
var str: string = 'asdfasdf';
var str1: String = new String('43563456')
数组
ts写的数组,其中的数据必须是同一个类型,但不指定长度
数组中所有数据的值类型必须是数字
var arr: number[] = [1,2,3];
var arr: Array<string> = ['a','b'];
声明二维数组
var arr: number[]
var brr: number[][] = [
[1,2,3],
[4,5,6]
];
元组 Tuple
ts中的元组表示不同类型数据组成的集合,通常会固定长度,同样可以使用下标访问元素和给元素赋值
元组中就可以放不同类型的数据
元组在定义的时候就将长度固定了
var x: [string,number] = ['a',2];
console.log(x);
console.log(x[0]);
错误
x[2] = 20
不能加长度
let x: [string, number];
x = ['hello', 10];
x[2] = 'world'; // 不能加长度
可以给元素push一个值,这个值必须是string或number的类型,其他类型不允许
x.push('aaaa')
错误
x.push(true) // 错误
当给元组中并不存在的下标进行赋值的时候,会使用联合类型:
x[3] = 'world'; // OK, 字符串可以赋值给(string | number)类型
x[6] = true; // Error, 布尔不是(string | number)类型
枚举
ts中的枚举相当于在定义变量类型,这个类型有固定的取值范围,默认值从0开始,向后递增,使用指定的键来换换取到值,如果一个变量使用了这个类型,那他的值就必须从这个类型中选择,不能随便赋值:
枚举 - 必须使用指定的集合中的值
枚举类型,其实是给数字起了一些名字,让我们可以通过这个名字获取到对应的数字
默认情况,第一个名字对应的值是0,依次向后递增
enum Color {Red,Green,Blue};
var c: Color = Color.Blue; // 2
如果给其中某一个名字赋值了,他后面的名字对应的值,是根据这里的值向后递增
enum Color {Red,Green = 5,Blue};
var c: Color = Color.Blue; // 6
每个值可以指定
enum Color {Red=3,Green = 4,Blue=2};
var c: Color = Color.Blue; // 2
可以指定非数字的值
enum Color {Red='男',Green = '女',Blue='不男不女'};
var c: Color = Color.Blue; // 不男不女
通过对应值的数字获取到对应的名字 - 名字是字符串类型
enum Color {Red,Green=5,Blue};
var c: string = Color[6] // Blue
如果我们指定了其中的值是非数字型的,就不能使用这个骚操作了
enum Color {Red='red',Green = 'green',Blue='blue'};
var c: string = Color['red']; // 这个地方的值必须是数字才行
Any
Any类型,表示弱类型,也就是当我们定义一个变量的时候,不能确定变量值的类型的时候,这个类型我们又爱又恨
使用:
var a:any = 20
var b:any = 'asdfasdf'
var c:any = [1,2,3]
注意:本来我们使用ts编写代码,为的是限制类型,减少安全隐患,但是如果使用了any类型,就跟直接写js一样了,失去了意义,所以若非迫不得已,尽量不要使用。
Void
这种类型,一般用于函数执行后,不使用return返回结果的时候,就指定返回结果是void
声明变量的时候不使用它 - 当函数没有返回值的时候,返回类型指定为void
function fn(a:number,b:number):void
{
console.log(a\*b);
}
Undefined
这种类型主要用于参数和返回值,用于变量毫无意义,因为定义一个变量指定为undefined类型时,以后也就只能是undefined类型了,函数中的用法:
function fn(num:number|undefined):number|undefined
{
return num;
}
undefined - 未定义类型
var a:undefined = undefined
定义变量不用undefined,因为定义了没有用
通常会用在函数的参数里面
希望fn函数的参数a是可选项
function fn(a:number|undefined):void
{
console.log(a);
}
fn(undefined)
函数可选项
参数名后面,类型的冒号之前加 ? 表示这个参数是可选项
undefined通常用在函数返回值,如果返回的是undefined就需要在返回值的地方指定undefined类型
function fn(a?:number):number|undefined
{
return a;
}
fn()
Null
null类型 - 空 - 这个数据要被销毁啦
通常在定义复杂数据类型,且在后期需要给赋值为null的时候使用
var a:number|null = 10;
使用变量a计算 - 完成
让内存回收这个变量
a = null
Never
never类型表示永远不存在的值的类型,例如,一个函数中抛出的错误,函数中有死循环永远不可能返回 …
function fn():never
{
throw new Error('错误')
}
function fn():never
{
return fn()
}
fn()
Object
对象类型:
var obj: object = {
name:"张三"
}
错误写法 - 对象默认不允许添加键值对
obj.name = '张三';
类型断言
如果在一段代码执行后的类型种类的可能性比较多,就需要假设这是一种什么类型 - 这种操作就叫做断言。
如果一个表达式的结果有可能是多种类型,最终需要肯定其中一种
var abcd: any = [1, 2, 3, 4, 5];
断言abcd变量是一个数组
(abcd as [string,number]).push(6)
(abcd as string) += 'ddd'
函数声明
在ts中,函数定义比起js中,多了参数类型和返回值的类型定义:
函数的定义,参数的类型声明,返回值的类型声明
function fn(a:number,b:number):number
{
// console.log(a+b);
return a+b
}
var res = fn(1,2)
参数默认值
function fn(a:number,b:number=3):number
{
return a+b
}
var res = fn(1)
但是在表示参数为可选项的时候,写法稍有不同:
参数可选项 - ?表示可有可无
function fn(a:number,b?:number):number
{
if(!b){
return a+5
}
return a+b
}
// var res = fn(1)
var res = fn(1,3)
带有默认值的参数,必须放在所有参数的最后面
可选项参数,必须放在所有参数的最后面
展开运算符和合并运算符同样可以使用在ts中,但是要注意运算符后面的变量的类型设置。
计算不定实参的和
function sum(...arr:Array<number>){
var sum = 0;
for(var i=0;i<arr.length;i++){
sum += arr[i]
}
return sum;
}
var res = sum(1,2,3);
console.log(res);
函数重载:通过 为同一个函数提供多个函数类型定义 来实现多种功能的目的。例:
function outputName(name:string):string
{
return "我叫"+name
}
var s1 = outputName('张三')
console.log(s1);
function outputAge(age:number):string
{
return "我今年"+age+"岁了"
}
var s2 = outputAge(12)
console.log(s2);
有多个函数结构非常类似,可以声明一个函数的结构,让函数遵循这个结构
function output(name:string):string; 定义了一个函数结构 - 名字叫output
function output(age:number):string;
function output(name:any):any
{
return "我今年"+name+"岁了";
}
var res = output(12)
console.log(res);
var res1 = output('李四')
console.log(res1);
var res2 = output(true) 报错的,因为函数的结构要求是参数string或number
console.log(res2);
ts中的类
定义
定义方式跟es6的定义方式类似
class 类名{
constructor(){
}
}
class Person{
// 静态属性 - 用类名直接调用的属性
static weight:number;
// 类的属性要定义在这里
name:string; // 表示类中有一个属性叫name
// 在ts类中,属性和方法前面可以加一个修饰符:
/\*
public - 公开的 - 在哪里都能用
protected - 受保护的
private - 私有的
\*/
public age:number; // public可以省略的
protected sex:string; // 受保护的只能在类里面用,类的外面不能用的
private height:number; // 私有的只能在类里面使用,类外面不能用
constructor(name:string,age:number,sex:string,height:number,weight:number){
// 给属性赋值的时候,必须在这个类中是本来就有这个属性才行
this.name = name
this.age = age
this.sex = sex
this.height = height;
// this.weight = weight;
Person.weight = weight;
this.init()
}
private init(){
// console.log(this.age);
// console.log(this.sex);
console.log(this.height);
console.log("这是初始化方法");
}
static fly(){
console.log("飞的更高");
}
}
var p = new Person('张三',12,'男',120,150)
console.log(p);
// console.log(p.age);
// console.log(p.sex); // 受保护的属性不能类的外面使用
// console.log(p.height) // 私有属性不能类的外面使用
// p.init()
console.log(Person.weight);
Person.fly()
继承
ts中类的继承和es6的继承是一样,使用extends关键字,然后在构造函数中调用super函数相当于在调用父类的构造函数。
如果子类和父类有同名的方法,在子类调用这个方法的时候先在子类里面找,如果子类没有再到父类里面找。
class Person{
// 静态属性 - 用类名直接调用的属性
static weight:number;
// 类的属性要定义在这里
name:string; // 表示类中有一个属性叫name
// 在ts类中,属性和方法前面可以加一个修饰符:
/\*
public - 公开的 - 在哪里都能用
protected - 受保护的
private - 私有的
\*/
public age:number; // public可以省略的
protected sex:string; // 受保护的只能在类里面用,类的外面不能用的
private height:number; // 私有的只能在类里面使用,类外面不能用
constructor(name:string,age:number,sex:string,height:number,weight:number){
// 给属性赋值的时候,必须在这个类中是本来就有这个属性才行
this.name = name
this.age = age
this.sex = sex
this.height = height;
// this.weight = weight;
Person.weight = weight;
this.init()
}
private init(){
// console.log(this.age);
// console.log(this.sex);
console.log(this.height);
console.log("这是初始化方法");
}
static fly(){
console.log("飞的更高");
}
}
var p = new Person('张三',12,'男',120,150)
console.log(p);
// console.log(p.age);
// console.log(p.sex); // 受保护的属性不能类的外面使用
// console.log(p.height) // 私有属性不能类的外面使用
// p.init()
console.log(Person.weight);
Person.fly()
类的修饰符
在类中定义属性的时候,提供了3个修饰符:
- public:公有的 - 在类里面、子类中、类的外面都可以访问
- protected:受保护的 - 在类里面、子类中可以访问,在类外面不能访问
- private:私有的 - 在类里面可以访问,在子类和类的外面都不能访问
public可以省略
例:
静态属性和方法
es5中静态方法使用:
// 模拟jquery的封装
function $(element){
return new Ele(element);
}
$.get = function(obj){
}
function Ele(element){
this.element = document.getElementById("#"+element);
}
Ele.prototype.css = function(attr,value){
if(value){
this.element.style[attr] = value;
}else{
return window.getComputedStyle(this.element)[attr];
}
}
$("#box").css("color","red");
在ts中定义静态的属性和方法使用static关键字。在静态方法中无法访问到普通的属性,只能访问到静态的属性。
class Person{
public name:string = "张三";
static age:number = 20;
constuctor(){
}
static print1(){
console.log(this.name); // 访问不到
}
static print2(){
console.log(Person.name); // 可以访问到
}
}
Person.print1();
Person.print2();
属性可以设置为只读
多态
面向对象的三大特点:封装、继承、多态
含义:多态就是说,父类定义一个方法不去实现,让继承它的子类去实现,这样每个子类都会有不同表现。多态其实也是继承的一种表现。
// 父类 - 动物类
class Animal{
public tui:string = "有腿";
public eat(){
console.log("喜欢吃");
}
public sport(){
console.log("能走");
}
public tuiNum(){
console.log("有多条腿");
}
}
// 子类 - 人类
class Person extends Animal{
sport(){
console.log("直立走");
}
tuiNum(){
console.log("两条腿");
}
}
var p = new Person();
console.log(p.tui); // 有腿
p.eat(); // 喜欢吃
p.sport(); // 直立走
p.tuiNum() // 两条腿
// 子类 - 鸟类
class Bird extends Animal{
sport(){
console.log("很少走,通常都在飞");
}
tuiNum(){
console.log("两条腿");
}
}
var b = new Bird();
console.log(b.tui);
b.eat();
b.sport(); // 很少走,通常都在飞
b.tuiNum(); // 两条腿
// 子类 - 狗类
class Dog extends Animal{
sport(){
console.log("通常都在跑,很少走");
}
tuiNum(){
console.log("4条腿");
}
}
var d = new Dog();
console.log(d.tui);
d.eat();
d.sport(); // 通常都在跑,很少走
d.tuiNum(); // 4条腿
效果:
多态的表现 |
---|
在这里插入图片描述 |
**小总结:**多态就是多个子类继承自同一个父类,但是每个子类将继承下来的属性或方法做了改善,最终每个子类表现出来的结果是不一样的。
多态其实源于继承,也是方法的重载。
抽象类
在实际工作中,项目负责人通常会写一些标准(类似于大纲),然后将标准交给具体实现的攻城狮,由攻城狮将这个标准进行具体化开发。
ts中的抽象类就是为制作标准的。抽象类不能被实例化,只能被派生类继承并实现。
定义抽象类使用abstract关键字来修饰类。
abstract class Animate{
public name:string;
constructor(name:string){
this.name = name;
}
}
var ani = new Animate("动物"); // 报错
class Dog extends Animate{
constructor(name:string){
super(name);
}
}
var d = new Dog("小黄");
这种结构没有意义。跟普通的继承是一样的,并不能体现出标准的特殊。在抽象类中通常会有抽象方法 - 使用abstract修饰的方法。
抽象方法必须在抽象类中,且只需要定义方法结构,不要具体的实现。但是派生类中必须实现(完善)抽象方法。
abstract class Animate{
public name:string;
constructor(name:string){
this.name = name;
}
abstract eat():void; // 抽象方法
}
class Dog extends Animate{
constructor(name:string){
super(name);
}
eat(){ // 实现了抽象方法
consolelog("小狗吃粮食");
}
}
这个结构就能体现出标准的特殊:规定子类必须包含eat方法。
抽象方法只能放在抽象类中。
抽象类存在的意义就是被其他类继承,是其他类的基类。
接口
抽象类只能给方法定义标准,对于属性限制不够,所以ts设计了接口语法,它定义了属性和方法的规范,起到限制和规范的作用。接口并不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。
ts的接口跟别的主流服务器端语言的接口一样,同时还增加了更加灵活的接口类型,包括属性、函数、可索引和类等。
简单来说,接口也是在定义标准,只不过更加灵活和全面。
属性接口
属性接口专门为了约束属性而设计。
语法:
interface 接口名称{
变量:类型;
变量:类型;
}
使用方式:
function printInfo(info:接口名称){
console.log(info.属性名); // 属性名必须是接口定义过的,否则报错
}
例:
// 以前对于数据的限制
// 1.定义方法
function printInfo():void{
console.log(123);
}
printInfo();
// 2.传入参数
function printInfo(info:number):void{
console.log(info);
}
printInfo(123);
// 3.传入的参数对json限制
function printInfo(info:{name:string}):void{
console.log(info);
}
printInfo({
name:"张三"
});
printInfo({ // 错误示例 - 键在函数中不存在
sex:"男"
});
// 这种函数只能对一个键做限制,要做批量限制很麻烦,要写很多函数
// 使用接口限制
// 1.定义接口
interface info {
name:string;
sex:string;
}
// 2.定义函数使用接口类型
function printInfo(data:info){
console.log(data.name);
console.log(data.sex);
// console.log(data.age); // 错误 - info中没有age键
}
// 3.使用
printInfo({
name:"张三",
sex:"男",
age:20 // 错误 - info中没有age键
});
var obj = {
name:"张三",
sex:"男",
age:20
}
printInfo(obj); // 正确
// 接口可以批量对变量进行约束 - 参数的顺序可以不一样,但是不能少参数
定义接口中的可选参数:
interface info{
name:string;
sex?:string;
[propName:string]:any // 这里表示其他属性也可以加,也可以不加
}
// 这个接口表示name是必须,sex是可选项
// 在属性前面可以使用readonly来修饰属性不可以修改
例:
// 对jquery的ajax的封装
$.ajax({
type: "GET",
url: "test.json",
data: {username:$("#username").val(), content:$("#content").val()},
dataType: "json"
});
// 定义接口
interface Config{
type?:string;
url:string;
data?:string;
dataType?:string;
}
// 使用接口类型封装ajax
function sendAjax(config:Config){
var xhr = new XMLHttpRequest();
}
// 调用
sendAjax({
url:"",
});
函数接口
函数接口是专门为了约束函数的参数和返回而设计。
语法:
总结
虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。
上面提到的关于这些JAVA基础、三大框架、项目经验、并发编程、JVM及调优、网络、设计模式、spring+mybatis源码解读、Mysql调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料
有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。
url: “test.json”,
data: {username:KaTeX parse error: Expected 'EOF', got '#' at position 3: ("#̲username").val(…(“#content”).val()},
dataType: “json”
});
// 定义接口
interface Config{
type?:string;
url:string;
data?:string;
dataType?:string;
}
// 使用接口类型封装ajax
function sendAjax(config:Config){
var xhr = new XMLHttpRequest();
}
// 调用
sendAjax({
url:“”,
});
##### 函数接口
函数接口是专门为了约束函数的参数和返回而设计。
语法:
# 总结
虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。
[外链图片转存中...(img-DSbmPwO5-1715491554126)]
[外链图片转存中...(img-ouWG691Y-1715491554126)]
**上面提到的关于这些JAVA基础、三大框架、项目经验、并发编程、JVM及调优、网络、设计模式、spring+mybatis源码解读、Mysql调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料**
有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**
**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**