Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start();
t2.start();
}
static class Sync implements Runnable{
private int flag;
private Object obj = new Object();
public void run() {
//同步代码块,会牺牲一些性能
synchronized (obj) {
for (int i = 0; i < 5; i++) {
flag = 0;
System.out.println("开始打饭"+flag);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = 1;
System.out.println("饭已打完"+flag);
}
}
}
}
//同步方法,同步的锁对象是当前对象,在调当前方法的时候,调用其他同步方法,会先检查当前方法的锁有没有释放,没有释放就不能调用其他方法
public synchronized void eat(){
}
public synchronized void eat2(){
}
//互斥锁
private final ReentrantLock lock = new ReentrantLock();
public void eatLock(){
lock.lock();//上锁
//执行相关代码
lock.unlock();//解锁
}
}
3.死锁
> 多线程中要进行资源的共享,就需要同步,同步过多,可能造成死锁
package com.test.testjva.thread;
public class DeadThreadDemo {
public static void main(String[] args) {
new DeadThread();
}
}
class Customer{
public synchronized void say(Waiter w){
System.out.println("顾客说,先吃饭,再买单");
w.doService();
}
public synchronized void doService(){
System.out.println("同意了,先买单,再吃饭");
}
}
class Waiter{
public synchronized void say(Customer c){
System.out.println("服务员说:先买单在吃饭");
c.doService();
}
public synchronized void doService(){
System.out.println("同意了,先吃饭,再买单");
}
}
//死锁,在调用一个对象的A方法时,就把当前对象锁住了,没执行完是不能调用该对象的其他方法的,必须等当前A方法执行完
//在当前对象的同步方法调用了其他对象的同步方法是比较危险的
class DeadThread implements Runnable{
Customer c = new Customer();
Waiter w = new Waiter();
public DeadThread (){
new Thread(this).start();
w.say(c);
}
public void run() {
c.say(w);
}
}
4.停止线程
package com.test.testjva.thread;
//中断线程一般自定义标记来中断
public class StopThread {
public static void main(String[] args) {
MyThread my = new MyThread();
Thread t1 = new Thread(my);
t1.start();
//在主线程中控制中断t1
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(500);
if(i==5) {
System.out.println(i);
my.setFlag(false);//中断线程
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class MyThread implements Runnable{
public boolean flag;//设置标记中断线程
public MyThread(){
flag = true;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public void run() {
int i = 0;
while(flag) {
System.out.println("i="+i);
if(flag)
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
if(i==100) break;
}
}
}
}
5.生产者与消费者应用案例(多线程最经典)
package com.test.testjva.thread;
//生产者和消费者
//没生产好,是不能消费的,没消费,是不能生产的
//生产和消费是2个线程控制的,但是每次执行某个线程是cpu随机选取的,所以如果有了生产,还没消费就不能再生产,所以如果有了生产,再随机到生产线程的情况下,就使用wait方法让出线程
//wait();//当前线程进入等待状态,但是会让出cpu并释放锁(因为线程抢的是随机的,抢到了,不轮到我,我就让出来)
//sleep();当前线程进入休眠状态,让出cpu不释放锁
public class ProducerAndConsumer {
public static void main(String[] args) {
Food food = new Food();
Producter p = new Producter(food);
Customers c = new Customers(food);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
//生产者
class Producter implements Runnable{
private Food food;
public Producter(Food food){
this.food = food;
}
public void run() {
for (int i = 0; i < 50; i++) {
if(i%2 == 0) {
food.set("银耳汤", "美容");
} else {
food.set("糖醋里脊", "功效:管饱,酸甜可口");
}
}
}
}
//消费者
class Customers implements Runnable{
private Food food;
public Customers(Food food){
this.food = food;
}
public void run() {
for (int i = 0; i < 50; i++) {food.get();}
}
}
//消费的对象
class Food {
private boolean flag = true;//true表示可以生产,false表示可以消费
private String name;//菜名
private String effect;//功效
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEffect() {
return effect;
}
public void setEffect(String effect) {
this.effect = effect;
}
public Food(String name, String effect) {
super();
this.name = name;
this.effect = effect;
}
public Food() {
super();
}
//生产产品
public synchronized void set(String name,String effectef ){
//表示可以消费不能生产
if(!flag){
try {
wait();//当前线程进入等待状态,但是会让出cpu并释放锁(因为线程抢的是随机的,抢到了,不轮到我,我就让出来)
//sleep();让出cpu不释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
setName(name);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
setEffect(effectef);
flag = false;//表示不能再生产
notify();//唤醒该监视器上的其他某一个线程
}
public synchronized void get(){
//表示可以生产不能消费
if(flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName()+getEffect());
flag = true;//表示不能再消费
notify();
}
}
6.线程生命周期和线程池
> 线程池:
> //像我们正常的一个应用线程一般在5,6个就是很多了,游戏应用线程比较多
> 1.预先创建
> 2.在任务没来之前,创建一定空闲线程
> 3.线程复用,减少频繁创建和销毁对象(创建线程的消耗很大的)
> JDK1.5版本以上提供了现成的线程池(我们就不用自己创建啦)
package com.test.testjva.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//用的频率比较高的的2和3
public class ExcutorDemo {
public static void main(String[] args) {
//1.创建一个单线程的执行器
ExecutorService service = Executors.newSingleThreadExecutor();
//service.execute(new DownLoadThread());//线程还保留在这里,等待执行其他任务
//2.创建固定数量的线程执行器
ExecutorService servicefix = Executors.newFixedThreadPool(3);
/*servicefix.execute(new DownLoadThread());
servicefix.execute(new DownLoadThread());
servicefix.execute(new DownLoadThread());
servicefix.execute(new DownLoadThread());*/
//3.创建一个可缓存线程执行器,60s空闲将被回收(从内存中释放)
ExecutorService servicecache = Executors.newCachedThreadPool();
servicecache.execute(new DownLoadThread());
servicecache.execute(new DownLoadThread());
servicecache.execute(new DownLoadThread());
servicecache.execute(new DownLoadThread());
//4.无限的
ExecutorService servicesche = Executors.newScheduledThreadPool(3);
}
static class DownLoadThread implements Runnable{
public void run() {
for (int i = 0; i <= 100; i+=10) {
System.out.println(Thread.currentThread().getName()+"已下载"+i+"%");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
7.网络编程基本概念
> 连接一台电脑:
> 需要知道:1.ip2.端口号
>
> 程序开发结构:
> 1.c/s(客户端/服务器) qq
>
> C/S传输方式:
> 1.TCP:传输控制协议。3次握手(安全(例如:打电话))可靠的协议,面向连接的协议(java提供了java.net包)
>
> 2.UDP:数据报协议。直接发,不管你收不收得到(例如:看电视,你看不看我都播节目)
>
> 2.b/s(浏览器/服务器) 网站web,不安全
8.Socket概念
![这里写图片描述](https://img-blog.csdn.net/20160202114633497)
> 快递员:socket
>
> 数据发送过程:
> 1.产生socket
> 2.调用bind将socket的信息通知给驱动程序
> 3.应用程序把数据传给socket
> 4.驱动程序从socket中取出数据并通知网卡发送出去
> 接受数据过程:
> 1.产生socket
> 2.调用bind将socket的信息通知给驱动程序
> 3.驱动程序根据从网卡传送过来的数据报中”指定的目标端口号“,将处理的数据传送到相应的socket中,应用程序从socket中取数据
9.简单TCP程序传输程序
package com.test.testjva.serverAndClient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer {
public static void main(String[] args) {
//端口号从1024~65535
try {
ServerSocket ss = new ServerSocket(8001);
System.out.println("服务器已启动,正在等待连接...");
Socket socket = ss.accept();//等待客户端连接,该方法会阻塞(客户端执行了它才会执行)
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String data = br.readLine();
System.out.println("data"+data);
//返回响应
OutputStream out = socket.getOutputStream();
PrintStream ps = new PrintStream(out);
ps.println("data=="+data);
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.test.testjva.serverAndClient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
public class EchoClient {
//传输过程:
//1.客户端通过输出流把数据发送到服务器(客户端可以先写一个输入流等待着)
//2.服务器通过输入流得到数据后再通过输出流返回到客户端
//3.客户端用刚刚写好的输入流得到服务器传来的数据,然后读出来
//连接服务器
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost",8001);
System.out.println("连接成功!");
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
PrintStream ps = new PrintStream(out);
ps.println("hello");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String data = br.readLine();
System.out.println("dataclient="+data);
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
10.服务器与多个客户端通信
package com.test.testjva.serverAndClient.muit;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.test.testjva.thread.ExcutorDemo;
//多客户端通信的时候,使用多线程处理客户端发送来的请求
public class EchoMuitServer {
public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool();
//端口号从1024~65535
try {
ServerSocket ss = new ServerSocket(8001);
System.out.println("服务器已启动,正在等待连接...");
while(true){
Socket socket = ss.accept();//等待客户端连接,该方法会阻塞(客户端执行了它才会执行)
//每一次过来都传到线程中去,然后继续等待
es.execute(new ClientThread(socket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
//处理客户端请求的线程
static class ClientThread implements Runnable{
private Socket socket;
public ClientThread(Socket socket){
this.socket =socket;
}
public void run() {
try {
System.out.println("客户端的ip为:"+socket.getInetAddress().getHostName());
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
//返回响应
OutputStream out = socket.getOutputStream();
PrintStream ps = new PrintStream(out);
while(true) {
String data = br.readLine();
if(data == null || data.equals("bye")){
break;
}
System.out.println("data"+data);
ps.println("data=="+data);
}
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.test.testjva.serverAndClient.muit;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class MuitClient {
//传输过程:
//1.客户端通过输出流把数据发送到服务器(客户端可以先写一个输入流等待着)
//2.服务器通过输入流得到数据后再通过输出流返回到客户端
//3.客户端用刚刚写好的输入流得到服务器传来的数据,然后读出来
//连接服务器
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost",8001);
System.out.println("连接成功!");
boolean flag = true;
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
PrintStream ps = new PrintStream(out);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
Scanner input = new Scanner(System.in);
while(flag){
System.out.println("请输入:");
String info = input.next();
if("bye".equals(info)){
flag = false;
}
ps.println(info);
info = br.readLine();
System.out.println("dataclient="+info);
}
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
11.客户端与客户端通信
package com.test.testjva.serverAndClient;
public class Info {
private String to;
private String from;
private String info;
private int type;//0表示登录,1表示发送消息
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Info [to=" + to + ", from=" + from + ", info=" + info + "]";
}
public Info(String to, String from, String info) {
super();
this.to = to;
this.from = from;
this.info = info;
}
public Info() {
super();
// TODO Auto-generated constructor stub
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
package com.test.testjva.serverAndClient.client;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import com.test.testjva.serverAndClient.Info;
public class Client {
public static void main(String[] args) {
getClient();
}
private static void getClient() {
try {
Socket socket = new Socket("localhost",8001);
System.out.println("连接成功!");
boolean flag = true;
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Scanner input = new Scanner(System.in);
System.out.println("请输入姓名:");
String name = input.nextLine();
Info info = new Info();
info.setFrom(name);
info.setType(0);
out.writeObject(info);
try {
info = (Info) in.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}//系统返回的信息
System.out.println(info.getInfo());
new Thread(new ReadInfoThread(in)).start();
while(flag){
info = new Info();
System.out.println("to:");
info.setTo(input.nextLine());
System.out.println("info:");
info.setInfo(input.nextLine());
info.setFrom(name);
info.setType(1);
out.writeObject(info);
}
out.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//接收消息的线程
static class ReadInfoThread implements Runnable{
private ObjectInputStream in;
public boolean flag = true;
public ReadInfoThread(ObjectInputStream in){
this.in = in;
flag = true;
}
public void run() {
while(flag) {
try {
Info info = (Info) in.readObject();
System.out.println("收到的消息;"+info.getInfo());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.test.testjva.serverAndClient.client;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.test.testjva.serverAndClient.Info;
public class Server {
public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool();
//用于存储客户端的服务线程
Vector<ClientThread> list = new Vector<ClientThread>();
//端口号从1024~65535
try {
ServerSocket ss = new ServerSocket(8001);
System.out.println("服务器已启动,正在等待连接...");
while(true){
Socket socket = ss.accept();//等待客户端连接,该方法会阻塞(客户端执行了它才会执行)
//每一次过来都传到线程中去,然后继续等待
ClientThread c = new ClientThread(socket,list);
es.execute(c);
}
} catch (IOException e) {
e.printStackTrace();
}
}
//处理客户端请求的线程
static class ClientThread implements Runnable{
private Socket socket;
private String name;
private Vector<ClientThread> list;
private ObjectOutputStream out;
private ObjectInputStream in;
public ClientThread(Socket socket, Vector<ClientThread> list){
list.add(this);
this.socket =socket;
this.list = list;
}
public void run() {
try {
System.out.println("客户端的ip为:"+socket.getInetAddress().getHostName());
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
while(true) {
Info info = null;
try {
info = (Info) in.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if(info.getType() == 0) {
name = info.getFrom();
Info welcome = new Info();
welcome.setInfo("welcome"+name);
} else if(info.getType() == 1) {
for (int i = 0; i < list.size(); i++) {
ClientThread ct = list.get(i);
if(ct.name.equals(info.getTo())) {
ct.out.writeObject(info);
break;
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
12.反射-Class
package com.test.testjva.reflection;
public class Cat{
//public int count;
private String name;
private int age;
public Cat(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Cat() {
super();
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Cat [name=" + name + ", age=" + age + "]";
}
private String privateTest(){
return "222";
}
}
package com.test.testjva.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Reflection1 {
public static void main(String[] args) {
getClassObj();
}
//获取一个class类对象
private static void getClassObj() {
Cat cat= new Cat("jack", 4);
//3中方式获得类信息
Class cls = cat.getClass();
Class cls2 = Cat.class;
try {
Class cls3 = Class.forName("com.test.testjva.reflection.Cat");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//通过类信息创建该对象,Cat的无参构造方法必须存在
try {
Cat catc = (Cat) cls2.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//获取构造方法
Constructor[] cons = cls2.getConstructors();
for (int i = 0; i < cons.length; i++) {
System.out.println(cons[i].getName());
}
try {
Constructor constss = cls2.getConstructor(String.class,int.class);
try {
Cat c = (Cat) constss.newInstance("jjjj",5);
System.out.println(c.getName());
} catch (Exception e) {
e.printStackTrace();
}
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
//得到类信息
String name = cls2.getPackage().getName();
//获取所以可用(公共的public)方法
Method[] medhods = cls2.getMethods();
for (Method method : medhods) {
System.out.println(method.getName()+"\\");
}
//获取所以可用(公共的)属性
Field[] f= cls2.getFields();
for (Field field : f) {
System.out.println("--"+field.getName());
}
//获取本类中定义的所有方法包含private,不包含父类方法
Method[] mes = cls2.getDeclaredMethods();
for (Method method : mes) {
System.out.println(method.getName());
}
Field[] fd = cls2.getDeclaredFields();
for (Field field : fd) {
System.out.println("==="+field.getName());
System.out.println(Modifier.toString(field.getModifiers()));
System.out.println(field.getType().getName());
}
//通过反射可以调用类里面private的方法和属性
try {
Method md = cls2.getDeclaredMethod("privateTest");
md.setAccessible(true);
try {
String test = (String) md.invoke(cat);
System.out.println("test==="+test);
} catch (Exception e) {
e.printStackTrace();
}
} catch (NoSuchMethodException | SecurityException e1) {
e1.printStackTrace();
}
//在cat对象上获取属性值
try {
//运行时忽略访问修饰符的限制
fd[0].setAccessible(true);
String nameS = (String) fd[0].get(cat);
System.out.println(nameS);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
13.动态代理
package com.test.testjva.reflectiondaili;
public interface SubJect {
void shopping();
}
package com.test.testjva.reflectiondaili;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//必须要做又不是核心业务的代码放在代理中去做
//自己写代理的情况比较少,写这个的目的是因为android里面有很多代理,便于理解别人的代码
//代理要做的事情
public class Proxy implements InvocationHandler{
private SubJect target;
public Proxy(SubJect target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("大量评估");
method.invoke(target, args);
//代购之后
System.out.println("满意度调查");
return null;
}
}
package com.test.testjva.reflectiondaili;
public class SuperMan implements SubJect{
@Override
public void shopping() {
System.out.println("哥有钱");
}
}
package com.test.testjva.reflectiondaili;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
SubJect s = new SuperMan();
com.test.testjva.reflectiondaili.Proxy proxy = new com.test.testjva.reflectiondaili.Proxy(s);
//动态创建一个代理对象(类加载器,)
SubJect obj = (SubJect) Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), proxy);
obj.shopping();
}
}
14.javabean反射和内省
package com.test.testjva.javabean;
public class User {
private String name;
private int num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public String toString() {
return "User [name=" + name + ", num=" + num + "]";
}
public User(String name, int num) {
super();
this.name = name;
this.num = num;
}
public User() {
super();
}
}
package com.test.testjva.javabean;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
//(反射和内省)前期用的比较少,写底层框架的时候,用的就比较多了,
//研究框架源代码的时候,就可以看懂了,很多框架源代码都是用反射和内省实现的
public class UserFractory {
private static Properties p = new Properties();
static {
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/test/testjva/javabean/user.properties");
try {
p.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static User newUser(){
User u = null;
try {
String user = p.getProperty("user");
Class bClass = Class.forName(user);
u = (User) bClass.newInstance();
BeanInfo info = Introspector.getBeanInfo(User.class);
//获取属性描述器
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : pds) {
String name = propertyDescriptor.getName();
if(name.equals("name")) {
Method md = propertyDescriptor.getWriteMethod();
md.invoke(u, p.getProperty("name"));
}
else if(name.equals("num")) {
Method md = propertyDescriptor.getWriteMethod();
int num = Integer.parseInt(p.getProperty("num"));
md.invoke(u, num);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return u;
}
}
package com.test.testjva.javabean;
public class UserTest {
public static void main(String[] args) {
User user = UserFractory.newUser();
System.out.println("user="+user);
}
}
创建文件:user.properties
user = com.test.testjva.javabean.User
name = my
num = 9
15.泛型
package com.test.testjva.javabean.generic;
import java.util.ArrayList;
import java.util.Collection;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
总结
最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
;
}
return u;
}
}
package com.test.testjva.javabean;
public class UserTest {
public static void main(String[] args) {
User user = UserFractory.newUser();
System.out.println("user="+user);
}
}
创建文件:user.properties
user = com.test.testjva.javabean.User
name = my
num = 9
15.泛型
package com.test.testjva.javabean.generic;
import java.util.ArrayList;
import java.util.Collection;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-tvqgamZK-1712154482121)]
[外链图片转存中…(img-Dx6eFUu1-1712154482121)]
[外链图片转存中…(img-G0M7OtIu-1712154482122)]
[外链图片转存中…(img-aSsPjvHR-1712154482122)]
[外链图片转存中…(img-pu4Fufk2-1712154482122)]
[外链图片转存中…(img-jFt5uhaj-1712154482123)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-ujbndvJH-1712154482123)]
总结
最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
[外链图片转存中…(img-uU5fjrnb-1712154482123)]
[外链图片转存中…(img-MXCKXHH4-1712154482123)]
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算